#!/usr/bin/env bash # Copyright: Julien Moutinho # License: AGPL-3.0-or-later # cd "${0%/*}" set -eu shopt -s nullglob ffmpeg_ () { local -; set -x; nice -19 time ffmpeg &2 "$@"; } set -x for dir in "$@"; do IFS=/ read -r user year x month x <<<"$dir" test -n "$year" || exec "$0" "$user"/2*/src/*/ test -n "$month" || exec "$0" "$user"/"$year"/src/*/ pushd "$user/$year" >/dev/null test -d src/"$month" || { popd; continue; } (cd src; find -L "$month" -type f -size +180M -printf '%f %p\n') | sort -t/ -k1.5 | cut -f2 -d ' ' | while read -r src; do echo >&2 "$dir: processing $year/src/$src" base=${src%.*} name=${base#*/} id=${name%%.*} mkdir -p {{tmp,wip}/reencode,old}/"${base%/*}" need_psize () { # Slow, but needed to make wide videos span two columns of the CSS grid IFS=' ' read -r width height rotation <<<"$(ffprobe -v error -select_streams v:0 -show_entries stream=width,height:stream_side_data=rotation -of csv=p=0:s='\ ' src/"$src")" case "$rotation" in (90|-90) w=$width; width=$height; height=$w;; esac if [ "$width" -gt "$height" ] then psize=$height else psize=$width fi } case "$src" in *.mp4|*.MOV) need_psize case $psize in 480) crf=30;; 720) crf=40;; 1080) crf=50;; *) exit 3;; esac preset=5 ext="preset=$preset.crf=$crf.av1.webm" need_opus () { test tmp/reencode/"$base".opus -nt src/"$src" || { ffmpeg_ -i src/"$src" \ -map 0:a -c:a libopus -b:a 64k -application voip \ wip/reencode/"$base".opus mv_ {wip,tmp}/reencode/"$base".opus } } test src/"$base.$ext" -nt src/"$src" || { need_opus ffmpeg_ -i src/"$src" -i tmp/reencode/"$base".opus \ -map 0:v \ -filter:v format=yuv420p \ -c:v libsvtav1 -preset "$preset" -crf "$crf" \ -svtav1-params input-depth=8:keyint=10s:enable-overlays=1:enable-tf=0:scd=1:scm=0:tune=0:fast-decode=1 \ -map 1:a -c:a copy \ wip/reencode/"$base.$ext" mv_ {wip/reencode,src}/"$base.$ext" mv_ {src,old}/"$src" } ;; esac done rm -vrf {tmp,wip}/reencode popd >/dev/null done