Class: Paperclip::FrameGrab

Inherits:
Processor
  • Object
show all
Defined in:
lib/paperclip/frame_grab.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(file, options = {}, attachment = nil) ⇒ FrameGrab

Returns a new instance of FrameGrab.



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# File 'lib/paperclip/frame_grab.rb', line 6

def initialize(file, options = {}, attachment = nil)
  super
  @file = file
  @time_offset = options[:time_offset] || '-4'
  geometry = options[:geometry]
  unless geometry.blank?
    @crop = geometry[-1,1] == '#'
    @target_geometry = Geometry.parse(geometry)
    @current_geometry = Geometry.parse(video_dimensions(file))
  end
  @current_format = File.extname(@file.path)
  @target_format = options[:format] || 'jpg'
  @basename = File.basename(@file.path, @current_format)
  @whiny = options[:whiny].nil? ? true : options[:whiny]
end

Instance Attribute Details

#current_formatObject

Returns the value of attribute current_format.



4
5
6
# File 'lib/paperclip/frame_grab.rb', line 4

def current_format
  @current_format
end

#current_geometryObject

Returns the value of attribute current_geometry.



4
5
6
# File 'lib/paperclip/frame_grab.rb', line 4

def current_geometry
  @current_geometry
end

#target_formatObject

Returns the value of attribute target_format.



4
5
6
# File 'lib/paperclip/frame_grab.rb', line 4

def target_format
  @target_format
end

#target_geometryObject

Returns the value of attribute target_geometry.



4
5
6
# File 'lib/paperclip/frame_grab.rb', line 4

def target_geometry
  @target_geometry
end

#time_offsetObject

Returns the value of attribute time_offset.



4
5
6
# File 'lib/paperclip/frame_grab.rb', line 4

def time_offset
  @time_offset
end

#whinyObject

Returns the value of attribute whiny.



4
5
6
# File 'lib/paperclip/frame_grab.rb', line 4

def whiny
  @whiny
end

Instance Method Details

#crop?Boolean

Returns:

  • (Boolean)


22
23
24
# File 'lib/paperclip/frame_grab.rb', line 22

def crop?
  !!@crop
end

#makeObject



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/paperclip/frame_grab.rb', line 26

def make
  src = @file
  dst = Tempfile.new([ @basename, @target_format ].compact.join("."))
  dst.binmode

  begin
    # grab frame at offset
    cmd = %Q[-itsoffset #{time_offset} -i :source -y -vcodec mjpeg -vframes 1 -an -f rawvideo ]

    # if scale-and-crop parameters can be calculated, we pipe to convert for resizing
    if scale_and_crop = transformation_options
      cmd << %{pipe: | convert #{scale_and_crop} - #{target_format}:- }

    # otherwise we let ffmpeg resize the to the right size without preserving aspect ratio
    else
      cmd << %{-s #{target_geometry} pipe: }
    end

    # then pipe to composite to overlay video icon
    cmd << %{| composite -gravity center :icon - :dest }
    
    Paperclip.run('ffmpeg', cmd, :source => File.expand_path(src.path), :dest => File.expand_path(dst.path), :icon => AssetType.find(:video).icon_path, :swallow_stderr => false)
  rescue PaperclipCommandLineError => e
    raise PaperclipError, "There was an error processing the thumbnail for #{@basename}: #{e}" if whiny
  end
  
  dst
end

#transformation_optionsObject

Duplicated from Thumbnail. We can’t just subclass because of assumed compatibility with Geometry.from_file



62
63
64
65
66
67
68
69
70
# File 'lib/paperclip/frame_grab.rb', line 62

def transformation_options
  if current_geometry
    scale, crop = current_geometry.transformation_to(target_geometry, crop?)
    trans = []
    trans << "-resize" << %["#{scale}"] unless scale.nil? || scale.empty?
    trans << "-crop" << %["#{crop}"] << "+repage" if crop
    trans.join(" ")
  end
end

#video_dimensions(file) ⇒ Object

get video dimensions in nasty hacky way



56
57
58
59
# File 'lib/paperclip/frame_grab.rb', line 56

def video_dimensions(file)
  dim = Paperclip.run('ffmpeg', '-i :source 2>&1', :source => File.expand_path(file.path), :expected_outcodes => [0,1], :swallow_stderr => false)
  $1 if dim =~ /(\d+x\d+)/
end