Class: VideoScreenshoter::Abstract

Inherits:
Object
  • Object
show all
Defined in:
lib/video_screenshoter/abstract.rb

Direct Known Subclasses

Hls, Image, Video

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(params) ⇒ Abstract

Returns a new instance of Abstract.

Raises:

  • (ArgumentError)


7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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
54
# File 'lib/video_screenshoter/abstract.rb', line 7

def initialize params
  params.each_with_index do |param, index|
    params[index] = Shellwords.escape(param) if param.is_a?(String)
  end
  [:ffmpeg, :imagemagick, :output_dir, :output_file, :verbose].each do |attr|
    self.send("#{attr}=".to_sym, params[attr].nil? ? VideoScreenshoter.send(attr) : params[attr])
  end
  FileUtils.mkdir_p self.output_dir
  self.input = params[:input]
  self.duration = input_duration
  raise ArgumentError.new('Incorrect or empty m3u8 playlist') if duration.to_i == 0
  
  # if false ffmpeg uses fast seek by keyframes like: ffmpeg -ss ... -i
  self.exact = params[:exact]
  
  if params[:times]
    self.exact = true if exact.nil?
    self.times = params[:times].to_a.map do |time|
      if time.is_a?(String) && matches = time.match(/(.*)%$/)
        time = matches[1].to_f / 100 * duration
      end
      time = duration + time if time < 0
      time = time.to_i
      time
    end.uniq
  elsif (number = params[:number].to_i) > 0
    [:offset_start, :offset_end].each do |attr|
      if percent = params[attr].to_s.match(/^(\d+)\\?%$/).to_a[1]
        self.send("#{attr}=", duration * percent.to_i / 100.0)
      else
        self.send("#{attr}=", params[attr].to_f)
      end
    end
    self.times = number.times.to_a.map { |time| ((offset_start + (duration - offset_start - offset_end) / number * time) * 100).round / 100.0 }.uniq
  else
    raise ArgumentError.new('times or number required') if times.empty?
  end
  
  self.size = params[:size] ? "-s #{params[:size]}" : ''

  # TODO possibility to replace original image by presetted image
  if params[:presets] && params[:presets].is_a?(Hash)
    self.presets = {}
    params[:presets].each do |name, preset|
      self.presets[name.to_sym] = !preset || preset.empty? || preset.index('-') == 0 ? preset : "-resize #{preset}"
    end
  end
end

Instance Attribute Details

#durationObject

Returns the value of attribute duration.



5
6
7
# File 'lib/video_screenshoter/abstract.rb', line 5

def duration
  @duration
end

#exactObject

Returns the value of attribute exact.



5
6
7
# File 'lib/video_screenshoter/abstract.rb', line 5

def exact
  @exact
end

#ffmpegObject

Returns the value of attribute ffmpeg.



5
6
7
# File 'lib/video_screenshoter/abstract.rb', line 5

def ffmpeg
  @ffmpeg
end

#imagemagickObject

Returns the value of attribute imagemagick.



5
6
7
# File 'lib/video_screenshoter/abstract.rb', line 5

def imagemagick
  @imagemagick
end

#inputObject

Returns the value of attribute input.



5
6
7
# File 'lib/video_screenshoter/abstract.rb', line 5

def input
  @input
end

#offset_endObject

Returns the value of attribute offset_end.



5
6
7
# File 'lib/video_screenshoter/abstract.rb', line 5

def offset_end
  @offset_end
end

#offset_startObject

Returns the value of attribute offset_start.



5
6
7
# File 'lib/video_screenshoter/abstract.rb', line 5

def offset_start
  @offset_start
end

#output_dirObject

Returns the value of attribute output_dir.



5
6
7
# File 'lib/video_screenshoter/abstract.rb', line 5

def output_dir
  @output_dir
end

#output_fileObject

Returns the value of attribute output_file.



5
6
7
# File 'lib/video_screenshoter/abstract.rb', line 5

def output_file
  @output_file
end

#presetsObject

Returns the value of attribute presets.



5
6
7
# File 'lib/video_screenshoter/abstract.rb', line 5

def presets
  @presets
end

#sizeObject

Returns the value of attribute size.



5
6
7
# File 'lib/video_screenshoter/abstract.rb', line 5

def size
  @size
end

#timesObject

Returns the value of attribute times.



5
6
7
# File 'lib/video_screenshoter/abstract.rb', line 5

def times
  @times
end

#verboseObject

Returns the value of attribute verbose.



5
6
7
# File 'lib/video_screenshoter/abstract.rb', line 5

def verbose
  @verbose
end

Instance Method Details

#ffmpeg_command(input, output, time) ⇒ Object



62
63
64
65
# File 'lib/video_screenshoter/abstract.rb', line 62

def ffmpeg_command input, output, time
  is = exact ? "-i #{input} -ss #{time}" : "-ss #{time} -i #{input}"
  "#{ffmpeg} #{is} -acodec -an #{size} -f image2 -vframes 1 -y #{output} 1>/dev/null 2>&1"
end

#ffmpeg_run(time = nil) ⇒ Object



67
68
69
70
71
# File 'lib/video_screenshoter/abstract.rb', line 67

def ffmpeg_run time = nil
  cmd = ffmpeg_command(input, output_fullpath(time), time)
  puts cmd if verbose
  system cmd
end

#imagemagick_command(input, preset_name) ⇒ Object



77
78
79
80
81
82
83
84
# File 'lib/video_screenshoter/abstract.rb', line 77

def imagemagick_command input, preset_name
  preset = presets[preset_name.to_sym]
  if !preset || preset.empty?
    "cp #{input} #{output_with_preset(input, preset_name)}"
  else
    "#{imagemagick} #{input} #{preset} #{output_with_preset(input, preset_name)}"
  end
end

#imagemagick_run(scr) ⇒ Object



86
87
88
89
90
91
92
93
94
# File 'lib/video_screenshoter/abstract.rb', line 86

def imagemagick_run scr
  if presets
    presets.each do |preset_name, preset|
      cmd = imagemagick_command(scr, preset_name)
      puts cmd if verbose
      system cmd
    end
  end
end

#output_fullpath(time, preset = nil) ⇒ Object



56
57
58
59
60
# File 'lib/video_screenshoter/abstract.rb', line 56

def output_fullpath time, preset = nil
  res = sprintf(File.join(output_dir, output_file), time)
  res.sub!(File.extname(res), "_#{preset}#{File.extname(res)}") if preset
  res
end

#output_with_preset(input, preset_name) ⇒ Object



73
74
75
# File 'lib/video_screenshoter/abstract.rb', line 73

def output_with_preset input, preset_name
  File.join(output_dir, File.basename(input, File.extname(input)) + '_' + preset_name.to_s + File.extname(input))
end

#runObject

Raises:

  • (NotImplementedError)


96
97
98
# File 'lib/video_screenshoter/abstract.rb', line 96

def run
  raise NotImplementedError
end