I have a rails app which uploads videos to an AWS S3 bucket using their CORS configuration, when this is completed and the rails video object is created an Elastic Transcoder job is created to encode the video to .mp4 format and generate a thumbnail image, AWS SNS is enabled to send push notifications when the job is complete.
The process all works nicely and I receive a SNS notification when the upload is complete, however I can fetch the video url just fine but the notification only contains the thumbnail pattern rather than the actual filename.
Below is a typical notification I receive from AWS SNS. NB. This is from the outputs hash
{"id"=>"1", "presetId"=>"1351620000001-000040", "key"=>"uploads/video/150/557874e9-4c67-40f0-8f98-8c59506647e5/IMG_0587.mp4", "thumbnailPattern"=>"uploads/video/150/557874e9-4c67-40f0-8f98-8c59506647e5/{count}IMG_0587", "rotate"=>"auto", "status"=>"Complete", "statusDetail"=>"The transcoding job is completed.", "duration"=>10, "width"=>202, "height"=>360}
As you can see under thumbnailPattern is just the filepattern to use, and not the actual file created.
Does anyone know how I can get the URLS to the files created over elastic transcoder and SNS?
transcoder.rb # => I create a new transcoder object when a video has been saved
class Transcoder < Video
def initialize(video)
@video = video
@directory = "uploads/video/#{@video.id}/#{SecureRandom.uuid}/"
@filename = File.basename(@video.file, File.extname(@video.file))
end
def create
transcoder = AWS::ElasticTranscoder::Client.new(region: "us-east-1")
options = {
pipeline_id: CONFIG[:aws_pipeline_id],
input: {
key: @video.file.split("/")[3..-1].join("/"), # slice off the amazon.com bit
frame_rate: "auto",
resolution: 'auto',
aspect_ratio: 'auto',
interlaced: 'auto',
container: 'auto'
},
outputs: [
{
key: "#{@filename}.mp4",
preset_id: '1351620000001-000040',
rotate: "auto",
thumbnail_pattern: "{count}#{@filename}"
}
],
output_key_prefix: "#{@directory}"
}
job = transcoder.create_job(options)
@video.job_id = job.data[:job][:id]
@video.save!
end
end
VideosController #create
class VideosController < ApplicationController
def create
@video = current_user.videos.build(params[:video])
respond_to do |format|
if @video.save
transcode = Transcoder.new(@video)
transcode.create
format.html { redirect_to videos_path, notice: 'Video was successfully uploaded.' }
format.json { render json: @video, status: :created, location: @video }
format.js
else
format.html { render action: "new" }
format.json { render json: @video.errors, status: :unprocessable_entity }
end
end
end
end
It doesn't appear that the actual name of the thumbnails are passed back, either from SNS notifications or from the request response upon creation of a job:
http://docs.aws.amazon.com/elastictranscoder/latest/developerguide/create-job.html#create-job-examples
http://docs.aws.amazon.com/elastictranscoder/latest/developerguide/notifications.html
Because the base path/name of your thumbnails is known, and the sequence number will always start at 00001, you can iterate from there to determine if/how many of the thumbnails exist upon job completion. Ensure you use HEAD requests against the objects in S3 to determine their presence; its about 10x cheaper than doing a LIST request.
It passed 4 years after last reply. New Cold War raised, there are a lot of political tensions but Amazon sill doesn't fixed this issue.
As workaround I found another solution: usually transcoded file (video/thumbnail) are placed into the new bucket. Or at least under some prefix. I created new S3 event for ObjectCreate(All)
for target bucket and specified prefix and connected it to pre-created SNS topic. This topic pings my backend's endpoint twice - first time when video transcoded and second time - when thumbnail created. Using regexp it is quite easy to distinguish what is what.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With