From 4e361176ec84d1972e6f97d819920f0ca7d0dfea Mon Sep 17 00:00:00 2001 From: =?utf8?q?Rapha=C3=ABl=20Gertz?= Date: Wed, 24 Jan 2024 05:18:39 +0100 Subject: [PATCH] Support file name with spaces Add fps support Compress to 720p or lower Compress to webm format with vp suffix Smarter lock --- vidpack | 179 +++++++++++++++++++++++++------------------------------- 1 file changed, 81 insertions(+), 98 deletions(-) diff --git a/vidpack b/vidpack index ed0abf6..9ebe26e 100755 --- a/vidpack +++ b/vidpack @@ -1,16 +1,17 @@ -#! /bin/sh +#! /bin/bash + +#XXX: TODO: remove file ffmpeg2pass-1.log + +# bitrate=2560k; for i in `find images/side_quests -type f -name "*.webm"`; do tmpdir=/tmp/vidpack; passlog="$tmpdir/$(echo $i | perl -pne 's%(?:.*/)([^/]+)\.(?:mov|mp4|webm)$%\1%')"; date=$(ffprobe -hide_banner -v quiet -show_entries format_tags=date,creation_time,com.apple.quicktime.creationdate -of default=nokey=1:noprint_wrappers=1 -i $i | perl -ne '$l = $_ unless /^$/; END { chomp $l; print $l }'); ffmpeg -i $i -v error -passlogfile $passlog.1080p -vf 'fps=30' -c:v libvpx-vp9 -b:v $bitrate -pass 1 -an -f null /dev/null < /dev/null; ffmpeg -y -i $i -v error -passlogfile $passlog.1080p -vf 'fps=30' -c:v libvpx-vp9 -b:v $bitrate -pass 2 -pix_fmt yuv420p -c:a libopus -movflags +faststart -metadata creation_time="$date" -fflags +bitexact $(echo $i | perl -pne 's/.[a-z]+$/.1080p.webm/') < /dev/null; done # Brighten #XXX: ffplay -vf "curves=all='0/0 0.25/0.375 0.5/0.75 0.75/0.875 1/1'" -#Set document directory -docdir=/var/www/doc - -#Set video directory -viddir=/var/www/video +# Rescale to 720p +#XXX: ffplay -vf scale=-1:720 #Set temporary directory -tmpdir=/tmp/vidpack +tmpdir='/tmp/vidpack'; #Without temporary directory if [ ! -d "$tmpdir" ]; then @@ -21,13 +22,13 @@ fi #Set time as utc export TZ=utc -#Change to document directory -pushd "$docdir" > /dev/null || exit 1 - #Iterate on each mov or mp4 in doc dir older than 1h -for i in `find $docdir -maxdepth 1 -type f,l -name '*.mov' -o -name '*.mp4' -mmin +60`; do +#for i in `find $docdir -maxdepth 1 -type f,l -name '*.mov' -o -name '*.mp4' -o -name '*.webm' -mmin +60`; do +#find . -type f \( -name 'p*.webm' -o -name 'n*.webm' \) -print0 | while read -d $'\0' i; do +find . -type f -size +0 \( -name '*.mp4' -o -name '*.avi' -o -name '*.mpg' -o -name '*.mkv' -o -name '*.webm' -o -name '*.mov' -o -name '*.ogv' \) -print0 | while read -d $'\0' i; do +#find . -type f -size +2G \( -name '*.mp4' -o -name '*.avi' -o -name '*.mpg' -o -name '*.mkv' -o -name '*.mov' -o -name '*.ogv' \) -print0 | while read -d $'\0' i; do #Set file date - fdate=$(date -u --rfc-3339=ns -r $i | perl -pne 's/\..*$/.000000Z/; s/ /T/'); + fdate=$(date -u --rfc-3339=ns -r "$i" | perl -pne 's/\..*$/.000000Z/; s/ /T/'); #Without file date if [ -z "$fdate" ]; then @@ -35,53 +36,35 @@ for i in `find $docdir -maxdepth 1 -type f,l -name '*.mov' -o -name '*.mp4' -mmi exit 1; fi - #Set name date - #XXX: may miss if filename don't match /^(.*[^0-9])?YYYYMMDD[^0-9]?HHMMSS([^0-9].*)?$/ - ndate=$(echo $i | perl -ne 'print if s/^(?:.*[^0-9])?([0-9]{4})([0-9]{2})([0-9]{2})(?:[^0-9])?([0-9]{2})([0-9]{2})([0-9]{2})(?:[^0-9].*)?$/\1-\2-\3T\4:\5:\6.000000Z/'); - - #Without name date - if [ -z "$ndate" ]; then - #Set name date - #XXX: catch when filename match only /^(.*[^0-9])?20YYMMDD([^0-9].*)?$/ - ndate=$(echo $i | perl -ne 'print if s/^(?:.*[^0-9])?(20[0-9]{2})([0-9]{2})([0-9]{2})(?:[^0-9].*)?$/\1-\2-\3T00:00:00.000000Z/'); - fi - #Set create date - cdate=$(ffprobe -hide_banner -v quiet -show_entries format_tags=date,creation_time,com.apple.quicktime.creationdate -of default=nokey=1:noprint_wrappers=1 -i $i | perl -ne '$l = $_ unless /^$/; END { chomp $l; print $l }'); + cdate=$(ffprobe -hide_banner -v quiet -show_entries format_tags=date,creation_time,com.apple.quicktime.creationdate -of default=nokey=1:noprint_wrappers=1 -i "$i" | perl -ne '$l = $_ unless /^$/; END { chomp $l; print $l }'); #Set best date - date=$(echo -e "$fdate\n$ndate\n$cdate" | perl -ne '$l = $_ unless /^(0000:00:00 00:00:00|)$/; END { chomp $l; print $l }'); - - #Set dest filename - dest="$viddir/$(echo $date | perl -pne 's%^([0-9]{4})-([0-9]{2})-([0-9]{2}).*$%\1/\2/\3%')/$(echo ${i#$docdir/} | perl -pne 's/\.(?:mov|mp4)$//')"; - - #Without dest directory - if [ ! -d "$(dirname $dest)" ]; then - #Create dest directory or die - mkdir -p "$(dirname $dest)" || exit 1; - fi + date=$(echo -e "$fdate\n$cdate" | perl -ne '$l = $_ unless /^(0000:00:00 00:00:00|)$/; END { chomp $l; print $l }'); #Set passlog filename - passlog="$tmpdir/$(echo $i | perl -pne 's%(?:.*/)([^/]+)\.(?:mov|mp4)$%\1%')"; + passlog="$tmpdir/$(dirname "$i" | md5sum - | perl -pne 's/\s+-$//')_$(basename "$i")"; #With passlog lock file if [ -f "$passlog.lock" ]; then #Display error echo "Operation in progress: $passlog-0.log exists" 1>&2 + # Skip to next + continue; #Exit with failure - exit 0; + #exit 0; fi #Set location #XXX: see https://stackoverflow.com/questions/65231616/what-is-the-difference-between-location-and-location-eng-metadata-of-a-mp4-f #XXX: drop location name after / - location=$(ffprobe -hide_banner -v quiet -show_entries format_tags=location,location-eng,com.apple.quicktime.location.ISO6709 -of default=nokey=1:noprint_wrappers=1 -i $i 2> /dev/null | perl -ne 's/\/.*$/\//g; $l = $_ unless /^$/; END { chomp $l; print $l }') + location=$(ffprobe -hide_banner -v quiet -show_entries format_tags=location,location-eng,com.apple.quicktime.location.ISO6709 -of default=nokey=1:noprint_wrappers=1 -i "$i" 2> /dev/null | perl -ne 's/\/.*$/\//g; $l = $_ unless /^$/; END { chomp $l; print $l }') #With location if [ ! -z "$location" ]; then #Replace with location arguments - location=" -metadata location=\"$location\""; + location="-metadata location=\"$location\""; #Without location else #Prevent empty location @@ -89,18 +72,18 @@ for i in `find $docdir -maxdepth 1 -type f,l -name '*.mov' -o -name '*.mp4' -mmi fi #Set source rate - #TODO: use instead which works on webm: ffprobe -hide_banner -v quiet -select_streams v:0 -show_entries format=bit_rate -of default=nokey=1:noprint_wrappers=1 -i "$i" | perl -ne 'chomp; print' - sourcerate=$(ffprobe -hide_banner -v quiet -select_streams v:0 -show_entries stream=bit_rate -of default=nokey=1:noprint_wrappers=1 "$i" | perl -ne 'chomp; print'); + sourcerate=$(ffprobe -hide_banner -v quiet -select_streams v:0 -show_entries format=bit_rate -of default=nokey=1:noprint_wrappers=1 "$i" | perl -ne 'chomp; print'); #Set bitrate bitrate=256k - #With sourcerate >= 5120k (1080p) - if [ $sourcerate -ge 5120000 ]; then - #Set bitrate - bitrate=5120k - #With sourcerate >= 2560k (720p) - elif [ $sourcerate -ge 2560000 ]; then + ##With sourcerate >= 5120k (1080p) + #if [ $sourcerate -ge 5120000 ]; then + # #Set bitrate + # bitrate=5120k + ##With sourcerate >= 2560k (720p) + #elif [ $sourcerate -ge 2560000 ]; then + if [ $sourcerate -ge 2560000 ]; then #Set bitrate bitrate=2560k #With sourcerate >= 1024k @@ -113,66 +96,70 @@ for i in `find $docdir -maxdepth 1 -type f,l -name '*.mov' -o -name '*.mp4' -mmi bitrate=512k fi - #With dest.webm existing - if [ ! -f "$dest.webm" ]; then - #Create passlog lock file - touch "$passlog.lock" - - #With 1080p sourcerate - if [ $sourcerate -ge 5120000 ]; then - #Set bitrate - bitrate=5120k - - #First pass - ffmpeg -i $i -v error -passlogfile $passlog.1080p -c:v libvpx-vp9 -b:v $bitrate -pass 1 -an -f null /dev/null < /dev/null; - - #With first pass - if [ $? = 0 ]; then - #Second pass - ffmpeg -y -i $i -v error -passlogfile $passlog.1080p -c:v libvpx-vp9 -b:v $bitrate -pass 2 -pix_fmt yuv420p -c:a libopus -movflags +faststart -metadata creation_time="$date"$location -fflags +bitexact $dest.1080p.webm < /dev/null; - fi - - #With passlog file - if [ -f "$passlog.1080p-0.log" ]; then - #Remove passlog file - unlink "$passlog.1080p-0.log"; - fi + #Set source fps + sourcefps=$(ffprobe -hide_banner -v quiet -select_streams v:0 -show_entries stream=r_frame_rate -of default=noprint_wrappers=1:nokey=1 -i "$i" | perl -pne 'use POSIX qw(ceil); if (/^([0-9]+)\/([0-9]+)$/) { print ceil($1/$2); } elsif (/^([0-9]+)$/) { print ceil($1); }; undef $_;'); + + #Set filters + filters=() + + #Set fps + fps=24 + + #With sourcefps > 59 + if [ $sourcefps -gt 59 ]; then + #Set fps + fps=30 + #With sourcefps > 49 + elif [ $sourcefps -gt 49 ]; then + #Set fps + fps=25 + #With sourcefps > 47 + elif [ $sourcefps -gt 47 ]; then + #Set fps + fps=24 + #With sourcefps > 29 + elif [ $sourcefps -gt 29 ]; then + #Set fps + fps=30 + #With sourcefps > 24 + elif [ $sourcefps -gt 24 ]; then + #Set fps + fps=25 + fi - #Set bitrate - bitrate=1024k - fi + #Add filter + filters+=("fps='$fps'") - #With sourcerate >= 2560k (720p) - if [ $sourcerate -ge 2560000 ]; then - #Set bitrate - bitrate=2560k + #Set source height + sourceheight=$(ffprobe -hide_banner -v quiet -select_streams v:0 -show_entries stream=height -of default=nokey=1:noprint_wrappers=1 -i "$i" | perl -ne 'chomp; print') - #First pass - ffmpeg -i $i -v error -passlogfile $passlog.720p -c:v libvpx-vp9 -b:v $bitrate -pass 1 -an -f null /dev/null < /dev/null; + #With sourceheight > 1080 + if [ $sourceheight -gt 1080 ]; then + #Add filter + filters+=("scale='-1:1080'") + fi - #With first pass - if [ $? = 0 ]; then - #Second pass - ffmpeg -y -i $i -v error -passlogfile $passlog.720p -c:v libvpx-vp9 -b:v $bitrate -pass 2 -pix_fmt yuv420p -c:a libopus -movflags +faststart -metadata creation_time="$date"$location -fflags +bitexact $dest.720p.webm < /dev/null; - fi + #Set filter + filter="" - #With passlog file - if [ -f "$passlog.720p-0.log" ]; then - #Remove passlog file - unlink "$passlog.720p-0.log"; - fi + #With filters + if [ ${#filters[@]} -gt 0 ]; then + #Set filter + filter=$(IFS=,; echo "-vf ${filters[*]}"); + fi - #Set bitrate - bitrate=1024k - fi + #With existing dest file + if [ ! -f "$i.vp" ]; then + #Create passlog lock file + touch "$passlog.lock" #First pass - ffmpeg -i $i -v error -passlogfile $passlog -c:v libvpx-vp9 -b:v $bitrate -pass 1 -an -f null /dev/null < /dev/null; + ffmpeg -i "$i" -v error -passlogfile "$passlog" $filter -c:v libvpx-vp9 -b:v $bitrate -pass 1 -an -f null /dev/null < /dev/null; #With first pass if [ $? = 0 ]; then #Second pass - ffmpeg -y -i $i -v error -passlogfile $passlog -c:v libvpx-vp9 -b:v $bitrate -pass 2 -pix_fmt yuv420p -c:a libopus -movflags +faststart -metadata creation_time="$date"$location -fflags +bitexact $dest.webm < /dev/null; + ffmpeg -y -i "$i" -v error -passlogfile "$passlog" $filter -c:v libvpx-vp9 -b:v $bitrate -pass 2 -pix_fmt yuv420p -c:a libopus -movflags +faststart -metadata creation_time="$date" $location -fflags +bitexact -f webm "$i.vp" < /dev/null; fi #With passlog file @@ -186,13 +173,9 @@ for i in `find $docdir -maxdepth 1 -type f,l -name '*.mov' -o -name '*.mp4' -mmi #Remove passlog lock file unlink "$passlog.lock"; fi - fi done -#Revert to old dir -popd > /dev/null || exit 1; - #Remove temporary directory rmdir "$tmpdir" || true; -- 2.41.1