Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Retrieve file and thumbnail url from AWS Elastic Transcoder job

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
like image 854
dodgerogers747 Avatar asked Mar 21 '23 02:03

dodgerogers747


2 Answers

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.

like image 93
Brandon Galbraith Avatar answered Mar 30 '23 01:03

Brandon Galbraith


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.

like image 34
Alex G.P. Avatar answered Mar 30 '23 01:03

Alex G.P.