Paperclip not executing FFMPEG properly

Im using a customs processor to run ffmpeg on a video to create a thumbnail.

So far so good. Except when I do:

cmd = "-i #{@file.path} -f flv -s 320x240 ~/Downloads/foobar/q.flv" success = Paperclip.run('ffmpeg', cmd)

Console is reporting:

ffmpeg '-i /var/folders/uL/uL0bYOOZEZaJH5E+BmDJVE+++TI/-Tmp-/stream, 16824,1.mpeg -f flv -s 320x240 ~/Downloads/foobar/q.flv' 2>/dev/null

I believe the problem is because Paperclip inserts single quotes when executing ffmpeg.

It works if I manually type in console (ie. without single quotes):

ffmpeg -i /var/folders/uL/uL0bYOOZEZaJH5E+BmDJVE+++TI/-Tmp-/stream, 16824,1.mpeg -f flv -s 320x240 ~/Downloads/foobar/q.flv

How can this be fixed?

this here is how i do it

def create_thumbnail jpg = File.join(File.dirname(vidfile.path), “#{id}.jpg”) File.open(jpg, ‘w’) command = <<-end_command

  ffmpeg -itsoffset -4 -i #{ vidfile.path } -y -vcodec mjpeg -vframes 1 -an -f rawvideo -s 160x120  #{ jpg }
end_command
command.gsub!(/\s+/, " ")

end

you have to manually delete the file on destroy since paperclip is only aware of the file i uploaded which it the video file and will not delete the jpg file.

File.delete(@vidfile.path.gsub(/flv/,“jpg”))

also you have to delete the original, and update the db entry

def set_new_filename File.delete(vidfile.path) update_attribute(:vidfile_file_name, “#{id}.flv”)

update_attribute(:vidfile_thumb, "#{id}.jpg")

end

i also set everything in an starling worker

ConvertWorker.async_convert_video(:file_path => vidfile.path)

Hi Radhames, do you mind showing what you have for the processor at / lib/paperclip_processors/your_processor_lib.rb ?

I tried:

module Paperclip   class VideoThumbnail < Processor

    attr_accessor :time_offset, :geometry, :whiny

    def initialize(file, options = {}, attachment = nil)       super       @time_offset = options[:time_offset] || '-4'       unless options[:geometry].nil? || (@geometry = Geometry.parse(options[:geometry])).nil?         @geometry.width = (@geometry.width / 2.0).floor * 2.0         @geometry.height = (@geometry.height / 2.0).floor * 2.0         @geometry.modifier = ''       end       @whiny = options[:whiny].nil? ? true : options[:whiny]       @basename = File.basename(file.path, File.extname(file.path))     end

    def make       dst = Tempfile.new([ @basename, 'jpg' ].compact.join("."))       dst.binmode

      puts 'wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww'       puts @file.path

      cmd = <<-end_command         ffmpeg -i #{@file.path} -f flv -s 320x240 ~/Downloads/foobar/ q.flv        end_command       cmd.gsub!(/\s+/, " ")

      begin         success = Paperclip.run('ffmpeg', cmd)       rescue PaperclipCommandLineError         raise PaperclipError, "There was an error processing the thumbnail for #{@basename}" if whiny       end       dst     end   end end

console reports:

[paperclip] ffmpeg ' ffmpeg -i /var/folders/uL/uL0bYOOZEZaJH5E+BmDJVE++ +TI/-Tmp-/stream,1547,1.mpeg -f flv -s 320x240 ~/Downloads/foobar/ q.flv ' 2>/dev/null

Check that your Rails app knows the real path to ffmpeg. In at least one of my apps, I have needed to provide a root-relative path to ffmpeg in order to have any conversion work.

Walter

Well all this is a simple call in my model, and i call the convert function, you can at it as a after_save

Most of the tutorials I've read suggest that the logic for the processing be placed in

/lib/paperclip_processors/your_processor_lib.rb

For example: http://thewebfellas.com/blog/2009/2/22/video-thumbnails-with-ffmpeg-and-paperclip

Is the after_save approach in the model a better way?

Been on this for hours, and still getting the same error... Would be great if someone can post a code snippet from a working copy

Most of the tutorials I’ve read suggest that the logic for the

processing be placed in

ill tell you what i do and why.

i use workling and create a worker process to the convertion , and call the working from an after save callback in the model.

I do that because i convert the video from whatever format to flv along with the thumbnail and that takes time , if i do that in the main thread it will cause my app to freeze for each conversion, that is why i moved to a worker process.

If you give me 2 hours all make an example app and upload it to github for you to pull, is that ok?

radhames, that sounds good. would appreciate that.

One other way, I've gotten it to work is in my model:

  before_save :process_thumbnail

  private   def process_thumbnail       system("ffmpeg -i #{self.media.to_file.path} -f flv -s 320x240 ~/ Downloads/foobar/q.flv")   end

But I dont know if this is a clean way of doing it. Is it? Will I have problems with the app hanging as you mentioned?

before_save :process_thumbnail

private

def process_thumbnail

  system("ffmpeg -i #{self.media.to_file.path} -f flv -s 320x240 ~/

Downloads/foobar/q.flv")

end

yes it will hang as long as this is in your model, and it will hang for a few seconds. Oh and use a after_save callback not a before_save.

ok im going to start working on it , meanwhile watch this railscast

http://railscasts.com/episodes/128-starling-and-workling

Even putting the logic/code in /lib/paperclip_processors/ your_processor_lib.rb as described at http://thewebfellas.com/blog/2009/2/22/video-thumbnails-with-ffmpeg-and-paperclip will make the application hang whenever a user uploads a video?

I will read and answer after lunch

Radhames, what do you think? I am guessing the article at http://www.google.com/url?sa=D&q=http://thewebfellas.com/blog/2009/2/22/video-thumbnails-with-ffmpeg-and-paperclip&usg=AFQjCNHbJbsr5cjILbhrgpvOot5qJhUPsw assumes that the uploader would be the admin, so there is no need for startling or a workling?

But if the app allows users to upload, then a startling/workling approach is needed since ffmpeg takes a while to process uploaded files?

Yes that is right, if only the admin will upload files there is no need for starling/working.

I dont see anything wrong in doing things with a method in the model like i told you the first time.

Hi Radhames, ok, then I will definitely need to use a workling and a startling for this. Since my users are the ones uploading. By the way, in Heroku hosting (Pricing | Heroku), a workling would be a worker right? So whenever I implement a workling in my app, it would trigger the workling in Heroku? Am I understanding this right?

Let me know when you get your example up. Am very eager to have a look at it

I guess what I am asking is. If my app allows users to upload content, which uses ffmpeg, and takes a while decode audio/video, will this trigger the workers at heroku automatically? Therefore, I don't need to use a workling/startling?

Or do I still need to implement a startling/workling for this to prevent the app from 'hanging'?

Ok I've gotten it to work. For everyone that is interested or devs who stumble across:

Model class:   has_attached_file :media,                     :styles => { :small => '94x58#',                                  :medium => '188x116#',                                  :large => '376x232#' },                     :url => '/assets/artists/:artist_id/ videos/:id/:style.:extension',                     :path => ':rails_root/public/assets/ artists/:artist_id/videos/:id/:style.:extension',                     :processors => [:video_thumbnail]

Sorry that i havent worked the example but i have been feeling a bit sick, i will upload it as soon as i feel better.