2017年09月21日 Script to merge movies left-right or top-bottom [長年日記]
_ mergemovies.sh
Script to merge two movies into left-right or top-bottom.
#! /bin/sh # if [ "X$1" = "X-h" -o "X$1" = "X--help" ] then echo "Usage: $0 -l left_movie -r right_movie -o output_movie [options]" echo " $0 -t top_movie -b bottom_movie -o output_movie [options]" echo "Merge movies into output_movie." echo "" echo "-l LEFT_MOVIE movie file for left side" echo "-r RIGHT_MOVIE movie file for right side" echo "-t TOP_MOVIE movie file for top side" echo "-b BOTTOM_MOVIE movie file for bottom side" echo "-o OUTPUT_MOVIE movie file for output" echo "-a AUDIO_INPUT lr for left and right (default)" echo " l for left" echo " r for right" echo " tb for top and bottom (default)" echo " t for top" echo " b for bottom" echo " none for no audio" echo "-bv VIDEO_BITRATE bitrate for video (e.g. 2000k)" echo "-ba AUDIO_BITRATE bitrate for audio (e.g. 192k)" echo "-vl VOLUME amplitude for left volume (e.g. 1.2)" echo " -vr for right" echo " -vt for top" echo " -vb for bottom" echo "-fr FRAME_RATE frame rate (e.g. 29.97)" echo "-sz SIZE size for output (e.g. 1920x1080)" echo "-stl STARTTIME start time for left movie (e.g. HH:MM:SS[.mmm])" echo " -str for right" echo " -stt for top" echo " -stb for bottom" echo "-etl ENDTIME endtime for left movie (e.g. HH:MM:SS[.mmm])" echo " -etr for right" echo " -ett for top" echo " -etb for bottom" echo "-ell ELAPSTIME elapstime for left movie (e.g. HH:MM:SS[.mmm])" echo " -elr for right" echo " -elt for top" echo " -elb for bottom" exit 0 fi function preconvert(){ input=$1; shift output=$1; shift pw=$1; shift ph=$1; shift vbitrate=$1; shift abitrate=$1; shift starttime=$1; shift endtime_with_opt=$1; shift volume=$1; shift framerate=$1 iwh=`ffmpeg -i ${input} 2>&1 | egrep 'Stream.*Video' | sed -e 's/^.* \([0-9][0-9]*x[0-9][0-9]*\)[^0-9].*$/\1/g'` iw=`echo ${iwh} | cut -dx -f1` ih=`echo ${iwh} | cut -dx -f2` cond=`echo ${iw}*${ph}/${ih}/${pw} | bc` if [ ${cond} -gt 0 ] then sw=${pw} sh=`echo ${pw}*${ih}/${iw} | bc` padw=0 padh=`echo "(${ph} - ${sh})/2" | bc` else sh=${ph} sw=`echo ${ph}*${iw}/${ih} | bc` padh=0 padw=`echo "(${pw} - ${sw})/2" | bc` fi ffmpeg -i ${input} -ss ${starttime} ${endtime_with_opt} -vcodec h264 -b:v ${vbitrate} -r ${framerate} -strict -2 -acodec aac -b:a ${abitrate} -vol ${volume} -filter_complex "[0:v]scale=${sw}:${sh},pad=${pw}:${ph}:${padw}:${padh}" -y ${output} } left_movie="" right_movie="" top_movie="" bottom_movie="" output_movie="" audio_input="" video_bitrate="2000k" audio_bitrate="192k" left_volume="256" right_volume="256" top_volume="256" bottom_volume="256" frame_rate="3000/1001" size="640x360" left_starttime="00:00:00" left_endelapstime="-t 24:00:00" right_starttime="00:00:00" right_endelapstime="-t 24:00:00" top_starttime="00:00:00" top_endelapstime="-t 24:00:00" bottom_starttime="00:00:00" bottom_endelapstime="-t 24:00:00" while [ $# -ne 0 ] do case $1 in -l) shift left_movie="$1" ;; -r) shift right_movie="$1" ;; -t) shift top_movie="$1" ;; -b) shift bottom_movie="$1" ;; -o) shift output_movie="$1" ;; -a) shift audio_input="$1" ;; -bv) shift video_bitrate="$1" ;; -ba) shift audio_bitrate="$1" ;; -vl) shift vol=`echo 256 \* $1 | bc | sed -e 's/\..*$//'` left_volume="${vol}" ;; -vr) shift vol=`echo 256 \* $1 | bc | sed -e 's/\..*$//'` right_volume="${vol}" ;; -vt) shift vol=`echo 256 \* $1 | bc | sed -e 's/\..*$//'` top_volume="${vol}" ;; -vb) shift vol=`echo 256 \* $1 | bc | sed -e 's/\..*$//'` bottom_volume="${vol}" ;; -fr) shift frame_rate="$1" ;; -sz) shift size="$1" ;; -stl) shift left_starttime="$1" ;; -etl) shift left_endelapstime="-to $1" ;; -ell) shift left_endelapstime="-t $1" ;; -str) shift right_starttime="$1" ;; -etr) shift right_endelapstime="-to $1" ;; -elr) shift right_endelapstime="-t $1" ;; -stt) shift top_starttime="$1" ;; -ett) shift top_endelapstime="-to $1" ;; -elt) shift top_endelapstime="-t $1" ;; -stb) shift bottom_starttime="$1" ;; -etb) shift bottom_endelapstime="-to $1" ;; -elb) shift bottom_endelapstime="-t $1" ;; esac shift done if [ "X${audio_input}" = "X" ] then if [ "X${left_movie}" = "X" ] then audio_input="tb" else audio_input="lr" fi fi pw=`echo ${size} | cut -dx -f1` ph=`echo ${size} | cut -dx -f2` if [ "X${left_movie}" = "X" ] then half_ph=`echo ${ph}/2 | bc` preconvert ${top_movie} /tmp/mergemovie.$$.1.tmp.mp4 ${pw} ${half_ph} ${video_bitrate} ${audio_bitrate} ${top_starttime} "${top_endelapstime}" ${top_volume} ${frame_rate} preconvert ${bottom_movie} /tmp/mergemovie.$$.2.tmp.mp4 ${pw} ${half_ph} ${video_bitrate} ${audio_bitrate} ${bottom_starttime} "${bottom_endelapstime}" ${bottom_volume} ${frame_rate} else half_pw=`echo ${pw}/2 | bc` preconvert ${left_movie} /tmp/mergemovie.$$.1.tmp.mp4 ${half_pw} ${ph} ${video_bitrate} ${audio_bitrate} ${left_starttime} "${left_endelapstime}" ${left_volume} ${frame_rate} preconvert ${right_movie} /tmp/mergemovie.$$.2.tmp.mp4 ${half_pw} ${ph} ${video_bitrate} ${audio_bitrate} ${right_starttime} "${right_endelapstime}" ${right_volume} ${frame_rate} fi ffmpeg -i /tmp/mergemovie.$$.1.tmp.mp4 -strict -2 -acodec copy -vn -y /tmp/mergemovie.$$.3.tmp.wav.mp4 ffmpeg -i /tmp/mergemovie.$$.2.tmp.mp4 -strict -2 -acodec copy -vn -y /tmp/mergemovie.$$.4.tmp.wav.mp4 case ${audio_input} in lr|tb) ffmpeg -i /tmp/mergemovie.$$.3.tmp.wav.mp4 -i /tmp/mergemovie.$$.4.tmp.wav.mp4 -strict -2 -acodec aac -b:a ${audio_bitrate} -filter_complex amix=inputs=2 -y /tmp/mergemovie.$$.5.tmp.wav.mp4 ;; l|t) mv /tmp/mergemovie.$$.3.tmp.wav.mp4 /tmp/mergemovie.$$.5.tmp.wav.mp4 ;; r|b) mv /tmp/mergemovie.$$.4.tmp.wav.mp4 /tmp/mergemovie.$$.5.tmp.wav.mp4 ;; esac ffmpeg -i /tmp/mergemovie.$$.1.tmp.mp4 -vcodec copy -strict -2 -an -y /tmp/mergemovie.$$.6.tmp.mp4 ffmpeg -i /tmp/mergemovie.$$.2.tmp.mp4 -vcodec copy -strict -2 -an -y /tmp/mergemovie.$$.7.tmp.mp4 if [ "X${left_movie}" = "X" ] then ffmpeg -i /tmp/mergemovie.$$.6.tmp.mp4 -i /tmp/mergemovie.$$.7.tmp.mp4 -strict -2 -vcodec h264 -b:v ${video_bitrate} -filter_complex "[0:v]pad=iw:ih*2[v1];[v1][1:v]overlay=0:H/2" -y /tmp/mergemovie.$$.8.tmp.mp4 else ffmpeg -i /tmp/mergemovie.$$.6.tmp.mp4 -i /tmp/mergemovie.$$.7.tmp.mp4 -strict -2 -vcodec h264 -b:v ${video_bitrate} -filter_complex "[0:v]pad=iw*2:ih[v1];[v1][1:v]overlay=W/2:0" -y /tmp/mergemovie.$$.8.tmp.mp4 fi if [ "X${audio_input}" = "Xnone" ] then mv /tmp/mergemovie.$$.8.tmp.mp4 ${output_movie} else ffmpeg -i /tmp/mergemovie.$$.8.tmp.mp4 -i /tmp/mergemovie.$$.5.tmp.wav.mp4 -strict -2 -vcodec copy -acodec copy -y ${output_movie} fi rm -f /tmp/mergemovie.$$.*.tmp.mp4 /tmp/mergemovie.$$.*.tmp.wav.mp4