Module: Video2gif::FFmpeg
- Includes:
- Subtitles
- Defined in:
- lib/video2gif/ffmpeg.rb,
lib/video2gif/ffmpeg/subtitles.rb
Defined Under Namespace
Modules: Subtitles
Constant Summary
collapse
- CROP_REGEX =
/crop=([0-9]+\:[0-9]+\:[0-9]+\:[0-9]+)/
Constants included
from Subtitles
Subtitles::KNOWN_BITMAP_FORMATS, Subtitles::KNOWN_TEXT_FORMATS
Class Method Summary
collapse
Methods included from Subtitles
included
Class Method Details
.crop(options) ⇒ Object
46
47
48
49
50
51
52
53
54
55
|
# File 'lib/video2gif/ffmpeg.rb', line 46
def self.crop(options)
crop_parameters = []
crop_parameters << "w=#{options[:wregion]}" if options[:wregion]
crop_parameters << "h=#{options[:hregion]}" if options[:hregion]
crop_parameters << "x=#{options[:xoffset]}" if options[:xoffset]
crop_parameters << "y=#{options[:yoffset]}" if options[:yoffset]
'crop=' + crop_parameters.join(':') unless crop_parameters.empty?
end
|
.cropdetect_command(options, logger, executable: 'ffmpeg') ⇒ Object
208
209
210
211
212
213
214
215
216
217
|
# File 'lib/video2gif/ffmpeg.rb', line 208
def self.cropdetect_command(options, logger, executable: 'ffmpeg')
command = ffmpeg_command(options, executable: executable)
command << '-filter_complex' << "cropdetect=limit=#{options[:autocrop]}"
command << '-f' << 'null'
command << '-'
logger.info(command.join(' ')) if options[:verbose] unless options[:quiet]
command
end
|
.drawtext(options) ⇒ Object
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
# File 'lib/video2gif/ffmpeg.rb', line 122
def self.drawtext(options)
if options[:text]
count_of_lines = options[:text].scan(/\\n/).count + 1
drawtext_parameters = []
drawtext_parameters << "x='#{ options[:xpos] || '(main_w/2-text_w/2)' }'"
drawtext_parameters << "y='#{ options[:ypos] || "(main_h-line_h*1.5*#{count_of_lines})" }'"
drawtext_parameters << "fontsize='#{ options[:textsize] || 32 }'"
drawtext_parameters << "fontcolor='#{ options[:textcolor] || 'white' }'"
drawtext_parameters << "borderw='#{ options[:textborder] || 2 }'"
drawtext_parameters << "fontfile='#{ options[:textfont] || 'Arial'}'\\\\:style='#{options[:textvariant] || 'Bold' }'"
drawtext_parameters << "text='#{text(options)}'"
'drawtext=' + drawtext_parameters.join(':')
end
end
|
.eq(options) ⇒ Object
99
100
101
102
103
104
105
106
107
108
109
110
111
|
# File 'lib/video2gif/ffmpeg.rb', line 99
def self.eq(options)
eq_parameters = []
eq_parameters << "contrast=#{options[:contrast]}" if options[:contrast]
eq_parameters << "brightness=#{options[:brightness]}" if options[:brightness]
eq_parameters << "saturation=#{options[:saturation]}" if options[:saturation]
eq_parameters << "gamma=#{options[:gamma]}" if options[:gamma]
eq_parameters << "gamma_r=#{options[:gamma_r]}" if options[:gamma_r]
eq_parameters << "gamma_g=#{options[:gamma_g]}" if options[:gamma_g]
eq_parameters << "gamma_b=#{options[:gamma_b]}" if options[:gamma_b]
'eq=' + eq_parameters.join(":")
end
|
.ffmpeg_command(options, executable: 'ffmpeg') ⇒ Object
194
195
196
197
198
199
200
201
202
203
204
205
206
|
# File 'lib/video2gif/ffmpeg.rb', line 194
def self.ffmpeg_command(options, executable: 'ffmpeg')
command = [executable]
command << '-y'
command << '-hide_banner'
command << '-loglevel' << 'verbose'
command << '-ss' << options[:seek] if options[:seek]
command << '-t' << options[:time] if options[:time]
command << '-i' << options[:input_filename]
command << '-an'
command << '-sn'
command << '-dn'
end
|
.ffprobe_command(options, logger, executable: 'ffprobe') ⇒ Object
182
183
184
185
186
187
188
189
190
191
192
|
# File 'lib/video2gif/ffmpeg.rb', line 182
def self.ffprobe_command(options, logger, executable: 'ffprobe')
command = [executable]
command << '-v' << 'error'
command << '-show_entries' << 'stream'
command << '-print_format' << 'json'
command << '-i' << options[:input_filename]
logger.info(command.join(' ')) if options[:verbose] unless options[:quiet]
command
end
|
.filtergraph(options) ⇒ Object
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
|
# File 'lib/video2gif/ffmpeg.rb', line 162
def self.filtergraph(options)
filtergraph = []
filtergraph << bitmap_subtitles_scale_overlay(options)
filtergraph << rate_with_interpolation(options)
filtergraph << fps(options)
filtergraph << options[:autocrop] if options[:autocrop]
filtergraph << crop(options)
filtergraph << zscale_and_tonemap(options)
filtergraph << scale(options)
filtergraph << eq(options)
filtergraph << text_subtitles(options)
filtergraph << drawtext(options)
filtergraph << split
filtergraph << palettegen(options)
filtergraph << paletteuse(options)
filtergraph.flatten.compact
end
|
.fps(options) ⇒ Object
42
43
44
|
# File 'lib/video2gif/ffmpeg.rb', line 42
def self.fps(options)
"fps=#{ options[:fps] || 20 }"
end
|
.gif_command(options, logger, executable: 'ffmpeg') ⇒ Object
219
220
221
222
223
224
225
226
227
228
|
# File 'lib/video2gif/ffmpeg.rb', line 219
def self.gif_command(options, logger, executable: 'ffmpeg')
command = ffmpeg_command(options, executable: executable)
command << '-filter_complex' << filtergraph(options).join(',')
command << '-f' << 'gif'
command << options[:output_filename]
logger.info(command.join(' ')) if options[:verbose] unless options[:quiet]
command
end
|
.interpolate(options) ⇒ Object
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
# File 'lib/video2gif/ffmpeg.rb', line 20
def self.interpolate(options)
if options[:rate] && Float(options[:rate]) < 1
minterpolate_parameters = []
minterpolate_parameters << 'mi_mode=mci'
minterpolate_parameters << 'mc_mode=aobmc'
minterpolate_parameters << 'me_mode=bidir'
minterpolate_parameters << 'me=epzs'
minterpolate_parameters << 'vsbmc=1'
minterpolate_parameters << "fps=#{video_info(options)[:avg_frame_rate] }/#{options[:rate]}"
'minterpolate=' + minterpolate_parameters.join(':')
end
end
|
.palettegen(options) ⇒ Object
143
144
145
146
147
148
149
150
|
# File 'lib/video2gif/ffmpeg.rb', line 143
def self.palettegen(options)
palettegen_parameters = []
palettegen_parameters << "#{ options[:palette] || 256 }"
palettegen_parameters << "stats_mode=#{options[:palettemode] || 'diff'}"
'[palettegen]palettegen=' + palettegen_parameters.join(':') + '[palette]'
end
|
.paletteuse(options) ⇒ Object
152
153
154
155
156
157
158
159
160
|
# File 'lib/video2gif/ffmpeg.rb', line 152
def self.paletteuse(options)
paletteuse_parameters = []
paletteuse_parameters << "dither=#{options[:dither] || 'floyd_steinberg'}"
paletteuse_parameters << 'diff_mode=rectangle'
paletteuse_parameters << "#{options[:palettemode] == 'single' ? 'new=1' : ''}"
'[paletteuse][palette]paletteuse=' + paletteuse_parameters.join(':')
end
|
.rate(options) ⇒ Object
16
17
18
|
# File 'lib/video2gif/ffmpeg.rb', line 16
def self.rate(options)
"setpts=PTS/#{options[:rate]}" if options[:rate]
end
|
.rate_with_interpolation(options) ⇒ Object
35
36
37
38
39
40
|
# File 'lib/video2gif/ffmpeg.rb', line 35
def self.rate_with_interpolation(options)
[
rate(options),
interpolate(options)
]
end
|
.scale(options) ⇒ Object
86
87
88
89
90
91
92
93
94
95
96
97
|
# File 'lib/video2gif/ffmpeg.rb', line 86
def self.scale(options)
unless options[:tonemap]
scale_parameters = []
scale_parameters << 'flags=lanczos'
scale_parameters << 'sws_dither=none'
scale_parameters << "width=#{ options[:width] || 480 }"
scale_parameters << "height=trunc(#{ options[:width] || 480 }/dar)"
'scale=' + scale_parameters.join(':')
end
end
|
.split ⇒ Object
139
140
141
|
# File 'lib/video2gif/ffmpeg.rb', line 139
def self.split
'split[palettegen][paletteuse]'
end
|
.text(options) ⇒ Object
113
114
115
116
117
118
119
120
|
# File 'lib/video2gif/ffmpeg.rb', line 113
def self.text(options)
options[:text].gsub(/\\n/, '')
.gsub(/([:])/, '\\\\\\\\\\1')
.gsub(/([,])/, '\\\\\\1')
.gsub(/\b'\b/, "\u2019")
.gsub(/\B"\b([^"\u201C\u201D\u201E\u201F\u2033\u2036\r\n]+)\b?"\B/, "\u201C\\1\u201D")
.gsub(/\B'\b([^'\u2018\u2019\u201A\u201B\u2032\u2035\r\n]+)\b?'\B/, "\u2018\\1\u2019")
end
|
.tonemap(options) ⇒ Object
68
69
70
71
72
73
74
75
|
# File 'lib/video2gif/ffmpeg.rb', line 68
def self.tonemap(options)
%W[
zscale=transfer=linear
tonemap=tonemap=#{options[:tonemap]}
zscale=transfer=bt709
format=gbrp
]
end
|
.video_info(options) ⇒ Object
12
13
14
|
# File 'lib/video2gif/ffmpeg.rb', line 12
def self.video_info(options)
options[:probe_infos][:streams].find { |s| s[:codec_type] == 'video' }
end
|
.zscale(options) ⇒ Object
57
58
59
60
61
62
63
64
65
66
|
# File 'lib/video2gif/ffmpeg.rb', line 57
def self.zscale(options)
zscale_parameters = []
zscale_parameters << 'dither=none'
zscale_parameters << 'filter=lanczos'
zscale_parameters << "width=#{ options[:width] || 480 }"
zscale_parameters << "height=trunc(#{ options[:width] || 480 }/dar)"
'zscale=' + zscale_parameters.join(':')
end
|
.zscale_and_tonemap(options) ⇒ Object
77
78
79
80
81
82
83
84
|
# File 'lib/video2gif/ffmpeg.rb', line 77
def self.zscale_and_tonemap(options)
if options[:tonemap]
[
zscale(options),
tonemap(options)
]
end
end
|