Skip to content

Instantly share code, notes, and snippets.

@joerodriguez
Forked from botsmack/encode.sh
Last active December 28, 2015 20:38
Show Gist options
  • Save joerodriguez/7558297 to your computer and use it in GitHub Desktop.
Save joerodriguez/7558297 to your computer and use it in GitHub Desktop.
remix with ffmpeg if input is already avc
#!/bin/bash
# encode.sh
#
# Copyright (c) 2013 Don Melton
#
# This version published on June 7, 2013.
#
# Re-encode video files in a format suitable for playback on Apple TV, Roku 3,
# iOS, OS X, etc.
#
# Input is assumed to be a single file readable by HandBrakeCLI and mediainfo,
# e.g. just about any .mkv, .avi, .mpg, etc. file.
#
# The script also automatically calculates video frame rates and audio channel
# configuration.
#
# Output is an MP4 container with H.264 video, AAC audio and possibly AC-3
# audio if the input has more than two channels.
#
# No scaling or cropping is performed on the output. This is a good thing.
#
# The output .mp4 file and a companion .log file are written to the current
# directory.
#
# This script depends on two separate command line tools:
#
# HandBrakeCLI http://handbrake.fr/
# mediainfo http://mediainfo.sourceforge.net/
#
# Make sure both are in your `$PATH` or redefine the variables below.
#
# Usage:
#
# ./encode.sh [input file]
#
logn="$1"
logn="$(basename "$logn")"
logn="${logn%\.[^.]*}"
{
die() {
echo "$program: $1" >&2
exit ${2:-1}
}
escape_string() {
echo "$1" | sed "s/'/'\\\''/g;/ /s/^\(.*\)$/'\1'/"
}
move_to_processed() {
echo "moving $1 >>>>> $2"
mv "$1" "$2"
}
readonly program="$(basename "$0")"
readonly input="$1"
output="$(basename "$input")"
output="${output%\.[^.]*}.m4v"
if [ ! "$input" ]; then
die 'too few arguments'
fi
handbrake="HandBrakeCLI"
ffmpeg="/usr/local/bin/ffmpeg"
mediainfo="/usr/local/bin/mediainfo"
mkvextract="/usr/local/bin/mkvextract"
audioformat="$("$mediainfo" --Inform='Audio;%Format%' "$input")"
if ([[ ! "$audioformat" =~ DTS ]] && [[ "$input" =~ m4v ]] ); then
move_to_processed $input
die 'format looks good'
fi
videocodec="$("$mediainfo" --Inform='Video;%Format%' "$input")"
num_channels="$("$mediainfo" --Inform='Audio;%Channels%' "$input" | sed 's/[^0-9].*$//')"
track_num="$("$mediainfo" --Inform='Audio;%StreamKindID%:%Format%:%Language/String%\n' "$input" | grep -i eng | grep 'AC-3' | cut -d':' -f1)"
[ ! -z $track_num ] || track_num="$("$mediainfo" --Inform='Audio;%StreamKindID%:%Format%:%Language/String%\n' "$input" | grep -i eng | grep 'DTS' | cut -d':' -f1)"
[ ! -z $track_num ] || track_num="$("$mediainfo" --Inform='Audio;%StreamKindID%:%Language/String%\n' "$input" | grep -i eng | cut -d':' -f1)"
if [ $track_num ]; then
track_num=$(($track_num + 1))
else
track_num="1"
fi
echo "choosing audio track $track_num"
echo "$videocodec"
if [ "$videocodec" = "AVC" ]; then
echo "found AVC video codec, converting with ffmpeg"
if ((num_channels > 2)); then
echo "Found more than 2 channels"
time nice -n 18 \
"$ffmpeg" -i "$input" \
-map 0:0 -map 0:1 \
-c:v copy \
-c:a:0 ac3 -b:a:0 640k \
-c:s copy \
"../processing/$output"
else
echo "Found only 2 channels"
time nice -n 18 \
"$ffmpeg" -i "$input" \
-map 0:0 -map 0:1 \
-c:v copy \
-c:a:0 libfaac -b:a:0 160k \
-c:s copy \
"../processing/$output"
fi
else
echo "found no AVC video codec, converting with handbrake"
handbrake_options="--large-file --encoder x264 --crop 0:0:0:0 --strict-anamorphic --x264-tune film --x264-preset veryfast"
# sample options
# handbrake_options="$handbrake_options --start-at duration:150 --stop-at duration:170"
if ($height > 1000); then
quality="20"
elif ($height > 720); then
quality="19"
elif ($height > 576); then
quality="18"
else
quality="18"
fi
handbrake_options="$handbrake_options -q $quality"
echo "encoding with quality $quality"
frame_rate="$("$mediainfo" --Inform='Video;%FrameRate_Original%' "$input")"
if [ ! "$frame_rate" ]; then
frame_rate="$("$mediainfo" --Inform='Video;%FrameRate%' "$input")"
fi
if [ "$frame_rate" == '29.970' ]; then
handbrake_options="$handbrake_options --rate 23.976"
else
handbrake_options="$handbrake_options --rate 30 --pfr"
fi
if ((num_channels > 2)); then
echo "Found more than 2 channels"
handbrake_options="$handbrake_options -a $track_num,$track_num --aencoder copy:ac3,ca_aac"
elif [ "$("$mediainfo" --Inform='General;%Audio_Format_List%' "$input" | sed 's| /.*||')" == 'AAC' ]; then
handbrake_options="$handbrake_options -a $track_num --aencoder copy:aac"
fi
if [ "$frame_rate" == '29.970' ]; then
handbrake_options="$handbrake_options --detelecine"
fi
echo "Encoding: $input"
time nice -n 18 \
"$handbrake" \
$handbrake_options \
--input "$input" \
--output "../processing/$output"
fi
short_name=${1##*/}
short_name=${short_name%.*}
out_dir="../../movies/$short_name"
mkdir "$out_dir"
move_to_processed "../processing/$output" "$out_dir/"
eng_sub_track_id="$("$mediainfo" --Inform='Text;%ID%:%Language/String%\n' "$input" | grep -i en | cut -d':' -f1 | head -n 1)"
if [[ ! -z $eng_sub_track_id ]]; then
# eng_sub_track_id=$((eng_sub_track_id-1))
echo "trying to extract english subtitle ID $eng_sub_track_id"
"$mkvextract" tracks "$input" $eng_sub_track_id:"$out_dir/$short_name.eng.srt"
else
echo "could not find an english subtitle"
fi
mv "$input" ../backup/
} 2>&1 | tee -a "../logs/${logn}.log"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment