亚马逊弹性转码与神社

时间:2017-03-31 16:09:45

标签: ruby-on-rails amazon-s3 shrine amazon-elastic-transcoder

我正在开发一款需要上传视频的应用。我添加了Shrine和s3存储。

直到这里一切正常。现在我需要对视频进行转码,然后将以下代码添加到video_uploader文件中

class VideoUploader < Shrine

  plugin :processing
  plugin :versions

  process(:store) do |io|

    transcoder = Aws::ElasticTranscoder::Client.new(
      access_key_id:     ENV['AWS_ACCESS_KEY_ID'],
      secret_access_key: ENV['AWS_SECRET_ACCESS_KEY'],
      region:            'us-east-1',
    )

    pipeline = transcoder.create_pipeline(options = {
        :name => "name",
        :input_bucket => "bucket",
        :output_bucket => "bucket",
        :role => "arn:aws:iam::XXXXX:role/Elastic_Transcoder_Default_Role",
    })

    PIPELINE_ID =  pipeline[:pipeline][:id]

    transcode_hd = transcoder.create_job({
      :pipeline_id=>PIPELINE_ID,
      :input=> {
        :key=> "cache/"+io.id,
        :frame_rate=> "auto",
        :resolution => "auto",
        :aspect_ratio => "auto",
        :container => 'auto'
      },
      :outputs=>[{
        :key=>"store/"+io.id,
        :preset_id=>"1351620000001-000010",
      }]
    })

  end

end 

转码工作正常,基本上是将上传到缓存文件夹的新文件转码并放入同名商店文件夹中。

现在的问题是将此文件附加到数据库中的记录。截至目前,记录使用不同的名称更新,它在0mb的商店文件夹中创建了一个新文件。

如何将处理结果附加到Shrine的上传文件中进行存储?

1 个答案:

答案 0 :(得分:3)

process(:store)块希望您返回Shrine的文件以上传到永久存储,因此这个流程不会运行Amazon Elastic Transcoder,因为Amazon Elastic Transcoder现在是将上传缓存的归档到永久存储。

您可以将转码请求延迟到后台作业,每隔N秒轮询转码作业,并从结果中创建Shrine::UploadedFile并更新记录。以下内容应该有效:

# superclass for all uploaders that use Amazon Elastic Transcoder
class TranscoderUploader < Shrine
  plugin :backgrounding
  Attacher.promote { |data| TranscodeJob.perform_async(data) }
end

class VideoUploader < TranscoderUploader
  plugin :versions
end

class TranscodeJob
  include Sidekiq::Worker

  def perform(data)
    attacher = TranscoderUploader::Attacher.load(data)
    cached_file = attacher.get #=> #<Shrine::UploadedFile>

    # create transcoding job, use `cached_file.id`

    transcoder.wait_until(:job_complete, id: job.id)
    response = transcoder.read_job(id: job.id)
    output = response.output

    versions = {
      video: attacher.shrine_class::UploadedFile.new(
        "id" => cached_file.id,
        "storage" => "store",
        "metadata" => {
          "width" => output.width,
          "height" => output.height,
          # ...
        }
      ),
      ...
    }

    attacher.swap(versions)
  end
end

如果您有兴趣为Amazon Elastic Transcoder制作Shrine插件,请查看为shrine-transloadit提供集成的Transloadit,其使用的实际流程与亚马逊弹性转码器,它与webhooks配合使用,而不是轮询响应。