commit 1fbeb95ca78b9e22454688d1d11d8335750b42c9 parent fecff68b69260c611c7d4a498ed02b32b6c7a2d2 Author: Anders Damsgaard <anders@adamsgaard.dk> Date: Wed, 27 Jan 2021 14:32:23 +0100 add mediapres for combining audio, images, and videos into single video Diffstat:
A | .local/bin/mediapres | | | 107 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
1 file changed, 107 insertions(+), 0 deletions(-)
diff --git a/.local/bin/mediapres b/.local/bin/mediapres @@ -0,0 +1,107 @@ +#!/bin/sh +# combine video and image files specified in "timestampfile" with +# "audiofile" to "outvideofile" +set -e + +videores="1920x1080" +bgcolor="black" +ffmpegcodec="-r 30 -c:v libx264 -threads 0 -preset faster -pix_fmt yuv420p -c:a aac -crf 23" +ext="mp4" + +die() +{ + printf '%s: error: %s\n' "${0##*/}" "$1" >&2 + exit 1 +} + +usage() +{ + die "${0##*/} timestampfile [audiofile] [outvideofile]" +} + +fit169() +{ + convert -resize "$videores"\> -size "$videores" "$1" \ + xc:"$bgcolor" +swap -gravity center -composite "$2" +} + +img2vid() +{ + ffmpeg -y \ + -f lavfi -i anullsrc=r=48000 -i "${1}" \ + -t "${2}" \ + $ffmpegcodec \ + "${3}" </dev/null +} + +recodevid() +{ + ffmpeg -y -i "${1}" -to "${2}" $ffmpegcodec "${3}" </dev/null +} + +time_to_sec() +{ + if [ "$(uname)" = Linux ]; then + date -d "$1" '+%s' + else + date -j '+%s' "$1" + fi +} + +if [ "$#" -lt 1 ]; then + usage +fi + +timestampfile="$1" +audiofile="$2" +outvideofile="${3:-out.${ext}}" + +tmpdir=".${outvideofile}.tmp" +mkdir -p "${tmpdir}" +files="${tmpdir}/list" +> "${files}" + +tstart="00:00:00" +while read -r tend file useaudio; do + + if test -z "$tend" || test -z "$file"; then + die "invalid line in timestampfile (tend = '$tend', file = '$file'" + fi + + tmpfile="${tmpdir}/$(basename "$file")" + + duration="$(($(time_to_sec "$tend") - $(time_to_sec "$tstart")))" + + out="${tmpfile%.*}.${ext}" + + if test ! -f "$out"; then + case "$(file -ib "$file")" in + video/*) + recodevid "$file" "$duration" "$out";; + image/*) + fit169 "$file" "$tmpfile" + img2vid "$tmpfile" "$duration" "$out" + rm -f "$tmpfile";; + *) + die "unsupported file type for $file";; + esac + fi + printf "file '%s'\\n" "$(basename ${tmpfile%.*}.${ext})" >> "${tmpdir}/list" + + tstart="$tend" +done < "$timestampfile" + +ffmpeg -y \ + -f concat -safe 0 -i "$files" \ + -max_muxing_queue_size 4096 \ + $ffmpegcodec \ + "$outvideofile" </dev/null + +if test "${audiofile}"; then + ffmpeg -y \ + -i "$outvideofile" \ + -i "${audiofile}" \ + -filter_complex amix=inputs=2:duration=longest \ + $ffmpegcodec \ + "$outvideofile" +fi