Create FFMPEG processor for Carrierwave in Rails 3
I have had the pleasure of working with the carrierwave gem recently (as opposed to paperclip), and I must say, I am quite the fan. Once major thing I missed however, was the available list of custom user plugins for it, unlike paperclip. I believe this is mostly due to how new and recent carrierwave is. That being said, I put together a simple example of a FFMPEG process that will allow me to resample the bitrate of a file. This should lay the ground work for other features as well. This example is using Rails 3, but should be easily adaptable for 2. Also, make sure you already have FFMPEG installed and running properly. So lets get started: First things first…we need to add the appropriate gems to our Gemfile:
# Gemfile gem "carrierwave" gem "streamio-ffmpeg"
Next is the meat and potatoes of this..the actual FFMPEG process for carrierwave. I choose to keep my plugin files in the directory lib/carrierwave. Make sure you have this path included in your application.rb file if you are using rails 3. Here is the code:
# lib/carrierwave/ffmpeg.rb
require "streamio-ffmpeg"
module CarrierWave
module FFMPEG
module ClassMethods
def resample( bitrate )
process :resample => bitrate
end
end
def resample( bitrate )
directory = File.dirname( current_path )
tmpfile = File.join( directory, "tmpfile" )
File.move( current_path, tmpfile )
file = ::FFMPEG::Movie.new(tmpfile)
file.transcode( current_path, :audio_bitrate => bitrate)
File.delete( tmpfile )
end
end
endGood. Now that we have the plugin coded up, we need to include it into our uploader. I already have one mounted to my Asset model. Here is what my AssetUploader now looks like:
# app/uploaders/asset_uploader.rb
require File.join(Rails.root, "lib", "carrier_wave", "ffmpeg")
class AssetUploader < CarrierWave::Uploader::Base
include CarrierWave::FFMPEG # <= include the plugin
# Choose what kind of storage to use for this uploader:
storage :file
# Override the directory where uploaded files will be stored.
# This is a sensible default for uploaders that are meant to be mounted:
def store_dir
"#{Rails.root}/uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
# Add a version, utilizing our processor
version :bitrate_128k do
process :resample => "128k"
end
endThere! Now whenever you add a new file, it should fire off the processor and create a new version. I hope this help anyone still up in the air about how to put together their own plugin/process for carrierwave. Next I will demonstrate how to incorporate Delayed::Job to move these intensive tasks to the background!