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 end
Good. 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 end
There! 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!