Uso de CarrierWave con Amazon Elastic Transcoder en una aplicación Rails
Hice dos preguntas adicionales antes de esto en Stack Overflow, pero obtuve muy poca ayuda y pensé en hacer una pregunta abierta para la posteridad. Pasé tiempo analizando los documentos de la API de AWS-SDK y encontré muy pocas respuestas directas a mis necesidades. También he publicado en los foros de AWS y no he podido obtener una buena respuesta allí. Parece imposible encontrar una solución simple, completa y paso a paso.
Lo que he completado:
Carga con CarrierWave directo a s3. Seguí Railscast # 383 y lo adapté a mis necesidades.Puedo "recuperar" mis archivos de mi bucket s3.Detalles sobre lo que he hecho hasta ahora:
Utilicé Carrierwave-Direct para cargar directamente a s3 (esto utiliza niebla para lidiar con la carga directamente a s3). La carga se procesa en un trabajo en segundo plano con Sidekiq. Después de que el archivo se coloca en el depósito, solo lo recupero iterando a través de las cargas de un usuario y llamo el archivo por la url de carga desde s3.
Aquí es donde estoy perdido:
Necesito transcodificar videos con el Elastic Transcoder provisto por AWS.Necesito recordar los videos cargados / convertidos del paquete de salida. ¿Cómo hago un enlace a la URL desde el "bucket de salida"? ¿Es una nueva referencia de URL o la URL sigue siendo la misma que la "URL de carga" original?Necesito integrar los videos transcodificados del transcodificador a Cloudfront y mostrarlos usando JWPlayer.¿Cómo integro el código API en mi proceso de carga en segundo plano?Aquí está mi código hasta ahora:
Mi cargador:
class VideoUploader < CarrierWave::Uploader::Base
include CarrierWaveDirect::Uploader
end
Mi inicializador que maneja los detalles de s3:
CarrierWave.configure do |config|
config.fog_credentials = {
provider: 'AWS',
aws_access_key_id: 'AWS_ACCESS_KEY_ID',
aws_secret_access_key: 'AWS_SECRET_ACCESS_KEY',
region: 'us-west-1'}
config.fog_directory = 'video-input'
config.fog_public = false # optional, defaults to true
config.fog_attributes = { 'Cache-Control' => "max-age=#{365.day.to_i}" } # optional, defaults to {}
end
Mi modelo de carga:
class Upload < ActiveRecord::Base
belongs_to :user
mount_uploader :video, VideoUploader
after_save :enqueue_video
def enqueue_video
VideoWorker.perform_async(id, key) if key.present?
end
class VideoWorker
include Sidekiq::Worker
def perform(id, key)
upload = Upload.find(id)
upload.key = key
video.remote_video_url = upload.video.direct_fog_url(with_path: true)
upload.save!
end
end
end
Mi vista:
Para mostrar todas las cargas de los usuarios:
<% @user.uploads.each do |upload| %>
<%= link_to upload.title, upload_url(upload) %>
<% end %>
Para mostrar la carga (en este momento es solo un enlace de descarga):
<h1><%= @upload.title %></h1>
<p><%= link_to @upload.video_url %></p>
No creo que mi esquema o formas sean relevantes.
Una muestra similar de cómo creo que podría funcionar el código:
Agregaría este código al trabajador de Sidekiq, pero no estoy seguro de si lo estoy haciendo bien. Tampoco estoy seguro de cómo voy a conectar mi "carga" a la "carga convertida".
upload.update_column 'converted_video',
File.basename(upload.video.path)
transcoder = AWS::ElasticTranscoder::Client.new
transcoder.create_job(
pipeline_id: APP_CONFIG[Rails.env][:pipeline_id],
input: {
key: upload.video.path,
frame_rate: 'auto',
resolution: 'auto',
aspect_ratio: 'auto',
interlaced: 'auto',
container: 'auto'
},
output: {
key: upload.converted_video.path,
preset_id: WEB_M4_PRESET_ID,
thumbnail_pattern: "",
rotate: '0'
}
)
Enlaces a un artículo útil y documentos sobre Elastic Transcoder:
http://www.techdarkside.com/getting-started-with-the-aws-elastic-transcoder-api-in-rails
http://docs.aws.amazon.com/sdkforruby/api/Aws/ElasticTranscoder.html