video_transcoding 0.17.4 → 0.18.0
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/README.md +21 -4
- data/bin/detect-crop +3 -2
- data/bin/transcode-video +74 -74
- data/lib/video_transcoding/media.rb +56 -3
- data/lib/video_transcoding/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 104584864a42079faafac8620a1f5ab6d54e13ea
|
4
|
+
data.tar.gz: d48bf0e8b305c1aa6d7adb448bf956d33c853d67
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8aea1ce8b0cb5d02d3294ad90f89a3c5c9db0477c643a41158b051e6da7220cf91873bb3ae5932895e03caeba3013cb040d1d9e51a280c070dc3c2f674874a04
|
7
|
+
data.tar.gz: e397fcab87c71bf434d5abf04db8428f28912f5be0c9347393c4d9dbbeac1b60e74087996ef8481d34f5632ff04ea0c8e2294e420b4dcfa1040c2fc5b145fac2
|
data/README.md
CHANGED
@@ -551,7 +551,9 @@ The transcoding process is started by executing the script:
|
|
551
551
|
|
552
552
|
The path is first deleted from the `queue.txt` file and then passed as an argument to the `transcode-video.` tool. To pause after `transcode-video` returns, simply insert a blank line at the top of the `queue.txt` file.
|
553
553
|
|
554
|
-
These examples are written in Bash and only supply crop values. But almost any scripting language can be used and any option can be changed on a per input basis.
|
554
|
+
These examples are written in Bash and only supply crop values. But almost any scripting language can be used and any option can be changed on a per input basis. [Nick Wronski](https://github.com/nwronski) has written a batch-processing wrapper for `transcode-video` in [Node.js](https://nodejs.org/), available here:
|
555
|
+
|
556
|
+
<https://github.com/nwronski/batch-transcode-video>
|
555
557
|
|
556
558
|
## Explanation
|
557
559
|
|
@@ -570,9 +572,7 @@ These are actually the settings used by my special ratecontrol system to configu
|
|
570
572
|
|
571
573
|
My system attempts to produce the highest possible video quality near a target bitrate. That target is automatically determined by `transcode-video` using the resolution of the input. For example, the default target for 1080p output is `6000` Kbps, which is about one-fifth the video bitrate found on a typical Blu-ray Disc.
|
572
574
|
|
573
|
-
The average bitrate (ABR) mode in x264 is normally used to target a specific bitrate.
|
574
|
-
|
575
|
-
Instead, I leverage the constant quality ratecontrol system in x264. This algorithm uses a constant ratefactor (CRF) to target a specific quality instead of a bitrate. A CRF is represented by a number from `0` to `51` with lower values indicating higher quality. The special value of `0` is for lossless output.
|
575
|
+
The average bitrate (ABR) mode in x264 is normally used to target a specific bitrate. Instead, I leverage the constant quality ratecontrol system in x264. This algorithm uses a constant ratefactor (CRF) to target a specific quality instead of a bitrate. A CRF is represented by a number from `0` to `51` with lower values indicating higher quality. The special value of `0` is for lossless output.
|
576
576
|
|
577
577
|
Unfortunately, the output bitrate is extremely unpredictable when using this CRF-based system. Typically, people pick a middle-level CRF value as their quality target and just hope for the best. This is what most of the presets built into HandBrake do, choosing a CRF of `20` or `22`.
|
578
578
|
|
@@ -662,6 +662,23 @@ For a few problematic videos, I have to apply options like `--force-rate 23.976
|
|
662
662
|
|
663
663
|
## History
|
664
664
|
|
665
|
+
Saturday, December 2, 2017
|
666
|
+
|
667
|
+
### [0.18.0](https://github.com/donmelton/video_transcoding/releases/tag/0.18.0)
|
668
|
+
|
669
|
+
* Improve the average bitrate (ABR) ratecontrol system provided by the `--abr` option in `transcode-video`. Via [ #179](https://github.com/donmelton/video_transcoding/issues/179).
|
670
|
+
* Implement it with a maximum bitrate constraint to raise its overal quality level and guarantee that it will not generate any `VBV underflow` warnings like the default ratecontrol system.
|
671
|
+
* Signal Hypothetical Reference Decoder (HRD) information, meaning that the VBV maximum bitrate value is added as metadata to the output video, something you should _not_ do when using the default ratecontrol system.
|
672
|
+
* Move it from the "Advanced" to the "Quality" section in the `--help` output and describe its quality output as "different" rather than "lower" compared to the default ratecontrol system.
|
673
|
+
* Also remove the no-longer valid characterization of ABR in the "Explanation" section of the "README" document.
|
674
|
+
* Deprecate the poorly named `--cvbr` and `--vbr` options in `transcode-video` and remove them from the `--help` output.
|
675
|
+
* The ratecontrol system implemented by the `--cvbr` option was always experimental. After much testing, it was found to be noticeably lower in quality compared to the default and to the new ABR implementation.
|
676
|
+
* The ratecontrol system implemented by the `--vbr` option was only ever intended for comparison testing. And probably used only by myself.
|
677
|
+
* Modify `transcode-video` to no longer re-calculate `vbv-bufsize` based on any user input value for `vbv-maxrate`. Instead, always calculate both `vbv-maxrate` and `vbv-bufsize` based on the target video bitrate.
|
678
|
+
* Deprecate the `--player` option in `detect-crop` and remove it from the `--help` output.
|
679
|
+
* Fix failure of subtitle detection for HandBrake nightly builds. Language detection for subtitles in disc image directory input and individual closed caption tracks may still be wrong but will not be fixed at this time. Via [ #172](https://github.com/donmelton/video_transcoding/issues/172).
|
680
|
+
* Mention [Nick Wronski](https://github.com/nwronski)'s nifty batch-processing wrapper for `transcode-video` in the the "README" document. Thanks, [@JMoVS](https://github.com/JMoVS)! Via [ #180](https://github.com/donmelton/video_transcoding/pull/180).
|
681
|
+
|
665
682
|
Sunday, September 10, 2017
|
666
683
|
|
667
684
|
### [0.17.4](https://github.com/donmelton/video_transcoding/releases/tag/0.17.4)
|
data/bin/detect-crop
CHANGED
@@ -31,8 +31,6 @@ Usage: #{$PROGRAM_NAME} [OPTION]... [FILE|DIRECTORY]...
|
|
31
31
|
(default: main feature or first listed)
|
32
32
|
--constrain constrain crop to optimal shape
|
33
33
|
--values-only output only unambiguous crop values, not commands
|
34
|
-
--player mpv|mplayer
|
35
|
-
select player for preview commands (default: mpv)
|
36
34
|
|
37
35
|
-v, --verbose increase diagnostic information
|
38
36
|
-q, --quiet decrease " "
|
@@ -60,6 +58,9 @@ HERE
|
|
60
58
|
opts.on('--values-only') { @values_only = true }
|
61
59
|
|
62
60
|
opts.on '--player ARG' do |arg|
|
61
|
+
Console.warn '**********'
|
62
|
+
Console.warn 'Using deprecated option: --player'
|
63
|
+
Console.warn '**********'
|
63
64
|
@player = case arg
|
64
65
|
when 'mpv', 'mplayer'
|
65
66
|
arg.to_sym
|
data/bin/transcode-video
CHANGED
@@ -56,6 +56,8 @@ Output options:
|
|
56
56
|
--dry-run don't transcode, just show `HandBrakeCLI` command and exit
|
57
57
|
|
58
58
|
Quality options:
|
59
|
+
--abr use constrained average bitrate (ABR) ratecontrol
|
60
|
+
(predictable size with different quality than default)
|
59
61
|
--target big|small
|
60
62
|
apply video bitrate target macro for all input resolutions
|
61
63
|
(`big` trades some size for increased quality)
|
@@ -186,13 +188,6 @@ External subtitle options:
|
|
186
188
|
(can be used multiple times)
|
187
189
|
|
188
190
|
Advanced options:
|
189
|
-
--cvbr use simple constrained variable bitrate (CVBR) ratecontrol
|
190
|
-
(more predictable size while avoiding VBV underflows)
|
191
|
-
(use with `--target big` for best results)
|
192
|
-
--abr use modified average bitrate (ABR) ratecontrol
|
193
|
-
(predictable size but lower quality than default)
|
194
|
-
--vbr QUALITY use true VBR ratecontrol at constant video quality (0-51)
|
195
|
-
(unpredictable size but useful for comparison to default)
|
196
191
|
-E, --encoder-option NAME=VALUE|_NAME
|
197
192
|
pass x264 video encoder option by name with value
|
198
193
|
or disable use of option by prefixing name with "_"
|
@@ -229,10 +224,11 @@ HERE
|
|
229
224
|
@format = :mkv
|
230
225
|
@log = true
|
231
226
|
@dry_run = false
|
232
|
-
@
|
233
|
-
@
|
234
|
-
@
|
235
|
-
@
|
227
|
+
@use_abr = false
|
228
|
+
@target_bitrate_2160p = 12000
|
229
|
+
@target_bitrate_1080p = 6000
|
230
|
+
@target_bitrate_720p = 3000
|
231
|
+
@target_bitrate_480p = 1500
|
236
232
|
@quick = false
|
237
233
|
@veryquick = false
|
238
234
|
@crop = {:top => 0, :bottom => 0, :left => 0, :right => 0}
|
@@ -262,9 +258,6 @@ HERE
|
|
262
258
|
@srt_language = {}
|
263
259
|
@srt_encoding = {}
|
264
260
|
@srt_offset = {}
|
265
|
-
@use_cvbr = false
|
266
|
-
@use_abr = false
|
267
|
-
@vbr_quality = nil
|
268
261
|
@encoder_options = {}
|
269
262
|
@disable_encoder_options = []
|
270
263
|
@handbrake_options = {}
|
@@ -319,30 +312,34 @@ HERE
|
|
319
312
|
opts.on('--no-log') { @log = false }
|
320
313
|
opts.on('--dry-run') { @dry_run = true }
|
321
314
|
|
315
|
+
opts.on '--abr' do
|
316
|
+
@use_abr = true
|
317
|
+
end
|
318
|
+
|
322
319
|
opts.on '--target ARG' do |arg|
|
323
320
|
case arg
|
324
321
|
when 'big'
|
325
|
-
@
|
326
|
-
@
|
327
|
-
@
|
328
|
-
@
|
322
|
+
@target_bitrate_2160p = 16000
|
323
|
+
@target_bitrate_1080p = 8000
|
324
|
+
@target_bitrate_720p = 4000
|
325
|
+
@target_bitrate_480p = 2000
|
329
326
|
when 'small'
|
330
|
-
@
|
331
|
-
@
|
332
|
-
@
|
333
|
-
@
|
327
|
+
@target_bitrate_2160p = 8000
|
328
|
+
@target_bitrate_1080p = 4000
|
329
|
+
@target_bitrate_720p = 2000
|
330
|
+
@target_bitrate_480p = 1000
|
334
331
|
when /^([0-9]+p)=([1-9][0-9]*)$/
|
335
332
|
bitrate = $2.to_i
|
336
333
|
|
337
334
|
case $1
|
338
335
|
when '2160p'
|
339
|
-
@
|
336
|
+
@target_bitrate_2160p = bitrate
|
340
337
|
when '1080p'
|
341
|
-
@
|
338
|
+
@target_bitrate_1080p = bitrate
|
342
339
|
when '720p'
|
343
|
-
@
|
340
|
+
@target_bitrate_720p = bitrate
|
344
341
|
when '480p'
|
345
|
-
@
|
342
|
+
@target_bitrate_480p = bitrate
|
346
343
|
else
|
347
344
|
fail UsageError, "invalid target video bitrate resolution: #{$1}"
|
348
345
|
end
|
@@ -355,8 +352,6 @@ HERE
|
|
355
352
|
|
356
353
|
@target_bitrate = arg.to_i
|
357
354
|
end
|
358
|
-
|
359
|
-
@vbr_quality = nil
|
360
355
|
end
|
361
356
|
|
362
357
|
opts.on '--quick' do
|
@@ -702,24 +697,6 @@ HERE
|
|
702
697
|
@srt_offset[@srt_file.size - 1] = arg
|
703
698
|
end
|
704
699
|
|
705
|
-
opts.on '--cvbr' do
|
706
|
-
@use_cvbr = true
|
707
|
-
@use_abr = false
|
708
|
-
@vbr_quality = nil
|
709
|
-
end
|
710
|
-
|
711
|
-
opts.on '--abr' do
|
712
|
-
@use_abr = true
|
713
|
-
@use_cvbr = false
|
714
|
-
@vbr_quality = nil
|
715
|
-
end
|
716
|
-
|
717
|
-
opts.on '--vbr ARG', Float do |arg|
|
718
|
-
@vbr_quality = arg
|
719
|
-
@use_cvbr = false
|
720
|
-
@use_abr = false
|
721
|
-
end
|
722
|
-
|
723
700
|
opts.on '-E', '--encoder-option ARG' do |arg|
|
724
701
|
if arg =~ /^([a-z0-9][a-z0-9_-]+)=([^ :]+)$/
|
725
702
|
@encoder_options[$1] = $2
|
@@ -743,6 +720,30 @@ HERE
|
|
743
720
|
fail UsageError, "invalid HandBrakeCLI option: #{arg}"
|
744
721
|
end
|
745
722
|
end
|
723
|
+
|
724
|
+
opts.on '--cvbr' do
|
725
|
+
Console.warn '**********'
|
726
|
+
Console.warn 'Using deprecated option: --cvbr'
|
727
|
+
Console.warn 'Replace with: -E crf-max=30 -E _qpmax'
|
728
|
+
Console.warn '**********'
|
729
|
+
@encoder_options['crf-max'] = '30'
|
730
|
+
@disable_encoder_options << 'qpmax'
|
731
|
+
@use_abr = false
|
732
|
+
end
|
733
|
+
|
734
|
+
opts.on '--vbr ARG', Float do |arg|
|
735
|
+
crf = arg.to_s.gsub(/\.0+$/, '')
|
736
|
+
Console.warn '**********'
|
737
|
+
Console.warn 'Using deprecated option: --vbr'
|
738
|
+
Console.warn "Replace with: -H quality=#{crf} -E _vbv-maxrate -E _vbv-bufsize -E _crf-max -E _qpmax"
|
739
|
+
Console.warn '**********'
|
740
|
+
@handbrake_options['quality'] = crf
|
741
|
+
@disable_encoder_options << 'vbv-maxrate'
|
742
|
+
@disable_encoder_options << 'vbv-bufsize'
|
743
|
+
@disable_encoder_options << 'crf-max'
|
744
|
+
@disable_encoder_options << 'qpmax'
|
745
|
+
@use_abr = false
|
746
|
+
end
|
746
747
|
end
|
747
748
|
|
748
749
|
def force_handbrake_option(name, value)
|
@@ -923,16 +924,16 @@ HERE
|
|
923
924
|
|
924
925
|
if width > 1920 or height > 1080
|
925
926
|
encoder_level = '5.1'
|
926
|
-
|
927
|
+
bitrate = @target_bitrate_2160p
|
927
928
|
elsif width > 1280 or height > 720
|
928
929
|
encoder_level = '4.0'
|
929
|
-
|
930
|
+
bitrate = @target_bitrate_1080p
|
930
931
|
elsif width * height > 720 * 576
|
931
932
|
encoder_level = '3.1'
|
932
|
-
|
933
|
+
bitrate = @target_bitrate_720p
|
933
934
|
else
|
934
935
|
encoder_level = '3.0'
|
935
|
-
|
936
|
+
bitrate = @target_bitrate_480p
|
936
937
|
end
|
937
938
|
|
938
939
|
case encoder
|
@@ -950,37 +951,36 @@ HERE
|
|
950
951
|
handbrake_options['encoder-profile'] = 'main10'
|
951
952
|
end
|
952
953
|
|
953
|
-
if @
|
954
|
-
|
955
|
-
|
956
|
-
bitrate = ((((media.info[:size] * 8) / media.info[:duration]) / 1000) / 1000) * 1000
|
954
|
+
if @target_bitrate.nil?
|
955
|
+
unless media.info[:directory]
|
956
|
+
media_bitrate = ((((media.info[:size] * 8) / media.info[:duration]) / 1000) / 1000) * 1000
|
957
957
|
|
958
|
-
|
959
|
-
|
958
|
+
if media_bitrate < bitrate
|
959
|
+
min_bitrate = bitrate / 2
|
960
960
|
|
961
|
-
|
962
|
-
|
963
|
-
|
964
|
-
|
965
|
-
end
|
961
|
+
if media_bitrate < min_bitrate
|
962
|
+
bitrate = min_bitrate
|
963
|
+
else
|
964
|
+
bitrate = media_bitrate
|
966
965
|
end
|
967
966
|
end
|
968
|
-
else
|
969
|
-
max_bitrate = @target_bitrate
|
970
|
-
end
|
971
|
-
|
972
|
-
if @use_abr
|
973
|
-
handbrake_options['vb'] = max_bitrate.to_s
|
974
|
-
else
|
975
|
-
handbrake_options['quality'] = '1'
|
976
|
-
encoder_options['vbv-maxrate'] = max_bitrate.to_s
|
977
|
-
encoder_options['vbv-bufsize'] = (@encoder_options.fetch('vbv-maxrate', max_bitrate).to_i * 2).to_s
|
978
|
-
encoder_options['crf-max'] = @use_cvbr ? '30' : '25'
|
979
967
|
end
|
968
|
+
else
|
969
|
+
bitrate = @target_bitrate
|
970
|
+
end
|
980
971
|
|
981
|
-
|
972
|
+
if @use_abr
|
973
|
+
handbrake_options['vb'] = bitrate.to_s
|
974
|
+
encoder_options['vbv-maxrate'] = ((bitrate * 1.5).to_i).to_s
|
975
|
+
encoder_options['vbv-bufsize'] = ((bitrate * 2).to_i).to_s
|
976
|
+
encoder_options['nal-hrd'] = 'vbr' if encoder =~ /^x264(?:_10bit)?$/
|
977
|
+
encoder_options['hrd'] = '1' if encoder =~ /^x265(?:_1[026]bit)?$/
|
982
978
|
else
|
983
|
-
handbrake_options['quality']
|
979
|
+
handbrake_options['quality'] = '1'
|
980
|
+
encoder_options['vbv-maxrate'] = bitrate.to_s
|
981
|
+
encoder_options['vbv-bufsize'] = ((bitrate * 2).to_i).to_s
|
982
|
+
encoder_options['crf-max'] = '25'
|
983
|
+
encoder_options['qpmax'] = '34'
|
984
984
|
end
|
985
985
|
|
986
986
|
if (@quick or @veryquick) and
|
@@ -127,6 +127,13 @@ module VideoTranscoding
|
|
127
127
|
track_info[:format] = $3
|
128
128
|
track_info[:encoding] = $4
|
129
129
|
@info[:subtitle][track] = track_info
|
130
|
+
elsif line =~ /^ \+ ([0-9]+), .*\[(.*)\]/
|
131
|
+
track = $1.to_i
|
132
|
+
track_info = {}
|
133
|
+
track_info[:language] = 'und'
|
134
|
+
track_info[:format] = ($2 == 'PGS' or $2 == 'VOBSUB') ? 'Bitmap' : 'Text'
|
135
|
+
track_info[:encoding] = $2
|
136
|
+
@info[:subtitle][track] = track_info
|
130
137
|
end
|
131
138
|
end
|
132
139
|
|
@@ -137,10 +144,11 @@ module VideoTranscoding
|
|
137
144
|
subtitle_track = 0
|
138
145
|
|
139
146
|
@scan.each_line do |line|
|
140
|
-
if line =~ /[ ]+Stream #0[.:]([0-9]+)[
|
147
|
+
if line =~ /[ ]+Stream #0[.:]([0-9]+)(?:\(([a-z]{3})\))?: (Video|Audio|Subtitle): (.*)/
|
141
148
|
stream = $1.to_i
|
142
|
-
|
143
|
-
|
149
|
+
language = $2
|
150
|
+
type = $3
|
151
|
+
attributes = $4
|
144
152
|
|
145
153
|
case type
|
146
154
|
when 'Video'
|
@@ -181,6 +189,51 @@ module VideoTranscoding
|
|
181
189
|
track_info = @info[:subtitle][subtitle_track]
|
182
190
|
track_info[:stream] = stream
|
183
191
|
|
192
|
+
if track_info[:language] == 'und'
|
193
|
+
case language
|
194
|
+
when 'alb'
|
195
|
+
track_info[:language] = 'sqi'
|
196
|
+
when 'arm'
|
197
|
+
track_info[:language] = 'hye'
|
198
|
+
when 'baq'
|
199
|
+
track_info[:language] = 'eus'
|
200
|
+
when 'bur'
|
201
|
+
track_info[:language] = 'mya'
|
202
|
+
when 'chi'
|
203
|
+
track_info[:language] = 'zho'
|
204
|
+
when 'cze'
|
205
|
+
track_info[:language] = 'ces'
|
206
|
+
when 'dut'
|
207
|
+
track_info[:language] = 'nld'
|
208
|
+
when 'fre'
|
209
|
+
track_info[:language] = 'fra'
|
210
|
+
when 'geo'
|
211
|
+
track_info[:language] = 'kat'
|
212
|
+
when 'ger'
|
213
|
+
track_info[:language] = 'deu'
|
214
|
+
when 'gre'
|
215
|
+
track_info[:language] = 'ell'
|
216
|
+
when 'ice'
|
217
|
+
track_info[:language] = 'isl'
|
218
|
+
when 'mac'
|
219
|
+
track_info[:language] = 'mkd'
|
220
|
+
when 'mao'
|
221
|
+
track_info[:language] = 'mri'
|
222
|
+
when 'per'
|
223
|
+
track_info[:language] = 'fas'
|
224
|
+
when 'rum'
|
225
|
+
track_info[:language] = 'ron'
|
226
|
+
when 'slo'
|
227
|
+
track_info[:language] = 'slk'
|
228
|
+
when 'tib'
|
229
|
+
track_info[:language] = 'bod'
|
230
|
+
when 'wel'
|
231
|
+
track_info[:language] = 'cym'
|
232
|
+
else
|
233
|
+
track_info[:language] = language
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
184
237
|
if attributes =~ /\(default\)/
|
185
238
|
track_info[:default] = true
|
186
239
|
else
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: video_transcoding
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.18.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Don Melton
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-12-03 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: |2
|
14
14
|
Video Transcoding is a package of tools to transcode, inspect
|
@@ -64,7 +64,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
64
64
|
version: '0'
|
65
65
|
requirements: []
|
66
66
|
rubyforge_project:
|
67
|
-
rubygems_version: 2.6.
|
67
|
+
rubygems_version: 2.6.14
|
68
68
|
signing_key:
|
69
69
|
specification_version: 4
|
70
70
|
summary: Tools to transcode, inspect and convert videos.
|