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 (http://heroku.com/pricing), 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.