Estoy trabajando en una aplicación que requiere subir videos. Agregué Shrine y almacenamiento s3.
Hasta aquí todo funciona. Ahora necesito transcodificar los videos y agregué el siguiente código al archivo 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 endLa transcodificación está funcionando y básicamente está transcodificando el nuevo archivo cargado en la carpeta de caché y colocándolo en la carpeta de la tienda con el mismo nombre.
El problema ahora es adjuntar este archivo al registro en la base de datos. A partir de ahora, el registro se actualiza con un nombre diferente, crea un nuevo archivo en la carpeta de la tienda de 0mb.
¿Cómo puedo adjuntar los resultados del procesamiento al archivo cargado de Shrine para su almacenamiento?
El bloque process(:store) espera que devuelva un archivo para que Shrine lo cargue en un almacenamiento permanente, por lo que este flujo no funcionará con Amazon Elastic Transcoder, porque Amazon Elastic Transcoder ahora es el que cargará el archivo almacenado en caché en un almacenamiento permanente.
Puede retrasar la solicitud de transcodificación a un trabajo en segundo plano, sondear el trabajo de transcodificación cada N segundos y crear un Shrine::UploadedFile a partir de los resultados y actualizar el registro. Algo como lo siguiente debería funcionar:
# 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 endSi por casualidad está interesado en crear un complemento de Shrine para Amazon Elastic Transcoder, eche un vistazo a shrine-transloadit que proporciona integración para Transloadit , que utiliza prácticamente el mismo flujo que Amazon Elastic Transcoder, y funciona con webhooks en lugar de que sondear la respuesta.