Skip to content

Instantly share code, notes, and snippets.

@kevinansfield
Created May 20, 2015 16:12
Show Gist options
  • Save kevinansfield/4ea00b95383916c465bf to your computer and use it in GitHub Desktop.
Save kevinansfield/4ea00b95383916c465bf to your computer and use it in GitHub Desktop.
Refile attachment with ZenCoder processing
# == Schema Information
#
# Table name: videos
#
# id :integer not null, primary key
# meta_info :jsonb default({}), not null, indexed
# created_at :datetime not null
# updated_at :datetime not null
# videoable_id :integer indexed => [videoable_type]
# videoable_type :string indexed => [videoable_id]
# video_file_id :string
# video_file_filename :string
# video_file_content_type :string
#
# Indexes
#
# index_videos_on_meta_info (meta_info)
# index_videos_on_videoable_type_and_videoable_id (videoable_type,videoable_id)
#
class Video < ActiveRecord::Base
belongs_to :videoable, polymorphic: true
validates :video_file, presence: true
after_save :zencode, if: 'video_file_id_changed?'
attachment :video_file,
extension: %w(3gp avc avi flv m4v mkv mov mp4 mpeg mpg mpe ogg wmv)
def transcode_complete?
meta_info['response'].try(:[], 'input').try(:[], 'state') == 'finished'
end
def thumbnail_url
@thumbnail_url ||= url_for_format('jpg')
end
def mp4_url
@mp4_url ||= url_for_format('mp4')
end
def webm_url
@webm_url ||= url_for_format('webm')
end
def ogv_url
@ogv_url ||= url_for_format('ogv')
end
def zencode
zencoder_response = Zencoder::Job.create(zencoder_params)
update_model = self.becomes(Video::AsZencoderUpdate)
update_model.meta_info[:request] = zencoder_response.body
update_model.save
end
private
def zencoder_params
{
:input => video_file_url,
:notifications => [notification_url],
:pass_through => id,
:outputs => [
{
:public => true,
:base_url => base_url,
:filename => video_file_id + '.mp4',
:label => 'webmp4',
:format => 'mp4',
:audio_codec => 'aac',
:video_codec => 'h264'
},
{
:public => true,
:base_url => base_url,
:filename => video_file_id + '.webm',
:label => 'webwebm',
:format => 'webm',
:audio_codec => 'vorbis',
:video_codec => 'vp8'
},
{
:public => true,
:base_url => base_url,
:filename => video_file_id + '.ogv',
:label => 'webogv',
:format => 'ogv',
:audio_codec => 'vorbis',
:video_codec => 'theora'
},
{
:thumbnails => {
:label => '420',
:public => true,
:base_url => base_url,
:filename => video_file_id,
:times => [4],
:aspect_mode => 'crop',
:width => '848',
:height => '420',
:format => 'jpg'
}
}
]
}
end
def video_file_url
Figaro.env.s3_host + '/store/' + video_file_id
end
def base_url
@base_url ||= Figaro.env.s3_host + '/videos/transcoded'
end
def url_for_format(extension)
base_url + '/' + video_file_id + '.' + extension
end
def notification_url
Rails.env.development? ? 'http://zencoderfetcher/' : zencoder_callbacks_url
end
end
class Video::AsZencoderUpdate < Video
# skip zencode callback to avoid infinite loop
skip_callback :save, :after, :zencode
end
class ZencoderCallbacksController < ApplicationController
skip_before_filter :verify_authenticity_token
def create
video = Video::AsZencoderUpdate.find_by_id(params[:job][:pass_through])
if video && params[:job][:state] == 'finished'
video.meta_info['response'] = params[:zencoder_callback]
video.save
end
render nothing: true
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment