video_transcoding 0.23.0 → 0.25.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +547 -0
- data/LICENSE +1 -1
- data/README.md +7 -497
- data/bin/convert-video +17 -2
- data/bin/detect-crop +3 -3
- data/bin/query-handbrake-log +2 -2
- data/bin/transcode-video +130 -34
- data/lib/video_transcoding.rb +1 -1
- data/lib/video_transcoding/cli.rb +1 -1
- data/lib/video_transcoding/console.rb +1 -1
- data/lib/video_transcoding/copyright.rb +2 -2
- data/lib/video_transcoding/crop.rb +1 -1
- data/lib/video_transcoding/errors.rb +1 -1
- data/lib/video_transcoding/ffmpeg.rb +1 -1
- data/lib/video_transcoding/handbrake.rb +1 -1
- data/lib/video_transcoding/media.rb +1 -1
- data/lib/video_transcoding/mkvpropedit.rb +1 -1
- data/lib/video_transcoding/mp4track.rb +1 -1
- data/lib/video_transcoding/tool.rb +1 -1
- data/lib/video_transcoding/version.rb +2 -2
- metadata +4 -3
data/bin/convert-video
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
#
|
3
3
|
# convert-video
|
4
4
|
#
|
5
|
-
# Copyright (c) 2013-
|
5
|
+
# Copyright (c) 2013-2020 Don Melton
|
6
6
|
#
|
7
7
|
|
8
8
|
$LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
|
@@ -436,8 +436,23 @@ HERE
|
|
436
436
|
Process.kill 'INT', io.pid
|
437
437
|
end
|
438
438
|
|
439
|
+
buffer = ''
|
440
|
+
|
439
441
|
io.each_char do |char|
|
440
|
-
|
442
|
+
if (char.bytes[0] & 0x80) != 0
|
443
|
+
buffer << char
|
444
|
+
else
|
445
|
+
if not buffer.empty?
|
446
|
+
print buffer
|
447
|
+
buffer = ''
|
448
|
+
end
|
449
|
+
|
450
|
+
print char
|
451
|
+
end
|
452
|
+
end
|
453
|
+
|
454
|
+
if not buffer.empty?
|
455
|
+
print buffer
|
441
456
|
end
|
442
457
|
end
|
443
458
|
rescue SystemCallError => e
|
data/bin/detect-crop
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
#
|
3
3
|
# detect-crop
|
4
4
|
#
|
5
|
-
# Copyright (c) 2013-
|
5
|
+
# Copyright (c) 2013-2020 Don Melton
|
6
6
|
#
|
7
7
|
|
8
8
|
$LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
|
@@ -90,8 +90,8 @@ HERE
|
|
90
90
|
|
91
91
|
print_all = ->(crop) do
|
92
92
|
puts
|
93
|
-
puts "mpv --no-audio --vf
|
94
|
-
puts "mpv --no-audio --vf
|
93
|
+
puts "mpv --no-audio --vf=\"lavfi=[drawbox=#{Crop.drawbox_string(crop, width, height)}:invert:1]\" #{shell_path}"
|
94
|
+
puts "mpv --no-audio --vf=crop=#{Crop.player_string(crop, width, height)} #{shell_path}"
|
95
95
|
print_transcode.call crop
|
96
96
|
end
|
97
97
|
|
data/bin/query-handbrake-log
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
#
|
3
3
|
# query-handbrake-log
|
4
4
|
#
|
5
|
-
# Copyright (c) 2013-
|
5
|
+
# Copyright (c) 2013-2020 Don Melton
|
6
6
|
#
|
7
7
|
|
8
8
|
$LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
|
@@ -137,7 +137,7 @@ HERE
|
|
137
137
|
File.foreach(log) do |line|
|
138
138
|
found = true if not found and line =~ /^HandBrake/
|
139
139
|
count += 1
|
140
|
-
fail "not a HandBrake-generated `.log` file: #{log}" if count >
|
140
|
+
fail "not a HandBrake-generated `.log` file: #{log}" if count > 10 and not found
|
141
141
|
duration_line = line if duration_line.nil? and line =~ /\+ duration: /
|
142
142
|
rate_line = line if line =~ /\+ frame rate: /
|
143
143
|
|
data/bin/transcode-video
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
#
|
3
3
|
# transcode-video
|
4
4
|
#
|
5
|
-
# Copyright (c) 2013-
|
5
|
+
# Copyright (c) 2013-2020 Don Melton
|
6
6
|
#
|
7
7
|
|
8
8
|
$LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
|
@@ -89,8 +89,10 @@ Video options:
|
|
89
89
|
(use `--crop auto` for `HandBrakeCLI` behavior)
|
90
90
|
--constrain-crop
|
91
91
|
constrain `--crop detect` to optimal shape
|
92
|
-
--fallback-crop handbrake|ffmpeg|none
|
92
|
+
--fallback-crop handbrake|ffmpeg|minimal|none
|
93
93
|
select fallback crop values if `--crop detect` fails
|
94
|
+
(`minimal` uses the smallest possible crop values
|
95
|
+
combining results from `HandBrakeCLI` and `ffmpeg`)
|
94
96
|
--720p fit video within 1280x720 pixel bounds
|
95
97
|
--max-width WIDTH, --max-height HEIGHT
|
96
98
|
fit video within horizontal and/or vertical pixel bounds
|
@@ -134,18 +136,21 @@ Audio options:
|
|
134
136
|
(can be used multiple times)
|
135
137
|
--reverse-double-order
|
136
138
|
reverse order of `double` width audio output tracks
|
137
|
-
--
|
138
|
-
|
139
|
-
(
|
139
|
+
--audio-format surround|stereo|all=ac3|aac
|
140
|
+
set audio format for specific or all output tracks
|
141
|
+
(default for surround: ac3; default for stereo: aac)
|
142
|
+
--keep-ac3-stereo
|
143
|
+
copy rather than transcode AC-3 stereo or mono audio tracks
|
144
|
+
even when the current stereo format is AAC
|
140
145
|
--ac3-encoder ac3|eac3
|
141
146
|
set AC-3 audio encoder (default: ac3)
|
142
147
|
--ac3-bitrate 384|448|640|768|1536
|
143
|
-
set AC-3 audio bitrate (default: 640)
|
148
|
+
set AC-3 surround audio bitrate (default: 640)
|
144
149
|
--pass-ac3-bitrate 384|448|640|768|1536
|
145
|
-
set AC-3
|
150
|
+
set AC-3 surround pass-through bitrate (default: 640)
|
146
151
|
--copy-audio TRACK|all
|
147
152
|
try to copy track selected by number in its original format
|
148
|
-
falling back to
|
153
|
+
falling back to surround format if original not allowed
|
149
154
|
or try to copy all tracks in same manner
|
150
155
|
(only applies to main and explicitly added audio tracks)
|
151
156
|
(can be used multiple times)
|
@@ -157,8 +162,10 @@ Audio options:
|
|
157
162
|
(can be used multiple times)
|
158
163
|
--aac-encoder NAME
|
159
164
|
use named AAC audio encoder (default: platform dependent)
|
160
|
-
--mixdown dpl2
|
161
|
-
set mixdown
|
165
|
+
--mixdown stereo|dpl2
|
166
|
+
set mixdown for stereo audio output tracks
|
167
|
+
to regular stereo or Dolby Pro Logic II format
|
168
|
+
(default: stereo)
|
162
169
|
--no-audio disable all audio output
|
163
170
|
|
164
171
|
Subtitle options:
|
@@ -253,14 +260,16 @@ HERE
|
|
253
260
|
@audio_language = []
|
254
261
|
@audio_width = {:main => :double, :other => :stereo}
|
255
262
|
@reverse_double_order = false
|
256
|
-
@
|
263
|
+
@surround_format = 'ac3'
|
264
|
+
@stereo_format = 'aac'
|
265
|
+
@keep_ac3_stereo = false
|
257
266
|
@ac3_encoder = 'ac3'
|
258
267
|
@ac3_bitrate = 640
|
259
268
|
@pass_ac3_bitrate = 640
|
260
269
|
@copy_audio = []
|
261
270
|
@copy_audio_name = []
|
262
271
|
@aac_encoder = nil
|
263
|
-
@mixdown = '
|
272
|
+
@mixdown = 'stereo'
|
264
273
|
@burn_subtitle = nil
|
265
274
|
@force_subtitle = nil
|
266
275
|
@extra_subtitle = []
|
@@ -430,7 +439,7 @@ HERE
|
|
430
439
|
|
431
440
|
opts.on '--fallback-crop ARG' do |arg|
|
432
441
|
@fallback_crop = case arg
|
433
|
-
when 'handbrake', 'ffmpeg', 'mplayer', 'none'
|
442
|
+
when 'handbrake', 'ffmpeg', 'mplayer', 'minimal', 'none'
|
434
443
|
arg.to_sym
|
435
444
|
else
|
436
445
|
fail UsageError, "invalid fallback crop argument: #{arg}"
|
@@ -557,10 +566,35 @@ HERE
|
|
557
566
|
|
558
567
|
opts.on('--reverse-double-order') { @reverse_double_order = true }
|
559
568
|
|
569
|
+
opts.on '--audio-format ARG' do |arg|
|
570
|
+
if arg =~ /^(surround|stereo|all)=(ac3|aac)$/
|
571
|
+
case $1
|
572
|
+
when 'surround'
|
573
|
+
@surround_format = $2
|
574
|
+
when 'stereo'
|
575
|
+
@stereo_format = $2
|
576
|
+
else
|
577
|
+
@surround_format = $2
|
578
|
+
@stereo_format = $2
|
579
|
+
end
|
580
|
+
else
|
581
|
+
fail UsageError, "invalid audio format argument: #{arg}"
|
582
|
+
end
|
583
|
+
end
|
584
|
+
|
585
|
+
opts.on '--keep-ac3-stereo' do
|
586
|
+
@keep_ac3_stereo = true
|
587
|
+
end
|
588
|
+
|
560
589
|
opts.on '--prefer-ac3' do
|
561
|
-
|
590
|
+
Console.warn '**********'
|
591
|
+
Console.warn 'Using deprecated option: --prefer-ac3'
|
592
|
+
Console.warn "Replace with: --audio-width all=surround --audio-format all=ac3"
|
593
|
+
Console.warn '**********'
|
562
594
|
@audio_width[:main] = :surround
|
563
595
|
@audio_width[:other] = :surround
|
596
|
+
@surround_format = 'ac3'
|
597
|
+
@stereo_format = 'ac3'
|
564
598
|
end
|
565
599
|
|
566
600
|
opts.on '--ac3-encoder ARG' do |arg|
|
@@ -620,7 +654,7 @@ HERE
|
|
620
654
|
|
621
655
|
opts.on '--mixdown ARG' do |arg|
|
622
656
|
@mixdown = case arg
|
623
|
-
when '
|
657
|
+
when 'stereo', 'dpl2'
|
624
658
|
arg
|
625
659
|
else
|
626
660
|
fail UsageError, "invalid mixdown: #{arg}"
|
@@ -843,6 +877,7 @@ HERE
|
|
843
877
|
adjust_metadata(handbrake_options['output'])
|
844
878
|
|
845
879
|
unless @dry_run
|
880
|
+
puts "Completed: #{handbrake_options['output']}"
|
846
881
|
seconds = Time.now.tv_sec - seconds
|
847
882
|
hours = seconds / (60 * 60)
|
848
883
|
minutes = (seconds / 60) % 60
|
@@ -1053,6 +1088,13 @@ HERE
|
|
1053
1088
|
hb_crop
|
1054
1089
|
when :ffmpeg, :mplayer
|
1055
1090
|
ff_crop
|
1091
|
+
when :minimal
|
1092
|
+
{
|
1093
|
+
:top => [hb_crop[:top], ff_crop[:top]].min,
|
1094
|
+
:bottom => [hb_crop[:bottom], ff_crop[:bottom]].min,
|
1095
|
+
:left => [hb_crop[:left], ff_crop[:left]].min,
|
1096
|
+
:right => [hb_crop[:right], ff_crop[:right]].min
|
1097
|
+
}
|
1056
1098
|
when :none
|
1057
1099
|
{:top => 0, :bottom => 0, :left => 0, :right => 0}
|
1058
1100
|
else
|
@@ -1094,41 +1136,78 @@ HERE
|
|
1094
1136
|
end
|
1095
1137
|
|
1096
1138
|
tracks, encoders, bitrates, mixdowns, names = [], [], [], [], []
|
1139
|
+
@aac_encoder ||= HandBrake.aac_encoder
|
1140
|
+
surround_encoder = @surround_format == 'ac3' ? @ac3_encoder : @aac_encoder
|
1141
|
+
stereo_encoder = @stereo_format == 'ac3' ? @ac3_encoder : @aac_encoder
|
1097
1142
|
|
1098
1143
|
add_surround = ->(info, copy) do
|
1099
1144
|
bitrate = info[:bps].nil? ? 640 : info[:bps] / 1000
|
1100
1145
|
|
1101
|
-
if
|
1102
|
-
(
|
1103
|
-
|
1104
|
-
|
1146
|
+
if copy or
|
1147
|
+
(@surround_format == 'ac3' and
|
1148
|
+
((@ac3_encoder == 'ac3' and info[:format] == 'AC3') or
|
1149
|
+
(@ac3_encoder == 'eac3' and info[:format] =~ /^(?:E-)?AC3$/)) and
|
1150
|
+
bitrate <= @pass_ac3_bitrate) or
|
1151
|
+
(@surround_format == 'aac' and info[:format] =~ /^AAC/)
|
1105
1152
|
encoders << 'copy'
|
1106
1153
|
bitrates << ''
|
1154
|
+
mixdowns << ''
|
1107
1155
|
else
|
1108
|
-
encoders <<
|
1156
|
+
encoders << surround_encoder
|
1109
1157
|
|
1110
|
-
if
|
1111
|
-
|
1112
|
-
|
1158
|
+
if @surround_format == 'ac3'
|
1159
|
+
if (@ac3_encoder == 'ac3' and @ac3_bitrate >= 640) or
|
1160
|
+
(@ac3_encoder == 'eac3' and @ac3_bitrate == 1536)
|
1161
|
+
bitrates << ''
|
1162
|
+
else
|
1163
|
+
bitrates << @ac3_bitrate.to_s
|
1164
|
+
end
|
1165
|
+
|
1166
|
+
mixdowns << ''
|
1113
1167
|
else
|
1114
|
-
bitrates <<
|
1168
|
+
bitrates << ''
|
1169
|
+
mixdowns << '5point1'
|
1115
1170
|
end
|
1116
1171
|
end
|
1117
|
-
|
1118
|
-
mixdowns << ''
|
1119
1172
|
end
|
1120
1173
|
|
1121
1174
|
add_stereo = ->(info, copy) do
|
1122
|
-
if copy or
|
1175
|
+
if copy or
|
1176
|
+
(info[:channels] <= 2.0 and
|
1177
|
+
((@stereo_format == 'aac' and info[:format] =~ /^AAC/) or
|
1178
|
+
(((@ac3_encoder == 'ac3' and info[:format] == 'AC3') or
|
1179
|
+
(@ac3_encoder == 'eac3' and info[:format] =~ /^(?:E-)?AC3$/)) and
|
1180
|
+
(@keep_ac3_stereo or @stereo_format == 'ac3'))))
|
1123
1181
|
encoders << 'copy'
|
1182
|
+
bitrates << ''
|
1124
1183
|
mixdowns << ''
|
1125
1184
|
else
|
1126
|
-
|
1127
|
-
|
1185
|
+
encoders << stereo_encoder
|
1186
|
+
|
1187
|
+
if stereo_encoder == 'eac3'
|
1188
|
+
if @ac3_bitrate == 1536
|
1189
|
+
bitrates << ''
|
1190
|
+
else
|
1191
|
+
if (info[:channels] > 1.0)
|
1192
|
+
if @ac3_bitrate == 768
|
1193
|
+
bitrates << '384'
|
1194
|
+
else
|
1195
|
+
bitrates << '224'
|
1196
|
+
end
|
1197
|
+
else
|
1198
|
+
if @ac3_bitrate == 768
|
1199
|
+
bitrates << '192'
|
1200
|
+
else
|
1201
|
+
bitrates << '96'
|
1202
|
+
end
|
1203
|
+
end
|
1204
|
+
end
|
1205
|
+
else
|
1206
|
+
bitrates << ''
|
1207
|
+
end
|
1208
|
+
|
1128
1209
|
mixdowns << (info[:channels] > 2.0 ? @mixdown : '')
|
1129
1210
|
end
|
1130
|
-
|
1131
|
-
bitrates << ''
|
1132
1211
|
end
|
1133
1212
|
|
1134
1213
|
track_order.each do |track|
|
@@ -1138,6 +1217,7 @@ HERE
|
|
1138
1217
|
|
1139
1218
|
if @copy_audio_name.first == :all or @copy_audio_name.include? track
|
1140
1219
|
name = info.fetch(:name, '')
|
1220
|
+
name ||= ''
|
1141
1221
|
else
|
1142
1222
|
name = ''
|
1143
1223
|
end
|
@@ -1162,7 +1242,7 @@ HERE
|
|
1162
1242
|
add_stereo.call info, copy
|
1163
1243
|
end
|
1164
1244
|
when :surround
|
1165
|
-
if
|
1245
|
+
if (info[:channels] > 2.0)
|
1166
1246
|
add_surround.call info, copy
|
1167
1247
|
else
|
1168
1248
|
add_stereo.call info, copy
|
@@ -1175,7 +1255,7 @@ HERE
|
|
1175
1255
|
handbrake_options['audio'] = tracks.join(',')
|
1176
1256
|
encoders = encoders.join(',')
|
1177
1257
|
handbrake_options['aencoder'] = encoders if encoders.gsub(/,/, '') != ''
|
1178
|
-
handbrake_options['audio-fallback'] =
|
1258
|
+
handbrake_options['audio-fallback'] = surround_encoder unless @copy_audio.empty?
|
1179
1259
|
bitrates = bitrates.join(',')
|
1180
1260
|
handbrake_options['ab'] = bitrates if bitrates.gsub(/,/, '') != ''
|
1181
1261
|
mixdowns = mixdowns.join(',')
|
@@ -1336,10 +1416,26 @@ HERE
|
|
1336
1416
|
Process.kill 'INT', io.pid
|
1337
1417
|
end
|
1338
1418
|
|
1419
|
+
buffer = ''
|
1420
|
+
|
1339
1421
|
io.each_char do |char|
|
1340
|
-
|
1422
|
+
if (char.bytes[0] & 0x80) != 0
|
1423
|
+
buffer << char
|
1424
|
+
else
|
1425
|
+
if not buffer.empty?
|
1426
|
+
print buffer
|
1427
|
+
buffer = ''
|
1428
|
+
end
|
1429
|
+
|
1430
|
+
print char
|
1431
|
+
end
|
1432
|
+
|
1341
1433
|
log_file.print char unless log_file.nil?
|
1342
1434
|
end
|
1435
|
+
|
1436
|
+
if not buffer.empty?
|
1437
|
+
print buffer
|
1438
|
+
end
|
1343
1439
|
end
|
1344
1440
|
rescue SystemCallError => e
|
1345
1441
|
raise "transcoding failed: #{e}"
|
data/lib/video_transcoding.rb
CHANGED