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}"