video_transcoding 0.19.0 → 0.20.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 +58 -7
- data/bin/query-handbrake-log +1 -1
- data/bin/transcode-video +10 -14
- data/lib/video_transcoding/handbrake.rb +6 -69
- data/lib/video_transcoding/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 695200c196efef71d738e5db7027d7b767751dfa09dc9c1033a35873ff19f9bb
|
4
|
+
data.tar.gz: 1eeddcc6b991a23c5e8d78843655862b2ca5774ff90c94cf7726cf23b39b46ff
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 35882e7a8f9384633941b8a93b084cc09b1d3b0f4c140aa4cac4fc0cdb88737426461c058eb84c34719c680a0b0b99d60559404de13686a5f9225da429cd9255
|
7
|
+
data.tar.gz: 62f40bdecf719ce99d60a3f885be636a2b1af800e862782069c96d806a7d7da3f6af447cea54e40817d9e53393fc9955e542b866c20f39f40e83d59f0e4a2944
|
data/README.md
CHANGED
@@ -6,7 +6,7 @@ Tools to transcode, inspect and convert videos.
|
|
6
6
|
|
7
7
|
Hi, I'm [Don Melton](http://donmelton.com/). I created these tools to transcode my collection of Blu-ray Discs and DVDs into a smaller, more portable format while remaining high enough quality to be mistaken for the originals.
|
8
8
|
|
9
|
-
What makes these tools unique
|
9
|
+
What makes these tools unique are the [two ratecontrol systems](#explanation) which achieve those goals.
|
10
10
|
|
11
11
|
This package is based on my original collection of [Video Transcoding Scripts](https://github.com/donmelton/video-transcoding-scripts) written in Bash. While still available online, those scripts are no longer in active development. Users are encouraged to install this Ruby Gem instead.
|
12
12
|
|
@@ -274,6 +274,8 @@ Or use this command to make main audio output as a single track but still allow
|
|
274
274
|
|
275
275
|
transcode-video --audio-width main=surround "/path/to/Movie.mkv"
|
276
276
|
|
277
|
+
Please note that tracks transcoded to stereo AAC format, including the main track, are output in matrix-encoded [Dolby Pro Logic II](https://en.wikipedia.org/wiki/Dolby_Pro_Logic) surround format when the original input is multi-channel surround sound. This means that even though the AAC stereo track contains only two discrete channels, it can be decoded as multiple channels. So Dolby Digital AC-3 format is not actually required for surround sound output.
|
278
|
+
|
277
279
|
If possible, audio is first passed through in its original format, providing that format is either AC-3 or AAC. This hardly ever works for Blu-ray Discs but it often will for DVDs and other random videos.
|
278
280
|
|
279
281
|
However, you can still copy audio tracks and maintain their original format, provided HandBrake and your selected file format support it:
|
@@ -557,6 +559,22 @@ These examples are written in Bash and only supply crop values. But almost any s
|
|
557
559
|
|
558
560
|
## Explanation
|
559
561
|
|
562
|
+
### A tale of two ratecontrol systems
|
563
|
+
|
564
|
+
What is a ratecontrol sytem? It's how a video encoder decides on the amount of bits to allocate for a specific frame.
|
565
|
+
|
566
|
+
My `transcode-video` tool has two different ratecontrol systems available to control the size and quality of output video. The special, or default, ratecontrol system is designed to deliver consistent quality, while the average bitrate (ABR) ratecontrol system, enabled via the `--abr` option, is designed to produce a predictable output size.
|
567
|
+
|
568
|
+
Both ratecontrol systems are modified versions of what is commonly called a constrained variable bitrate (CVBR) mode. Which means they both allow bitrate to vary per frame but still constrain that bitrate.
|
569
|
+
|
570
|
+
My special ratecontrol system leverages the constant quality ratecontrol system already within the x264 video encoder, an algorithm which uses a constant ratefactor (CRF) to target a specific quality instead of a bitrate.
|
571
|
+
|
572
|
+
My average bitrate (ABR) ratecontrol system modifies the ABR algorithm already within x264 which targets a specific bitrate, constraining it to produce better overall quality.
|
573
|
+
|
574
|
+
The target video bitrate for both systems 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.
|
575
|
+
|
576
|
+
While both systems deliver high quality, they sometimes have different visual characteristics.
|
577
|
+
|
560
578
|
### How my special ratecontrol system works
|
561
579
|
|
562
580
|
When using `transcode-video`, you might notice two lines in the console output containing something like this:
|
@@ -565,16 +583,13 @@ When using `transcode-video`, you might notice two lines in the console output c
|
|
565
583
|
options: vbv-maxrate=6000:vbv-bufsize=12000:crf-max=25:qpmax=34
|
566
584
|
|
567
585
|
quality: 1.00 (RF)
|
568
|
-
|
569
586
|
```
|
570
587
|
|
571
588
|
These are actually the settings used by my special ratecontrol system to configure the x264 video encoder within HandBrake.
|
572
589
|
|
573
|
-
|
590
|
+
This system attempts to produce the highest possible video quality near a target bitrate using a constant ratefactor (CRF) to specify quality. 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.
|
574
591
|
|
575
|
-
|
576
|
-
|
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`.
|
592
|
+
Unfortunately, the output bitrate is extremely unpredictable when using the x264's default 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
593
|
|
579
594
|
But such a strategy can result in output larger than its input or, worse, output too low in quality to be mistaken for that input.
|
580
595
|
|
@@ -598,7 +613,29 @@ There's a final change required for the VBV model. I need to set the VBV buffer
|
|
598
613
|
|
599
614
|
It's safe to set `vbv-bufsize` anywhere in the range from one half to twice that of `vbv-maxrate`. However, that larger `vbv-bufsize` value produces an output bitrate closest to, on average, that of the target. So, if `vbv-maxrate` is `6000` Kbps, then I set `vbv-bufsize` to `12000` Kbps.
|
600
615
|
|
601
|
-
|
616
|
+
### How my average bitrate (ABR) ratecontrol system works
|
617
|
+
|
618
|
+
When using `transcode-video` with the `--abr` option, you might notice two lines in the console output containing something like this:
|
619
|
+
|
620
|
+
```
|
621
|
+
options: vbv-maxrate=9000:vbv-bufsize=12000:nal-hrd=vbr
|
622
|
+
|
623
|
+
bitrate: 6000 kbps, pass: 0
|
624
|
+
```
|
625
|
+
|
626
|
+
This ABR ratecontrol system attempts to produce a predictable output size while still maintaining high quality by manipulating the video buffering verifier (VBV) model within the x264 video encoder.
|
627
|
+
|
628
|
+
As mentioned before, the VBV model typically allows bitrates to peak as high as `25000` Kbps during playback on most devices. But I constrain the VBV maximum bitrate (`vbv-maxrate`) to only 1.5 times that of the target, i.e. to just `9000` Kbps when the target bitrate is `6000` Kbps for 1080p output.
|
629
|
+
|
630
|
+
It seems counterintuitive, but constraining the maximum bitrate prevents too much bitrate being wasted on complex or difficult to encode passages at the expense of quality elsewhere. This is because with an average bitrate algorithm, when the peaks get too high then the valleys get too low.
|
631
|
+
|
632
|
+
As with the default ratecontrol system, I need to set the VBV buffer size (`vbv-bufsize`) so that my previous adjustment of `vbv-maxrate` won't be ignored by x264. So, if `vbv-maxrate` is `9000` Kbps, then I set `vbv-bufsize` to `12000` Kbps.
|
633
|
+
|
634
|
+
This VBV model manipulation is exactly the same strategy used by streaming services such as Netflix.
|
635
|
+
|
636
|
+
The final setting, `nal-hrd=vbr`, doesn't actually affect ratecontrol. This is a x264 option signaling Hypothetical Reference Decoder (HRD) information, meaning that it adds the VBV maximum bitrate value as metadata to the output video. Which is useful for certain streaming environments and media tools.
|
637
|
+
|
638
|
+
And this information is safe to include since my ABR ratecontrol implementation will, by design, never exceed the maximum bitrate. Which is something the default ratecontrol system cannot promise.
|
602
639
|
|
603
640
|
## FAQ
|
604
641
|
|
@@ -652,6 +689,20 @@ For a few problematic videos, I have to apply options like `--force-rate 23.976
|
|
652
689
|
|
653
690
|
## History
|
654
691
|
|
692
|
+
### [0.20.0](https://github.com/donmelton/video_transcoding/releases/tag/0.20.0)
|
693
|
+
|
694
|
+
Monday, June 18, 2018
|
695
|
+
|
696
|
+
* Now require `HandBrakeCLI` version 1.0.0 or later. Not only does this change make for easier testing, but it allows removal of many capability-detection hacks needed to support older versions. My thanks again to all the users who provided positive feedback about this online!
|
697
|
+
* Relax frame rate control in `transcode-video` so that the options `--rate=30` and `--pfr` are no longer passed to `HandBrakeCLI` for most non-DVD videos. This means that the peak frame rate will no longer be limited to `30` FPS, allowing camera-generated videos to retain their original frame rates. However, the old behavior can be restored for those videos by adding `--limit-rate 30` to your `transcode-video` command line.
|
698
|
+
* Modify `transcode-video` to no longer pass `--encoder-preset=medium` to `HandBrakeCLI` since that's the default behavior anyway. However, adding `--preset medium` to your `transcode-video` command line still does so.
|
699
|
+
* Modify `transcode-video` to no longer pass a named audio encoder to `HandBrakeCLI` in order to select AAC, i.e. `ca_aac` or `av_aac`, since AAC is the default audio format anyway. However, adding the `--aac-encoder` option to your `transcode-video` command line still allows an explicit choice.
|
700
|
+
* Modify `transcode-video` to substitute "analyse" for the x264 option called "partitions" when invoked with the `--quick` or `--veryquick` options. This is done to better match the archaic internal name used by HandBrake. It has no effect on actual transcoding behavior.
|
701
|
+
* Add `-n` as a shortcut alias for the `--dry-run` option in `transcode-video`. This is the same shortcut alias used in `rsync` and `make`.
|
702
|
+
* Expand the "Explanation" section of the "README" document to describe both the special, or default, ratecontrol system and the average bitrate (ABR) ratecontrol system, enabled via the `--abr` option.
|
703
|
+
* Add clarification to the "README" document that stereo AAC tracks can also include surround audio information in matrix-encoded Dolby Pro Logic II format.
|
704
|
+
* Fix spelling of "suppress" in the `--help` output of `query-handbrake-log`. Thanks, [@chrisridd](https://github.com/chrisridd)! Via [ #205](https://github.com/donmelton/video_transcoding/pull/205).
|
705
|
+
|
655
706
|
### [0.19.0](https://github.com/donmelton/video_transcoding/releases/tag/0.19.0)
|
656
707
|
|
657
708
|
Saturday, January 27, 2018
|
data/bin/query-handbrake-log
CHANGED
@@ -39,7 +39,7 @@ r, ratefactor average P-frame quantizer for transcoding
|
|
39
39
|
|
40
40
|
Options:
|
41
41
|
--reverse reverse direction of sort
|
42
|
-
--tabular use tab character as field delimiter and
|
42
|
+
--tabular use tab character as field delimiter and suppress labels
|
43
43
|
|
44
44
|
-v, --verbose increase diagnostic information
|
45
45
|
-q, --quiet decrease " "
|
data/bin/transcode-video
CHANGED
@@ -53,7 +53,7 @@ Output options:
|
|
53
53
|
import chapter names from `.csv` text file
|
54
54
|
(in NUMBER,NAME format, e.g. "1,Intro")
|
55
55
|
--no-log don't write log file
|
56
|
-
|
56
|
+
-n, --dry-run don't transcode, just show `HandBrakeCLI` command and exit
|
57
57
|
|
58
58
|
Quality options:
|
59
59
|
--abr use constrained average bitrate (ABR) ratecontrol
|
@@ -95,7 +95,6 @@ Video options:
|
|
95
95
|
(`23.976` applied automatically for some inputs)
|
96
96
|
--limit-rate FPS
|
97
97
|
set peak-limited video frame rate
|
98
|
-
(`30` applied automatically for most inputs)
|
99
98
|
--filter NAME[=SETTINGS]
|
100
99
|
apply `HandBrakeCLI` video filter with optional settings
|
101
100
|
(`deinterlace` applied automatically for some inputs)
|
@@ -316,7 +315,7 @@ HERE
|
|
316
315
|
end
|
317
316
|
|
318
317
|
opts.on('--no-log') { @log = false }
|
319
|
-
opts.on('--dry-run')
|
318
|
+
opts.on('-n', '--dry-run') { @dry_run = true }
|
320
319
|
|
321
320
|
opts.on '--abr' do
|
322
321
|
@use_abr = true
|
@@ -876,13 +875,13 @@ HERE
|
|
876
875
|
height = adjusted_height
|
877
876
|
end
|
878
877
|
else
|
879
|
-
anamorphic =
|
878
|
+
anamorphic = 'auto-anamorphic'
|
880
879
|
end
|
881
880
|
|
882
881
|
handbrake_options[anamorphic] = nil unless @handbrake_options.has_key? 'custom-anamorphic'
|
883
882
|
|
884
883
|
unless @handbrake_options.has_key? 'rate'
|
885
|
-
rate =
|
884
|
+
rate = nil
|
886
885
|
fps = media.info[:fps]
|
887
886
|
|
888
887
|
if fps == 29.97
|
@@ -902,18 +901,14 @@ HERE
|
|
902
901
|
end
|
903
902
|
end
|
904
903
|
|
905
|
-
|
906
|
-
|
907
|
-
if rate == '30'
|
908
|
-
handbrake_options['pfr'] = nil
|
909
|
-
else
|
904
|
+
unless rate.nil?
|
905
|
+
handbrake_options['rate'] = rate
|
910
906
|
handbrake_options['cfr'] = nil
|
911
907
|
end
|
912
908
|
end
|
913
909
|
|
914
910
|
encoder = @handbrake_options.fetch('encoder', 'x264')
|
915
911
|
return unless encoder =~ /^x264(?:_10bit)?$/ or encoder =~ /^x265(?:_1[026]bit)?$/
|
916
|
-
handbrake_options['encoder-preset'] = 'medium'
|
917
912
|
|
918
913
|
if width > 1920 or height > 1080
|
919
914
|
encoder_level = '5.1'
|
@@ -979,7 +974,7 @@ HERE
|
|
979
974
|
if (@quick or @veryquick) and
|
980
975
|
@handbrake_options.fetch('encoder-preset', 'medium') == 'medium' and
|
981
976
|
encoder =~ /^x264(?:_10bit)?$/
|
982
|
-
encoder_options['
|
977
|
+
encoder_options['analyse'] = 'none'
|
983
978
|
encoder_options['ref'] = '1'
|
984
979
|
encoder_options['bframes'] = '1' if @veryquick
|
985
980
|
encoder_options['rc-lookahead'] = '30'
|
@@ -1071,7 +1066,7 @@ HERE
|
|
1071
1066
|
if copy or (info[:format] == 'AAC' and info[:channels] <= 2.0)
|
1072
1067
|
encoders << 'copy'
|
1073
1068
|
else
|
1074
|
-
@aac_encoder ||=
|
1069
|
+
@aac_encoder ||= ''
|
1075
1070
|
encoders << @aac_encoder
|
1076
1071
|
end
|
1077
1072
|
|
@@ -1127,7 +1122,8 @@ HERE
|
|
1127
1122
|
end
|
1128
1123
|
|
1129
1124
|
handbrake_options['audio'] = tracks.join(',')
|
1130
|
-
|
1125
|
+
encoders = encoders.join(',')
|
1126
|
+
handbrake_options['aencoder'] = encoders if encoders.gsub(/,/, '') != ''
|
1131
1127
|
handbrake_options['audio-fallback'] = @ac3_encoder unless @copy_audio.empty?
|
1132
1128
|
bitrates = bitrates.join(',')
|
1133
1129
|
handbrake_options['ab'] = bitrates if bitrates.gsub(/,/, '') != ''
|
@@ -11,83 +11,20 @@ module VideoTranscoding
|
|
11
11
|
COMMAND_NAME = 'HandBrakeCLI'
|
12
12
|
|
13
13
|
def setup
|
14
|
-
Tool.provide(COMMAND_NAME, ['--
|
15
|
-
fail "#{COMMAND_NAME}
|
14
|
+
Tool.provide(COMMAND_NAME, ['--version']) do |output, status, _|
|
15
|
+
fail "#{COMMAND_NAME} version 1.0.0 or later required" unless status == 0
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
unless (version =~ /^([0-9]+)\.([0-9]+)/ and (($1.to_i * 100) + $2.to_i) >= 10) or
|
22
|
-
(version =~ /^svn([0-9]+)/ and $1.to_i >= 6536)
|
23
|
-
fail "#{COMMAND_NAME} version 0.10.0 or later required"
|
24
|
-
end
|
17
|
+
unless output =~ /^HandBrake ([^h][^ ]+)/
|
18
|
+
Console.debug output
|
19
|
+
fail "#{COMMAND_NAME} version unknown"
|
25
20
|
end
|
26
|
-
end
|
27
21
|
|
28
|
-
|
29
|
-
IO.popen([Tool.use(COMMAND_NAME), '--version'], :err=>[:child, :out]) do |io|
|
30
|
-
if io.read =~ /^HandBrake ([^h][^ ]+)/
|
31
|
-
Console.info "#{$MATCH.strip} found..."
|
32
|
-
end
|
33
|
-
end
|
34
|
-
rescue SystemCallError => e
|
35
|
-
raise "#{COMMAND_NAME} failed during execution: #{e}"
|
22
|
+
Console.info "#{$MATCH.strip} found..."
|
36
23
|
end
|
37
24
|
end
|
38
25
|
|
39
26
|
def command_name
|
40
27
|
Tool.use(COMMAND_NAME)
|
41
28
|
end
|
42
|
-
|
43
|
-
def auto_anamorphic
|
44
|
-
properties = Tool.properties(COMMAND_NAME)
|
45
|
-
|
46
|
-
unless properties.has_key? :auto_anamorphic
|
47
|
-
if help_text =~ /auto-anamorphic/
|
48
|
-
properties[:auto_anamorphic] = 'auto-anamorphic'
|
49
|
-
else
|
50
|
-
properties[:auto_anamorphic] = 'strict-anamorphic'
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
properties[:auto_anamorphic]
|
55
|
-
end
|
56
|
-
|
57
|
-
def aac_encoder
|
58
|
-
properties = Tool.properties(COMMAND_NAME)
|
59
|
-
|
60
|
-
unless properties.has_key? :aac_encoder
|
61
|
-
if help_text =~ /ca_aac/
|
62
|
-
properties[:aac_encoder] = 'ca_aac'
|
63
|
-
else
|
64
|
-
properties[:aac_encoder] = 'av_aac'
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
properties[:aac_encoder]
|
69
|
-
end
|
70
|
-
|
71
|
-
private
|
72
|
-
|
73
|
-
def help_text
|
74
|
-
properties = Tool.properties(COMMAND_NAME)
|
75
|
-
|
76
|
-
unless properties.has_key? :help_text
|
77
|
-
properties[:help_text] = ''
|
78
|
-
|
79
|
-
begin
|
80
|
-
IO.popen([Tool.use(COMMAND_NAME), '--help'], :err=>[:child, :out]) do |io|
|
81
|
-
properties[:help_text] = io.read
|
82
|
-
end
|
83
|
-
rescue SystemCallError => e
|
84
|
-
raise "#{COMMAND_NAME} help text unavailable: #{e}"
|
85
|
-
end
|
86
|
-
|
87
|
-
fail "#{COMMAND_NAME} failed during execution" unless $CHILD_STATUS.exitstatus == 0
|
88
|
-
end
|
89
|
-
|
90
|
-
properties[:help_text]
|
91
|
-
end
|
92
29
|
end
|
93
30
|
end
|
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.20.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: 2018-
|
11
|
+
date: 2018-06-19 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.7.
|
67
|
+
rubygems_version: 2.7.6
|
68
68
|
signing_key:
|
69
69
|
specification_version: 4
|
70
70
|
summary: Tools to transcode, inspect and convert videos.
|