134 lines
3.3 KiB
Bash
Executable File
134 lines
3.3 KiB
Bash
Executable File
#!/bin/bash -e
|
|
|
|
set -e
|
|
|
|
# defaults for all configuration values
|
|
ENC="ffmpeg"
|
|
CRF=24
|
|
OPTS="-c:v libx265 -pix_fmt yuv420p10le -preset fast -x265-params crf=${CRF}:aq-mode=3 -c:a libvorbis -aq 5"
|
|
# This is to split out and copy attachment streams, like subtitles
|
|
# and fonts, so they only get copied once.
|
|
DATA_OPTS="-map 0 -c:s copy -c:t copy -c:d copy -vn -an"
|
|
SUFFIX="_new.mkv"
|
|
SERVERS=":"
|
|
LEN=300
|
|
OUTDIR=`mktemp -d`
|
|
VERBOSE="error"
|
|
# override defaults in a ~/.dverc file
|
|
if [ -f ~/.dverc ]; then
|
|
source ~/.dverc
|
|
fi
|
|
|
|
function on_finish() {
|
|
echo "Cleaning up temporary working files"
|
|
cd "$CWD"
|
|
rm -rf "${OUTDIR}"/
|
|
echo "Finished cleaning"
|
|
}
|
|
|
|
function usage() {
|
|
cat << EOF
|
|
usage: $0 [options] filename
|
|
|
|
This script breaks a video file up into chunks and encodes them in parallel via SSH on
|
|
multiple hosts.
|
|
|
|
OPTIONS:
|
|
-h this help message.
|
|
-l comma separated list of hosts to use to encode. (default=${SERVERS})
|
|
-t rough length of individual video chunks, in seconds. (default=${LEN})
|
|
-o encoding options. (default=${OPTS})
|
|
-s output file suffix. (default=${SUFFIX})
|
|
-q video encoding quality, shortcut to use default encoding options with
|
|
a different CRF. (default=${CRF})
|
|
-v verbose job output. (default=false)
|
|
EOF
|
|
}
|
|
|
|
# check all required helper utils
|
|
function checkpaths() {
|
|
for cmd in parallel ffmpeg; do
|
|
if ! CMD=`which $cmd`; then
|
|
echo "$cmd not found in local path."
|
|
exit 1
|
|
fi
|
|
done
|
|
}
|
|
|
|
while getopts “hl:t:o:s:q:v” OPTION; do
|
|
case $OPTION in
|
|
h)
|
|
usage
|
|
exit 1
|
|
;;
|
|
l)
|
|
SERVERS="$OPTARG"
|
|
;;
|
|
t)
|
|
LEN="$OPTARG"
|
|
;;
|
|
q)
|
|
CRF="$OPTARG"
|
|
OPTS="-c:v libx265 -pix_fmt yuv420p10le -preset fast -x265-params crf=${CRF}:aq-mode=3 -c:a libvorbis -aq 5"
|
|
;;
|
|
o)
|
|
OPTS="$OPTARG"
|
|
;;
|
|
s)
|
|
SUFFIX="$OPTARG"
|
|
;;
|
|
v)
|
|
VERBOSE="info"
|
|
;;
|
|
?)
|
|
usage
|
|
exit
|
|
;;
|
|
esac
|
|
done
|
|
shift $((OPTIND-1))
|
|
|
|
if [ $# -lt 1 ]; then
|
|
usage
|
|
exit 1
|
|
fi
|
|
|
|
CWD=`pwd`
|
|
trap on_finish EXIT
|
|
|
|
checkpaths
|
|
|
|
if ! mkdir -p ${OUTDIR}; then
|
|
echo "Couldn't create temp chunk output dir ${OUTDIR}."
|
|
exit 1
|
|
fi
|
|
|
|
echo "Creating chunks to encode"
|
|
if [[ "$1" == *".AVI" || "$1" == *".avi" ]]; then
|
|
$ENC -fflags +genpts -i "$1" -map 0 -codec copy -f segment -segment_time $LEN -segment_format matroska -v ${VERBOSE} "${OUTDIR}/chunk-%03d.orig"
|
|
else
|
|
$ENC -i "$1" -map 0 -codec copy -f segment -segment_time $LEN -segment_format matroska -v ${VERBOSE} "${OUTDIR}/chunk-%03d.orig"
|
|
fi
|
|
echo "Copying file metadata"
|
|
DATA_IN="-i data.enc -map 1"
|
|
${ENC} -y -v ${VERBOSE} -i "$1" ${DATA_OPTS} -f matroska "${OUTDIR}/data.enc" ||
|
|
DATA_IN=""
|
|
|
|
cd "$OUTDIR"
|
|
|
|
echo "Running parallel encoding jobs"
|
|
PAR_OPTS="--no-notice --gnu -j 1 -S ${SERVERS} --eta --retries 2 --nice 10"
|
|
PAR_OPTS="${PAR_OPTS} --workdir ... --transfer --return {.}.enc"
|
|
ENC_OPTS="-y -v ${VERBOSE} -i {} ${OPTS} -f matroska {.}.enc"
|
|
|
|
parallel ${PAR_OPTS} ${ENC} ${ENC_OPTS} ::: chunk-*.orig
|
|
|
|
echo "Combining chunks into final video file"
|
|
echo "ffconcat version 1.0" > concat.txt
|
|
for f in `ls chunk-*.enc | sort`; do
|
|
echo "file $f" >> concat.txt
|
|
done
|
|
BASE=`basename "$1"`
|
|
OUTFILE="${CWD}"/"${BASE%.*}${SUFFIX}"
|
|
${ENC} -y -v ${VERBOSE} -f concat -i concat.txt ${DATA_IN} -map 0 -f matroska -c copy "${OUTFILE}"
|