π
2024-11-17 01:01
in Linux
This is a script I've had for over 20 years to recompress videos to multiple formats, including resizing resolution, rotating files, changing framerate, capturing from PAL analog cards, back in the day capturing videos from an analog tivo (circa 20 years ago), and much more.
While some amount is kind of obsolete and left for posterity, it's full of options that took me a long time to find for mencoder, and now ffmpeg, the better solution.
The script: https://marc.merlins.org/linux/scripts/vidcomp
There isn't a lot of documentation, except the script itself. Please get the version from the link above, but for indexing purposes, I'll include a potentially slightly out of date version here:
#!/bin/bash
# vidcomp -h -time "-dvd-device . -alang English" dvd://1 /var/local/space/vid/10com8.avi
# http://gentoo-wiki.com/HOWTO_Mencoder_Introduction_Guide
# http://electron.mit.edu/~gsteele/ffmpeg
# http://www.mplayerhq.hu/DOCS/HTML/en/menc-feat-enc-libavcodec.html
# http://web.njit.edu/all_topics/Prog_Lang_Docs/html/mplayer/encoding.html
# http://www.linux.com/article.pl?sid=06/08/22/2121258
# transcode -f 15 -w 800,250,100 -y divx5,lame -N 0x55 -o test.avi -i $1
# enable PAL on PVR350 mpeg2 encoder
#v4l2-ctl --set-input 2
#v4l2-ctl -s 2
#v4l2-ctl --set-ctrl=video_peak_bitrate=8000000
#v4l2-ctl --set-ctrl=video_bitrate=6000000
# dumpstream stream# file.tivo
dumpstream () {
mplayer tivo://tivo/$1 -demuxer 33 -dumpstream -dumpfile "$2"
}
die () {
echo "${1:-}"
exit 1
}
# vidcomp -br 10000 -time "-edl cuts" rec_0012.mov
#mplayer -vf cropdetect enquete.vob
#vidcomp -h -vf crop=336:320:12:126 enquete.vob
# Aspect ratio has to be forced with codecs other than xvid
#vf='-vf scale=480:370'
# vidcomp -vf "-filter:v fps=29" $i
vf=""
af=""
#codec=h264
#codec=h265
#br=3000
# AV1 is supposed to be better tan VP9, but on my short tests,
# VP9 was faster and gave smaller files.
codec=vp9
br=2000
abr=128
rot=""
ffrot=""
aud_channels=""
aud_srate=""
time="" # -ss 10 -endpos 1:54:00 (mencoder)
# -time "-ss 0:3:40 -t 3:20" (ffmpeg)
# or -time "-ss 0:3:40 -t 3:20" -vf "mp=eq2=0.9:1:-0.1" (ffmpeg)
# vidcomp -br 8000 -time "-ss 04:00 -t 0:29:20" -vf "mp=eq2=0.9:1:-0.1" full.avi
# Crop the right side crop=1540:1080:0:0
if [ $0 = *tivo* ]]; then
echo "Tivo Mode"
# tivo files are sometimes mis-detected: force the right demuxer
demux="-demuxer 33"
# Aspect ratio has to be forced with codecs other than xvid
aspect='-force-avi-aspect 1.333'
# and remove crap we don't want (tivo inserts a line of crap at the top)
vf="-vf crop=352:476,kerndeint"
elif [ $0 = *pal* ]]; then
# Couldn't quite get this to work yet, crop overrides it :(
#vf='-vf scale=540:405,crop=512:384,kerndeint'
vf='-vf scale=768:576,kerndeint'
# problem with divx is that pass2 can fail with br too low errors
codec=h264
br=800
# elif [ $0 = *camvidrecomp ]]; then
# codec=ffmpeg
# br=8000
# abr=128
# old cameras
# abr=48
# br=2400
# aud_channels="-channels 1"
# aud_srate="-srate 22050"
fi
# Hack for MTS
demux="-mc 100"
#demux="-demuxer lavf"
#aspect='-force-avi-aspect 1.777'
while [ ! -z "$1" ] && [ "$1" =~ ^-.* ]]
do
if [ "$1" = "-w" ]; then
shift
codec=win
vf="-forceidx -vf kerndeint"
fi
if [ "$1" = "-d" ]; then
shift
codec=divx
#vf="-forceidx -vf kerndeint"
fi
if [ "$1" = "-D" ]; then
shift
codec=divx1
vf="-forceidx -vf kerndeint"
fi
if [ "$1" = "-F" ]; then
shift
codec=flv
br=400
abr=56
aud_srate="-srate 22050"
vf='-vf scale=512:384'
fi
if [ "$1" = "-h" -o "$1" = "-h4" ]; then
shift
codec=h264
vf="-forceidx -vf kerndeint"
fi
if [ "$1" = "-h4ff" ]; then
shift
codec=ffmpeg4
fi
if [ "$1" = "-h5" ]; then
shift
codec=h265
fi
if [ "$1" = "-vp9" ]; then
shift
codec=vp9
fi
if [ "$1" = "-av1" ]; then
shift
codec=av1
fi
if [ "$1" = "-x" ]; then
shift
codec=xvid
vf="-forceidx -vf kerndeint"
fi
if [ "$1" = "-ff" ]; then
shift
codec=ffmpeg
fi
# https://trac.ffmpeg.org/wiki/Encode/H.264
# says not compatible with most players
if [ "$1" = "-ffll" ]; then
shift
codec=ffmpegll
fi
if [ "$1" = "-vol" ]; then
shift
vol=":vol=$1"
shift
fi
# try instead of rotate
if [ "$1" = "-f" ]; then
shift
rot="-vf flip,mirror"
#ffrot="-vf hflip,vflip"
# https://www.baeldung.com/linux/ffmpeg-rotate-video#:~:text=transpose%20is%20an%20FFmpeg%20filter,the%20values%20from%200%2D3.
ffrot="-vf hflip,vflip"
ffrot="-vf transpose=1,transpose=3"
fi
if [ "$1" = "-r" ]; then
#rot="-vf mirror,rotate=$2"
# works with -r 3
rot="-vf rotate=$2"
ffrot="-vf transpose=$2"
shift 2
fi
if [ "$1" = "-br" ]; then
br="$2"
shift 2
fi
# -ss 10 -endpos 1:54:00
# -ss 00:01:00 -to 00:02:00
if [ "$1" = -time ]; then
time="$2"
shift 2
fi
# for instance -vf scale=540:405,crop=512:384
if [ "$1" = -vf ]; then
vf="$2"
shift 2
fi
done
test $# -eq 1 || test $# -eq 2 || die "$0 file_src file_dest (please read script for options)"
test $# -eq 2 && test -f "$2" && die "file_dest should not exist"
src="$1"
dest="${2:-$src.new}"
#set -vx
if [ "$codec" = win ]; then
ionice -c3 nice -19 mencoder $demux $aud_channels $aud_srate -oac mp3lame -lameopts mode=3:abr:br=$abr$vol $time $aspect $vf -ovc lavc -lavcopts vcodec=msmpeg4v2:vhq:vbitrate=$br $rot -o "$dest" "$src"
elif [ "$codec" = divx1 ]; then
ionice -c3 nice -19 mencoder $demux $aud_channels $aud_srate -oac mp3lame -lameopts mode=3:abr:br=$abr$vol $time $aspect $vf -ovc lavc -lavcopts vcodec=mpeg4:vhq:trell=yes:v4mv=yes:vbitrate=$br -ffourcc DX50 $rot -o "$dest" "$src"
elif [ "$codec" = flv ]; then
# http://www.jeremychapman.info/cms/mencoder-avi-to-flv-conversion
ionice -c3 nice -19 mencoder $demux $aud_channels $aud_srate -oac mp3lame -lameopts mode=3:abr:br=$abr$vol $time $aspect $vf -ovc lavc -lavcopts vcodec=flv:vbitrate=$br:mbd=2:mv0:trell:v4mv:cbp:last_pred=3 -of lavf $rot -o "$dest" "$src"
elif [ "$codec" = xvid ]; then
ionice -c3 nice -19 mencoder $demux $aud_channels $aud_srate -oac mp3lame -lameopts mode=3:abr:br=$abr$vol $time $aspect $vf -ovc xvid -xvidencopts bitrate=$br $rot -o "$dest" "$src"
elif [ "$codec" = ffmpeg4 ]; then
# aspect/-force-avi-aspect not supported by ffmpeg
#ionice -c3 nice -19 ffmpeg $time -analyzeduration 9999999 -probesize 9999999 -y -i "$src" $vf -c:v libx264 -preset medium -b:v ${br}k -pass 1 -c:a libfdk_aac -b:a 128k -f mp4 /dev/null
#ionice -c3 nice -19 ffmpeg $time -analyzeduration 9999999 -probesize 9999999 -i "$src" $vf -c:v libx264 -preset medium -b:v ${br}k -pass 2 -c:a libfdk_aac -b:a 128k -f mp4 "$dest"
ionice -c3 nice -19 ffmpeg $time -analyzeduration 9999999 -probesize 9999999 -y -i "$src" -filter:v fps=30 $vf -c:v libx264 -preset medium -b:v ${br}k -pass 1 -an -f mp4 /dev/null
ionice -c3 nice -19 ffmpeg $time -analyzeduration 9999999 -probesize 9999999 -i "$src" -filter:v fps=30 $vf -c:v libx264 -preset medium -b:v ${br}k -pass 2 -c:a aac -b:a 128k -f mp4 "$dest"
### H265 in MP4 => slow and royalties
elif [ "$codec" = h265 ]; then
# https://trac.ffmpeg.org/wiki/Encode/H.265
ionice -c3 nice -19 ffmpeg $time -y -i "$src" $vf $ffrot -filter:v fps=30 -c:v libx265 -b:v ${br}k -x265-params pass=1 -an -f mp4 /dev/null
ionice -c3 nice -19 ffmpeg $time -i "$src" $vf $ffrot -filter:v fps=30 -c:v libx265 -b:v ${br}k -x265-params pass=2 -c:a aac -b:a 128k -f mp4 "$dest"
# https://trac.ffmpeg.org/wiki/Encode/AV1
#
# vp9 vs av1 comparison and flags:
# https://jonathanmh.com/p/encoding-webm-videos-with-ffmpeg-vp9-av1
# Gemini says: Compression Efficiency
# * AV1: Offers the best compression efficiency, resulting in smaller file sizes for a given quality level
# * H.265: Provides significant improvements over H.264, offering better compression than VP9 in many cases
# * VP9: While not as efficient as H.265 or AV1, it still offers decent compression and is widely supported.
# Encoding and Decoding Speed:
# * AV1: Requires more computational power for encoding and decoding, which can impact performance on older hardware
# * H.265: Offers a good balance between compression efficiency and encoding/decoding speed.
# * VP9: Generally faster to encode and decode compared to AV1.
### VP9 is free version of H265
# https://caniuse.com/?search=vp9
# cpu used lower values are slower but better quality -row-mt 1 added HT. Speed is faster than AV1 but compression seems still good
# 2453715 file1.mp4
# 1555963 file1_av1_4.webm
# 1611192 file1_av1_6.webm
# 1611192 file1_av1_8.webm
# 1668740 file1_vp9_4.webm
# 1598794 file1_vp9_6.webm
# 1595698 file1_vp9_8.webm
elif [ "$codec" = vp9 ]; then
ionice -c3 nice -19 ffmpeg $time -y -i "$src" $vf $ffrot -filter:v fps=30 -c:v libvpx-vp9 -b:v ${br}k -cpu-used 6 -row-mt 1 -pass 1 -an -f null /dev/null
ionice -c3 nice -19 ffmpeg $time -i "$src" $vf $ffrot -filter:v fps=30 -c:v libvpx-vp9 -b:v ${br}k -cpu-used 6 -row-mt 1 -pass 2 -c:a libopus -b:a 128k "$src.webm"
### AV1 a better version of VP9
# https://caniuse.com/?search=av1
# https://trac.ffmpeg.org/wiki/Encode/AV1
# cpu used lower values are slower but better quality -row-mt 1 added HT
elif [ "$codec" = av1 ]; then
ionice -c3 nice -19 ffmpeg $time -y -i "$src" $vf $ffrot -filter:v fps=30 -c:v libaom-av1 -b:v ${br}k -cpu-used 8 -row-mt 1 -pass 1 -an -f null /dev/null
ionice -c3 nice -19 ffmpeg $time -i "$src" $vf $ffrot -filter:v fps=30 -c:v libaom-av1 -b:v ${br}k -cpu-used 8 -row-mt 1 -pass 2 -c:a libopus -b:a 128k "$src.webm"
# old legacy mencoder stuff (mencoder h264 or divx)
else
pass="$dest".pass
for i in 1 2
do
echo "DOING $codec PASS $i"
echo "------------------"
if [ "$codec" = h264 ]; then
#vf=$vf,dsize=4/3,scale
#vf=$vf,scale=720:480
vf=$vf,scale # why is scale there by itself?
# Trellis searched quantization
# do not allow space in source, to allow a multi file source
ionice -c3 nice -19 mencoder -passlogfile "$pass" $demux $aud_channels $aud_srate -oac mp3lame -lameopts mode=3:abr:br=$abr$vol $time $aspect -vf $vf -ovc x264 -x264encopts bitrate=$br:turbo=1:pass=1:threads=0 $rot -o "$dest" $src || die "multipass failed on pass $i"
elif [ "$codec" = divx ]; then
# Trellis searched quantization
ionice -c3 nice -19 mencoder -passlogfile "$pass" $demux $aud_channels $aud_srate -oac mp3lame -lameopts mode=3:abr:br=$abr$vol $time $aspect $vf -ovc lavc -lavcopts vcodec=mpeg4:vhq:trell=yes:v4mv=yes:vbitrate=$br:vpass=$i -ffourcc DX50 $rot -o "$dest" "$src" || die "multipass failed on pass $i"
fi
done
/bin/rm "$pass" *.pass.mbtree &>/dev/null
#else
# echo "Unknown $codec" >&2
fi
#vidrename --noinfo "$dest"
/bin/rm ffmpeg2pass-0.log ffmpeg2pass-0.log.mbtree x265_2pass.log* &>/dev/null
Again, to up to date version is here: https://marc.merlins.org/linux/scripts/vidcomp |