-
-
Save rdela/0506661064a8efbd4769 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# | |
# transcode-video.sh | |
# | |
# Copyright (c) 2013-2014 Don Melton | |
# | |
# This script uses `HandBrakeCLI` (see: <http://handbrake.fr/>) to transcode a | |
# video file or disc image directory into a format and size similar to videos | |
# available for download from the iTunes Store. | |
# | |
# While working best with a Blu-ray Disc or DVD ripped to a single video file | |
# or complete disc image directory, this script will also accept other video | |
# files as input. | |
# | |
# The goal of this script is NOT to make an exact pixel-for-pixel, | |
# wave-for-wave copy of the input. That's not practical. Instead, the goal is | |
# to create a portable version of that input as quickly as possible at a | |
# reasonable quality --- something that can be enjoyed without prejudice on | |
# both a small tablet computer and a large, wide-screen home entertainment | |
# system with 5.1 surround sound. | |
# | |
# Also, it should be possible for the output of this script to be served by | |
# media management systems like Plex (see: <http://www.plexapp.com/>) without | |
# further dynamic transcoding. In other words, transcode a video file with | |
# this script and never have to explicitly or implicitly transcode it again. | |
# | |
# Some of this script's various behaviors can be changed or disabled via | |
# command line options. Try: | |
# | |
# transcode-video.sh --help | |
# | |
# ...for more information. | |
# | |
# However, this script will automatically determine the optimal video bitrate, | |
# number of audio tracks, etc. WITHOUT ANY command line options. For example: | |
# | |
# transcode-video.sh "/path/to/Movie file.mkv" | |
# | |
# ...or: | |
# | |
# transcode-video.sh "/path/to/Movie disc image directory/" | |
# | |
# ...will usually produce the expected output. | |
# | |
# By default, this script will try to create an MP4 format file with dual | |
# audio tracks (like iTunes video), but it can also output Matroska format | |
# (i.e. MKV). | |
# | |
# For MP4 output, audio input is first transcoded into Advanced Audio Coding | |
# (AAC) format. A second audio track in Dolby Digital (AC-3) format is added | |
# if that audio input is multi-channel, i.e. surround sound. | |
# | |
# MKV output is handled like MP4, but any AC-3 format track is placed first. | |
# | |
# Multi-channel audio input is transcoded into AC-3 format at 384 kbps, and | |
# stereo or mono audio input into AAC format at 160 or 80 kbps. | |
# | |
# Any existing AAC stereo or mono audio input is passed through without | |
# transcoding. | |
# | |
# By default, any existing multi-channel AC-3 audio input is passed through | |
# without transcoding if it's at or below 448 kbps. All other multi-channel | |
# audio input is transcoded at 384 kbps. Both of these bitrate limits can be | |
# adjusted at the command line. | |
# | |
# The user can even completely disable multi-channel AC-3 audio output. | |
# | |
# The first audio track from the input is selected, by default, for | |
# transcoding. However, this script allows the user to choose a different | |
# audio track if one is available. | |
# | |
# All video is transcoded into H.264 format. By default, this script uses a | |
# constant rate factor (CRF) mode, which can sometimes output a larger bitrate | |
# than its input. | |
# | |
# To produce output at a much more predictable size, this script uses the | |
# `x264` video buffer verifier (VBV) system to limit the video bitrate. | |
# | |
# For Blu-ray Disc input, this script will produce output at a size much like | |
# 1080p iTunes video. | |
# | |
# This script also allows the user to explicitly choose a maximum video | |
# bitrate as well as a specific constant rate factor for that video. | |
# | |
# If faster transcoding time or a smaller output file size is desired for | |
# Blu-ray Disc and other 1080p video input, this script can scale that input | |
# to fit within a 1280x720 pixel bounds, much like 720p iTunes video. | |
# | |
# By default this script uses the `x264` "fast" preset to transcode all video. | |
# This is done to achieve both the performance AND quality goals. Transcoding | |
# with the "fast" preset still results in high-quality output. | |
# | |
# However, if even higher quality video is desired, access to both the | |
# "medium" and "slow" `x264` presets are available. Please note that using | |
# these other presets does NOT guarantee higher-quality output. | |
# | |
# When an input frame rate of 29.97 fps is detected, by default, this script | |
# will automatically apply a "detelecine" filter to that input and force an | |
# output frame rate of 23.976 fps. However, the user can disable this | |
# automatic behavior. For disc image directory input, this behavior is always | |
# disabled since the "real" frame rate can't be detected reliably there. | |
# | |
# The user can also explicitly force output at 23.976 fps or even a different | |
# frame rate, as well as separately apply the "detelecine" filter. | |
# | |
# For input with Blu-ray- or DVD-compatible subtitles (PGS or VobSub formats), | |
# this script will automatically burn into the video the first subtitle that | |
# has its forced flag set. | |
# | |
# However, this script allows the user to choose a different subtitle track | |
# with which to burn into the video, as well as explicitly disabling just the | |
# automatic behavior. | |
# | |
# Please note that the automatic subtitle burning behavior is always disabled | |
# for disc image directory input since the forced flag can't be detected there. | |
# | |
# For other subtitle manipulation, it's best to use another program on this | |
# script's output after transcoding is complete. | |
# | |
# This script does NOT facilitate the automatic cropping behavior of | |
# `HandBrakeCLI` due to reliability problems with that feature. Instead, | |
# cropping bounds must be passed explicitly at the command line. Use the | |
# `detect-crop.sh` script to aid in determining these parameters. | |
# | |
# WARNING: This script is designed to work on OS X. There's no guarantee it | |
# will work on a different operating system. | |
# | |
about() { | |
cat <<EOF | |
$program 3.1 of June 27, 2014 | |
Copyright (c) 2013-2014 Don Melton | |
EOF | |
exit 0 | |
} | |
usage() { | |
cat <<EOF | |
Transcode video file or disc image directory into MP4 (or optionally Matroska) | |
format, with configuration and at bitrate similar to popluar online downloads. | |
Works best with Blu-ray or DVD rip. | |
Usage: $program [OPTION]... [FILE|DIRECTORY] | |
--title NUMBER select numbered title in video media (default: 1) | |
(\`0\` to scan media, list title numbers and exit) | |
--chapters STRING select chapters, single or range (default: all) | |
--mkv output Matroska format | |
--preset NAME use x264 fast|medium|slow preset (default: fast) | |
--max BITRATE set maximum video bitrate (default: based on input) | |
--crf FACTOR set constant rate factor (default: 18) | |
--resize resize video to fit within 1280x720 pixel bounds | |
--rate FPS force video frame rate (default: based on input) | |
--audio TRACK select audio track identified by number (default: 1) | |
--ac3 BITRATE set AC-3 audio bitrate to 384|448|640 kbps | |
(default: 384) | |
--pass-ac3 BITRATE passthru AC-3 audio <= 384|448|640 kbps | |
(default: 448) | |
--no-ac3 don't output multi-channel AC-3 audio | |
--crop T:B:L:R set video croping bounds (default: 0:0:0:0) | |
--detelecine apply detelecine filter to video | |
(always use alongside \`--rate\` option) | |
--no-auto-detelecine don't automatically apply detelecine filter | |
to \`29.97\` fps video | |
--burn TRACK burn subtitle track identified by number | |
(default: first "forced" subtitle, if any) | |
--no-auto-burn don't automatically burn first "forced" subtitle | |
--help display this help and exit | |
--version output version information and exit | |
Requires \`HandBrakeCLI\` executable in \$PATH. | |
Output and log file are written to current working directory. | |
EOF | |
exit 0 | |
} | |
syntax_error() { | |
echo "$program: $1" >&2 | |
echo "Try \`$program --help\` for more information." >&2 | |
exit 1 | |
} | |
die() { | |
echo "$program: $1" >&2 | |
exit ${2:-1} | |
} | |
readonly program="$(basename "$0")" | |
case $1 in | |
--help) | |
usage | |
;; | |
--version) | |
about | |
;; | |
esac | |
debug='' | |
title='1' | |
chapters_options='' | |
container_format='mp4' | |
container_format_options='--large-file' | |
preset_options='--x264-preset fast' | |
max_bitrate='' | |
rate_factor='18' | |
resize='' | |
frame_rate_options='' | |
audio_track='1' | |
ac3_bitrate='384' | |
pass_ac3_bitrate='448' | |
crop='0:0:0:0' | |
filter_options='' | |
auto_detelecine='yes' | |
subtitle_track='' | |
auto_burn='yes' | |
limit_reference_frames='' | |
optimize='' | |
while [ "$1" ]; do | |
case $1 in | |
--debug) | |
debug='yes' | |
;; | |
--title) | |
title="$(printf '%.0f' "$2")" | |
shift | |
if (($title < 0)); then | |
die "invalid title number: $title" | |
fi | |
;; | |
--chapters) | |
chapters_options="--chapters $2" | |
shift | |
;; | |
--mkv) | |
container_format='mkv' | |
container_format_options='' | |
;; | |
--preset) | |
preset="$2" | |
shift | |
case $preset in | |
fast|slow) | |
preset_options="--x264-preset $preset" | |
;; | |
medium) | |
preset_options='' | |
;; | |
*) | |
syntax_error "unsupported preset: $preset" | |
;; | |
esac | |
;; | |
--max|--abr) | |
if [ "$1" == '--abr' ]; then | |
echo "$program: deprecated option: $1" >&2 | |
echo "$program: use this option instead: --max" >&2 | |
fi | |
max_bitrate="$(printf '%.0f' "$2")" | |
shift | |
if (($max_bitrate < 1)); then | |
die "invalid maximum video bitrate: $max_bitrate" | |
fi | |
;; | |
--crf) | |
rate_factor="$(printf '%.2f' "$2" | sed 's/0*$//;s/\.$//')" | |
shift | |
if (($rate_factor < 0)); then | |
die "invalid constant rate factor: $rate_factor" | |
fi | |
;; | |
--resize) | |
resize='yes' | |
;; | |
--rate) | |
frame_rate_options="--rate $(printf '%.3f' "$2" | sed 's/0*$//;s/\.$//')" | |
shift | |
;; | |
--audio) | |
audio_track="$(printf '%.0f' "$2")" | |
shift | |
if (($audio_track < 1)); then | |
die "invalid audio track: $audio_track" | |
fi | |
;; | |
--ac3) | |
ac3_bitrate="$2" | |
shift | |
case $ac3_bitrate in | |
384|448|640) | |
;; | |
*) | |
syntax_error "unsupported AC-3 audio bitrate: $ac3_bitrate" | |
;; | |
esac | |
;; | |
--pass-ac3) | |
pass_ac3_bitrate="$2" | |
shift | |
case $pass_ac3_bitrate in | |
384|448|640) | |
;; | |
*) | |
syntax_error "unsupported AC-3 audio passthru bitrate: $pass_ac3_bitrate" | |
;; | |
esac | |
;; | |
--no-ac3|--no-surround) | |
if [ "$1" == '--no-surround' ]; then | |
echo "$program: deprecated option: $1" >&2 | |
echo "$program: use this option instead: --no-ac3" >&2 | |
fi | |
ac3_bitrate='' | |
;; | |
--crop) | |
crop="$2" | |
shift | |
;; | |
--detelecine) | |
filter_options='--detelecine' | |
auto_detelecine='' | |
;; | |
--no-auto-detelecine) | |
auto_detelecine='' | |
;; | |
--burn) | |
subtitle_track="$(printf '%.0f' "$2")" | |
shift | |
if (($subtitle_track < 1)); then | |
die "invalid subtitle track: $subtitle_track" | |
fi | |
auto_burn='' | |
;; | |
--no-auto-burn) | |
auto_burn='' | |
;; | |
--limit-reference-frames) | |
echo "$program: deprecated option: $1" >&2 | |
limit_reference_frames='yes' | |
;; | |
--optimize) | |
echo "$program: deprecated option: $1" >&2 | |
optimize='yes' | |
;; | |
-*) | |
syntax_error "unrecognized option: $1" | |
;; | |
*) | |
break | |
;; | |
esac | |
shift | |
done | |
readonly input="$1" | |
if [ ! "$input" ]; then | |
syntax_error 'too few arguments' | |
fi | |
if [ ! -e "$input" ]; then | |
die "input not found: $input" | |
fi | |
if ! $(which HandBrakeCLI >/dev/null); then | |
die 'executable not in $PATH: HandBrakeCLI' | |
fi | |
title_options="--title $title" | |
if [ "$title" == '0' ]; then | |
echo "Scanning: $input" >&2 | |
fi | |
# Leverage `HandBrakeCLI` scan mode to extract all file- or directory-based | |
# media information. Significantly speed up scan with `--previews 2:0` option | |
# and argument. | |
# | |
readonly media_info="$(HandBrakeCLI $title_options --scan --previews 2:0 --input "$input" 2>&1)" | |
if [ "$debug" ]; then | |
echo "$media_info" >&2 | |
fi | |
if [ "$title" == '0' ]; then | |
# Extract and reformat summary from media information for title listing. | |
# | |
readonly formatted_titles_info="$(echo "$media_info" | | |
sed -n '/^+ title /,$p' | | |
sed '/^ + autocrop: /d;/^ + support /d;/^HandBrake/,$d;s/\(^ *\)+ \(.*$\)/\1\2/')" | |
if [ ! "$formatted_titles_info" ]; then | |
die "no media title available in: $input" | |
fi | |
echo "$formatted_titles_info" | |
exit | |
elif [ "$title" == '1' ]; then | |
title_options='' | |
fi | |
if [ ! "$(echo "$media_info" | sed -n '/^+ title /,$p')" ]; then | |
echo "$program: \`title $title\` not found in: $input" >&2 | |
echo "Try \`$program --title 0 [FILE|DIRECTORY]\` to scan for titles." >&2 | |
echo "Try \`$program --help\` for more information." >&2 | |
exit 1 | |
fi | |
readonly output="$(basename "$input" | sed 's/\.[^.]\{1,\}$//').$container_format" | |
if [ -e "$output" ]; then | |
die "output file already exists: $output" | |
fi | |
readonly size_array=($(echo "$media_info" | sed -n 's/^ + size: \([0-9]\{1,\}\)x\([0-9]\{1,\}\).*$/\1 \2/p')) | |
if ((${#size_array[*]} != 2)); then | |
die "no video size information in: $input" | |
fi | |
readonly width="${size_array[0]}" | |
readonly height="${size_array[1]}" | |
# Limit `x264` video buffer verifier (VBV) size to values appropriate for | |
# H.264 level with High profile: | |
# | |
# 25000 for level 4.0 (e.g. Blu-ray input) | |
# 17500 for level 3.1 (e.g. 720p input) | |
# 12500 for level 3.0 (e.g. DVD input) | |
# | |
reference_frames_option='' | |
level_option='' | |
size_options='--strict-anamorphic' | |
if (($width > 1280)) || (($height > 720)); then | |
if [ ! "$resize" ]; then | |
vbv_maxrate='5000' | |
max_bufsize='25000' | |
if [ "$preset" == 'slow' ]; then | |
if [ "$limit_reference_frames" ]; then | |
# Maintain compatibility with H.264 level 4.0. | |
# | |
reference_frames_option='ref=4:' | |
else | |
# Force H.264 level to 4.0 when using 5 reference frames. | |
# Which causes HandBrakeCLI to emit this message: | |
# | |
# x264 [warning]: DPB size (5 frames, 39000 mbs) > level limit (4 frames, 32768 mbs) | |
# | |
# ...but it can be ignored since the VBV maximum rate is | |
# usually low. | |
# | |
level_option=':level=4' | |
fi | |
fi | |
else | |
vbv_maxrate='4000' | |
max_bufsize='17500' | |
size_options='--maxWidth 1280 --maxHeight 720 --loose-anamorphic' | |
fi | |
elif (($width > 720)) || (($height > 576)); then | |
vbv_maxrate='4000' | |
max_bufsize='17500' | |
else | |
vbv_maxrate='2000' | |
max_bufsize='12500' | |
fi | |
if [ "$max_bitrate" ]; then | |
if (($max_bitrate > vbv_maxrate)); then | |
vbv_maxrate="$max_bitrate" | |
fi | |
elif [ -f "$input" ]; then | |
readonly duration_array=($(echo "$media_info" | | |
sed -n 's/^ + duration: \([0-9][0-9]\):\([0-9][0-9]\):\([0-9][0-9]\)$/ \1 \2 \3 /p' | | |
sed 's/ 0/ /g')) | |
if ((${#duration_array[*]} == 3)); then | |
# Calculate total bitrate from file size in bits divided by video | |
# duration in seconds. | |
# | |
bitrate="$((($(stat -L -f %z "$input") * 8) / ((duration_array[0] * 60 * 60) + (duration_array[1] * 60) + duration_array[2])))" | |
if [ "$bitrate" ]; then | |
# Convert to kbps and round to nearest thousand. | |
# | |
bitrate="$((((bitrate / 1000) / 1000) * 1000))" | |
if (($bitrate < $vbv_maxrate)); then | |
readonly min_bitrate="$((vbv_maxrate / 2))" | |
if (($bitrate < $min_bitrate)); then | |
vbv_maxrate="$min_bitrate" | |
else | |
vbv_maxrate="$bitrate" | |
fi | |
fi | |
fi | |
fi | |
fi | |
# The `x264` video buffer verifier (VBV) size must always be less than the | |
# maximum rate to maintain quality in constant rate factor (CRF) mode. | |
# | |
vbv_bufsize="$((vbv_maxrate / 2))" | |
if (($vbv_bufsize > $max_bufsize)); then | |
vbv_bufsize="$max_bufsize" | |
vbv_maxrate="$((vbv_bufsize * 2))" | |
fi | |
# First extract frame rate from media information summary. If that frame rate | |
# is `23.976` then it's possible "real" frame rate is `29.97`. For file input, | |
# re-extract frame rate from stream information if available. | |
# | |
frame_rate="$(echo "$media_info" | sed -n 's/^ + size: .*, \([0-9]\{1,\}\.[.0-9]\{1,\}\) fps$/\1/p')" | |
if [ "$frame_rate" == '23.976' ] && [ -f "$input" ]; then | |
readonly video_track_info="$(echo "$media_info" | | |
sed -n '/^ Stream #[^:]\{1,\}: Video: /p' | | |
sed -n 1p)" | |
if [ "$video_track_info" ]; then | |
readonly raw_frame_rate="$(echo "$video_track_info" | sed -n 's/^.*, \([0-9.]\{1,\}\) fps, .*$/\1/p')" | |
if [ "$raw_frame_rate" ]; then | |
frame_rate="$raw_frame_rate" | |
fi | |
fi | |
fi | |
if [ ! "$frame_rate" ]; then | |
die "no video frame rate information in: $input" | |
fi | |
# Allow user to explicitly choose output frame rate. If none is chosen and | |
# input frame rate is `29.97` then force output frame rate of `23.976`. | |
# Otherwise set peak frame rate to `30` so HandBrakeCLI` can dynamically | |
# determine output frame rate. | |
# | |
if [ ! "$frame_rate_options" ]; then | |
if [ "$auto_detelecine" ] && [[ "$frame_rate" =~ '29.97' ]]; then | |
frame_rate_options='--rate 23.976' | |
else | |
frame_rate_options='--rate 30 --pfr' | |
fi | |
fi | |
readonly all_audio_tracks_info="$(echo "$media_info" | | |
sed -n '/^ + audio tracks:$/,/^ + subtitle tracks:$/p' | | |
sed -n '/^ + /p')" | |
if [ ! "$all_audio_tracks_info" ]; then | |
die "no audio track information in: $input" | |
fi | |
readonly audio_track_info="$(echo "$all_audio_tracks_info" | sed -n ${audio_track}p)" | |
if [ ! "$audio_track_info" ]; then | |
die "\`audio $audio_track\` track not found in: $input" | |
fi | |
audio_track_channels="$(echo "$audio_track_info" | | |
sed -n 's/^[^(]\{1,\} ([^(]\{1,\}) (\([^(]\{1,\}\)) .*$/\1/p' | | |
sed 's/ ch$//')" | |
case $audio_track_channels in | |
'Dolby Surround') | |
audio_track_channels='2' | |
;; | |
[0-9]*) | |
high_channels="$(echo "$audio_track_channels" | sed 's/\.[0-9]\{1,\}$//')" | |
low_channels="$(echo "$audio_track_channels" | sed 's/^[0-9]\{1,\}\.//')" | |
if [ "$high_channels" ] && [ "$low_channels" ]; then | |
audio_track_channels="$((high_channels + low_channels))" | |
fi | |
;; | |
*) | |
die "bad audio channel information in: $input" | |
;; | |
esac | |
if [ ! "$audio_track_channels" ]; then | |
die "no audio channel information in: $input" | |
fi | |
# For MP4 output, transcode audio input first into Advanced Audio Coding (AAC) | |
# format. Add second audio track in Dolby Digital (AC-3) format if audio input | |
# is multi-channel. | |
# | |
# Handle MKV output like MP4, but place any AC-3 format track first. | |
# | |
# Transcode stereo or mono audio using `HandBrakeCLI` default behavior, at 160 | |
# or 80 kbps in AAC format. Use existing audio if already in that format. | |
# | |
# Transcode multi-channel audio input at 384 kbps in AC-3 format. Use existing | |
# audio if already in that format and at or below 448 kbps. Allow user to | |
# disable AC-3 format output, change bitrate, or allow larger input bitrate to | |
# pass through without transcoding. | |
# | |
if [ "$ac3_bitrate" ] && (($audio_track_channels > 2)); then | |
readonly help="$(HandBrakeCLI --help 2>/dev/null)" | |
if $(echo "$help" | grep -q ca_aac); then | |
aac_encoder='ca_aac' | |
else | |
aac_encoder='faac' | |
fi | |
if $(echo "$help" | grep -q ffac3); then | |
ac3_encoder='ffac3' | |
else | |
ac3_encoder='ac3' | |
fi | |
readonly audio_track_bitrate="$(echo "$audio_track_info" | sed -n 's/^.* \([0-9]\{1,\}\)bps$/\1/p')" | |
if (($pass_ac3_bitrate < $ac3_bitrate)); then | |
pass_ac3_bitrate="$ac3_bitrate" | |
fi | |
if [[ "$audio_track_info" =~ '(AC3)' ]] && ((($audio_track_bitrate / 1000) <= $pass_ac3_bitrate)); then | |
if [ "$container_format" == 'mp4' ]; then | |
audio_options='--aencoder $aac_encoder,copy:ac3' | |
else | |
audio_options='--aencoder copy:ac3,$aac_encoder' | |
fi | |
elif [ "$container_format" == 'mp4' ]; then | |
audio_options="--aencoder $aac_encoder,$ac3_encoder --ab ,$ac3_bitrate" | |
else | |
audio_options="--aencoder $ac3_encoder,$aac_encoder --ab $ac3_bitrate," | |
fi | |
elif [[ "$audio_track_info" =~ '(aac)' ]]; then | |
audio_options='--aencoder copy:aac' | |
else | |
audio_options='' | |
fi | |
if (($audio_track > 1)); then | |
audio_options="--audio $audio_track $audio_options" | |
fi | |
if [ "$auto_detelecine" ] && [[ "$frame_rate" =~ '29.97' ]]; then | |
filter_options='--detelecine' | |
fi | |
readonly all_subtitle_tracks_info="$(echo "$media_info" | | |
sed -n '/^ + subtitle tracks:$/,$p' | | |
sed -n '/^ + /p')" | |
if [ "$subtitle_track" ] && [ ! "$all_subtitle_tracks_info" ]; then | |
die "no subtitle track information in: $input" | |
fi | |
# For file input, automatically find first "forced" subtitle and select it for | |
# burning into video. Allow user to disable this behavior. | |
# | |
if [ "$auto_burn" ] && [ -f "$input" ]; then | |
readonly raw_subtitle_tracks_info="$(echo "$media_info" | sed -n '/^ Stream #[^:]\{1,\}: Subtitle: /p')" | |
if [ "$raw_subtitle_tracks_info" ]; then | |
readonly raw_subtitle_tracks_count="$(echo "$raw_subtitle_tracks_info" | wc -l | sed 's/ //g')" | |
if [ "$raw_subtitle_tracks_count" == "$(echo "$all_subtitle_tracks_info" | wc -l | sed 's/ //g')" ]; then | |
index='1' | |
while ((index <= $raw_subtitle_tracks_count)); do | |
if [[ "$(echo "$raw_subtitle_tracks_info" | sed -n ${index}p)" =~ '(forced)' ]]; then | |
subtitle_track="$index" | |
break | |
fi | |
index="$((index + 1))" | |
done | |
fi | |
fi | |
fi | |
subtitle_options='' | |
if [ "$subtitle_track" ]; then | |
readonly subtitle_track_info="$(echo "$all_subtitle_tracks_info" | sed -n ${subtitle_track}p)" | |
if [ ! "$subtitle_track_info" ]; then | |
die "\`subtitle $subtitle_track\` track not found in: $input" | |
fi | |
# Burn only Blu-ray- or DVD-compatible subtitles (PGS or VobSub formats). | |
# | |
if [[ "$subtitle_track_info" =~ '(Bitmap)(PGS)' ]] || [[ "$subtitle_track_info" =~ '(Bitmap)(VOBSUB)' ]]; then | |
subtitle_options="--subtitle $subtitle_track --subtitle-burned" | |
elif [ ! "$auto_burn" ]; then | |
die "incompatible format for \`subtitle $subtitle_track\` track in: $input" | |
fi | |
fi | |
if [ "$container_format" == 'mp4' ] && [ "$optimize" ]; then | |
container_format_options="$container_format_options --optimize" | |
fi | |
if [ "$debug" ]; then | |
echo "title_options = $title_options" >&2 | |
echo "chapters_options = $chapters_options" >&2 | |
echo "container_format_options = $container_format_options" >&2 | |
echo "preset_options = $preset_options" >&2 | |
echo "reference_frames_option = $reference_frames_option" >&2 | |
echo "vbv_maxrate = $vbv_maxrate" >&2 | |
echo "vbv_bufsize = $vbv_bufsize" >&2 | |
echo "level_option = $level_option" >&2 | |
echo "rate_factor = $rate_factor" >&2 | |
echo "frame_rate_options = $frame_rate_options" >&2 | |
echo "audio_options = $audio_options" >&2 | |
echo "crop = $crop" >&2 | |
echo "size_options = $size_options" >&2 | |
echo "filter_options = $filter_options" >&2 | |
echo "subtitle_options = $subtitle_options" >&2 | |
echo "input = $input" >&2 | |
echo "output = $output" >&2 | |
exit | |
fi | |
echo "Transcoding: $input" >&2 | |
time HandBrakeCLI \ | |
$title_options \ | |
$chapters_options \ | |
--markers \ | |
$container_format_options \ | |
--encoder x264 \ | |
$preset_options \ | |
--encopts ${reference_frames_option}vbv-maxrate=$vbv_maxrate:vbv-bufsize=$vbv_bufsize$level_option \ | |
--quality $rate_factor \ | |
$frame_rate_options \ | |
$audio_options \ | |
--crop $crop \ | |
$size_options \ | |
$filter_options \ | |
$subtitle_options \ | |
--input "$input" \ | |
--output "$output" \ | |
2>&1 | tee -a "${output}.log" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment