#!/bin/bash -e set -e # defaults for all configuration values ENC="ffmpeg" OPTS="-c:v libx265 -preset fast -x265-params crf=24 -c:a libvorbis -aq 5 -c:s copy" SUFFIX="_new.mkv" SERVERS=":" LEN=60 OUTDIR="/tmp/.dve" #ram VERBOSE="error" # override defaults in a ~/.dverc file if [ -f ~/.dverc ]; then source ~/.dverc fi 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=${MINLEN}) -o encoding options. (default=${OPTS}) -s output file suffix. (default=${SUFFIX}) -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:v” OPTION; do case $OPTION in h) usage exit 1 ;; l) SERVERS="$OPTARG" ;; t) LEN="$OPTARG" ;; o) OPTS="$OPTARG" ;; s) SUFFIX="$OPTARG" ;; v) VERBOSE="info" ;; ?) usage exit ;; esac done shift $((OPTIND-1)) if [ $# -lt 1 ]; then usage exit 1 fi 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 CWD=`pwd` 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" echo "parallel ${PAR_OPTS} ${ENCPATH} ${ENC_OPTS} ::: chunk-*.orig" 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 -f matroska -map 0 -c copy "${OUTFILE}" echo "Cleaning up temporary working files" rm -f "${OUTDIR}"/* cd "$CWD"