ruby-av / paperclip-av-transcoder

Audio/Video Transcoder for Paperclip using FFMPEG/Avconv
MIT License
136 stars 83 forks source link

Thumbs depending on the video duration #53

Closed Eyap53 closed 7 years ago

Eyap53 commented 7 years ago

Hi, as said in the title, i would like to add thumbs, depending on the video duration.

It it possible to define time using percentage? Or to use a variable duration? I know that the duration can be found in the _meta, but is it possible to retrieve it before the saving ?

Here is my code :

validates :title,
            length: { in: 2..60 }
  validates :description,
            length: { minimum: 2 }

  has_attached_file :content, styles: {
      :medium => {
          :format => 'mp4',
          #convert_options: {
              #output: {
                #name: 'value' # Results in `-name value` in the command line
              #}
          #}
      },
      :thumb0 => { :geometry => '320x180#', :format => 'jpeg', :time => 1.0 * duration / 6.0 },
      :thumb1 => { :geometry => '320x180#', :format => 'jpeg', :time => 2.0 * duration / 6.0},
      :thumb2 => { :geometry => '320x180#', :format => 'jpeg', :time => 3.0 * duration / 6.0},
      :thumb3 => { :geometry => '320x180#', :format => 'jpeg', :time => 4.0 * duration / 6.0},
      :thumb4 => { :geometry => '320x180#', :format => 'jpeg', :time => 5.0 * duration / 6.0},
      }, :processors => [:transcoder]

  validates_attachment :content, presence: true,
                       content_type: { content_type: /\Avideo\/.*\Z/ },
                       size: { :less_than => 2.gigabytes }

Thx in advance for your reply ! (After thinking about it i should have posted on StackOverflow instead... sorry about that)

attenzione commented 7 years ago

time can be defined as lambda (this is how it's done in paperclip) and method from instance, for example:

  styles: {
    thumb: {
      format: 'jpg',
      time: ->(attachment) { attachment.instance.method(:style_time_for) },
      processors: [:transcoder]
    }
  }

  def style_time_for(meta, _options)
    meta[:duration].to_f / 2
  end
Eyap53 commented 7 years ago

Thanks for your fast reply ! I'm new to rails and i'm not really used to lambdas, but i am checking the manual right know ;) I will post my working code if someone else need it.

Eyap53 commented 7 years ago

Well, it is working like that, even if it's not elegant at all :

  has_attached_file :content, styles: {
      :medium => {
          :format => 'mp4',
      },
      :thumb0 => { :geometry => '320x180#', :format => 'jpeg', :time => ->(attachment) { attachment.instance.method(:style_time_for0) } },
      :thumb1 => { :geometry => '320x180#', :format => 'jpeg', :time => ->(attachment) { attachment.instance.method(:style_time_for1) } },
      :thumb2 => { :geometry => '320x180#', :format => 'jpeg', :time => ->(attachment) { attachment.instance.method(:style_time_for2) } },
      :thumb3 => { :geometry => '320x180#', :format => 'jpeg', :time => ->(attachment) { attachment.instance.method(:style_time_for3) } },
      :thumb4 => { :geometry => '320x180#', :format => 'jpeg', :time => ->(attachment) { attachment.instance.method(:style_time_for4) } },
      }, :processors => [:transcoder]

  def style_time_for0(meta, _options)
    1*meta[:duration].to_f / 6
  end
  def style_time_for1(meta, _options)
    2*meta[:duration].to_f / 6
  end
  def style_time_for2(meta, _options)
    3*meta[:duration].to_f / 6
  end
  def style_time_for3(meta, _options)
    4*meta[:duration].to_f / 6
  end
  def style_time_for4(meta, _options)
    5*meta[:duration].to_f / 6
  end

(I will try to add a loop with a parameter later). Thanks for all !