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.