dotfiles

configuration files for shell, text editor, graphical environment, etc.
git clone git://src.adamsgaard.dk/dotfiles # fast
git clone https://src.adamsgaard.dk/dotfiles.git # slow
Log | Files | Refs | README | LICENSE Back to index

mediapres (2198B)


      1 #!/bin/sh
      2 # combine video and image files specified in "timestampfile" with
      3 # "audiofile" to "outvideofile"
      4 set -e
      5 
      6 videores="1920x1080"
      7 bgcolor="black"
      8 ffmpegcodec="-r 30 -c:v libx264 -threads 0 -preset faster -pix_fmt yuv420p -c:a aac -crf 23"
      9 ext="mp4"
     10 
     11 die()
     12 {
     13 	printf '%s: error: %s\n' "${0##*/}" "$1" >&2
     14 	exit 1
     15 }
     16 
     17 usage()
     18 {
     19 	die "${0##*/} timestampfile [audiofile] [outvideofile]"
     20 }
     21 
     22 fit169()
     23 {
     24 	convert -resize "$videores"\> -size "$videores" "$1" \
     25 		xc:"$bgcolor" +swap -gravity center -composite "$2"
     26 }
     27 
     28 img2vid()
     29 {
     30 	ffmpeg -y \
     31 		-f lavfi -i anullsrc=r=48000 -i "${1}" \
     32 		-t "${2}" \
     33 		$ffmpegcodec \
     34 		"${3}" </dev/null
     35 }
     36 
     37 recodevid()
     38 {
     39 	ffmpeg -y -i "${1}" -to "${2}" $ffmpegcodec "${3}" </dev/null
     40 }
     41 
     42 time_to_sec()
     43 {
     44 	if [ "$(uname)" = Linux ]; then
     45 		date -d "$1" '+%s'
     46 	else
     47 		date -j '+%s' "$(printf "$1" | sed 's/://;s/:/./')"
     48 	fi
     49 }
     50 
     51 if [ "$#" -lt 1 ]; then
     52 	usage
     53 fi
     54 
     55 timestampfile="$1"
     56 audiofile="$2"
     57 outvideofile="${3:-out.${ext}}"
     58 
     59 tmpdir=".${outvideofile}.tmp"
     60 mkdir -p "${tmpdir}"
     61 files="${tmpdir}/list"
     62 > "${files}"
     63 
     64 tstart="00:00:00"
     65 while read -r tend file useaudio; do
     66 
     67 	if test -z "$tend" || test -z "$file"; then
     68 		die "invalid line in timestampfile (tend = '$tend', file = '$file'"
     69 	fi
     70 
     71 	tmpfile="${tmpdir}/$(basename "$file")"
     72 
     73 	duration="$(($(time_to_sec "$tend") - $(time_to_sec "$tstart")))"
     74 
     75 	out="${tmpfile%.*}.${ext}"
     76 
     77 	if test ! -f "$out"; then
     78 		if test ! -r "$file"; then
     79 			die "couldn't read $file"
     80 		fi
     81 		case "$(file -ib "$file")" in
     82 			video/*)
     83 				recodevid "$file" "$duration" "$out";;
     84 			image/*)
     85 				fit169 "$file" "$tmpfile"
     86 				img2vid "$tmpfile" "$duration" "$out"
     87 				rm -f "$tmpfile";;
     88 			*)
     89 				die "unsupported file type for $file";;
     90 		esac
     91 	fi
     92 	printf "file '%s'\\n" "$(basename ${tmpfile%.*}.${ext})" >> "${tmpdir}/list"
     93 
     94 	tstart="$tend"
     95 done < "$timestampfile"
     96 
     97 ffmpeg -y \
     98 	-f concat -safe 0 -i "$files" \
     99 	-max_muxing_queue_size 9999 \
    100 	$ffmpegcodec \
    101 	"$outvideofile" </dev/null
    102 
    103 if test "${audiofile}"; then
    104 	ffmpeg -y \
    105 		-i "${outvideofile}" \
    106 		-i "${audiofile}" \
    107 		-filter_complex amix=inputs=2:duration=longest \
    108 		$ffmpegcodec \
    109 		"audio-${outvideofile}"
    110 	mv "audio-${outvideofile}" "${outvideofile}"
    111 fi
    112 
    113 rm -rf "${tmpdir}"