10
My FFmpeg Bash Functions
(infosec.pub)
submitted
3 days ago* (last edited 22 hours ago)
by
Willie169@infosec.pub
to
c/ffmpeg@programming.dev
remove_extension() {
sed -E 's/^(.+)\.[^.]+$/\1/'
}
get_extension() {
sed -E '/^\.?[^.]+$/d; s/^.+\.([^.]*)$/\1/'
}
ffmpeg_av1_opus() {
if [ "$#" -lt 4 ]; then
return
fi
ffmpeg -i "$4" -c:v libsvtav1 -preset "$1" -crf "$2" -c:a libopus -vbr:a 1 -b:a "$3" "${5:-"$(echo "$4" | remove_extension)_ffmpeg_av1_$1_$2_opus_$3.mkv"}"
}
ffmpeg_av1_lossless_flac() {
if [ "$#" -eq 0 ]; then
return
fi
ffmpeg -i "$1" -c:v libsvtav1 -svtav1-params lossless=1 -preset -2 -c:a flac "${2:-"$(echo "$1" | remove_extension)_ffmpeg_av1_lossless_flac.mkv"}"
}
ffmpeg_opus() {
if [ "$#" -lt 2 ]; then
return
fi
ffmpeg -i "$2" -c:a libopus -vbr:a 1 -b:a "$1" "${3:-"$(echo "$2" | remove_extension)_ffmpeg_opus_$1.opus"}"
}
ffmpeg_flac() {
if [ "$#" -eq 0 ]; then
return
fi
ffmpeg -i "$1" -c:a flac "${2:-"$(echo "$1" | remove_extension)_ffmpeg_flac.flac"}"
}
ffmpeg_segment() {
if [ "$#" -lt 2 ]; then
return
fi
ffmpeg -i "$2" -c copy -map 0 -segment_time "$1" -f segment -reset_timestamps 1 "${3:-"$(echo "$2" | remove_extension)_ffmpeg_%04d.$(echo "$2" | get_extension)"}"
}
ffmpeg_concat_auto() {
local files=()
if [ "$#" -eq 0 ]; then
for f in *; do
test -f "$f" && files+=("$f")
done
else
files=("$@")
fi
ffmpeg -f concat -safe 0 -i <(printf "file '$PWD/%s'\n" "${files[@]}") -c copy "$(echo "${files[0]}" | remove_extension | sed -E 's/_ffmpeg_[0-9]+$//').$(echo "${files[0]}" | get_extension)"
}
ffmpeg_concat() {
if [ "$#" -lt 2 ]; then
return
fi
ffmpeg -f concat -safe 0 -i <(printf "file '$PWD/%s'\n" "${@:2}") -c copy "$1"
}
echo_non_ffmpeg() {
while IFS= read -r -d '' f; do
case "$f" in
*ffmpeg_*) ;;
*)
echo "$f"
;;
esac
done < <(find . -type f -print0)
}
remove_non_ffmpeg() {
while IFS= read -r -d '' f; do
case "$f" in
*ffmpeg_*) ;;
*)
rm -f "$f"
;;
esac
done < <(find . -type f -print0)
}
echo_ffmpeg() {
while IFS= read -r -d '' f; do
case "$f" in
*ffmpeg_*)
echo "$f"
;;
*) ;;
esac
done < <(find . -type f -print0)
}
remove_ffmpeg() {
while IFS= read -r -d '' f; do
case "$f" in
*ffmpeg_*)
rm -f "$f"
;;
*) ;;
esac
done < <(find . -type f -print0)
}
mv_space_underscore() {
while IFS= read -r -d '' f; do
new="${f// /_}"
[[ -e "$new" ]] && {
echo "skipping '$f', '$new' exists"
continue
}
mv -- "$f" "$new"
done < <(find . -depth -name '* *' -print0)
}
mv_space_hyphen() {
while IFS= read -r -d '' f; do
new="${f// /-}"
[[ -e "$new" ]] && {
echo "skipping '$f', '$new' exists"
continue
}
mv -- "$f" "$new"
done < <(find . -depth -name '* *' -print0)
}
Edit: Add -vbr:a 1 to opus, thanks to exdor.
Very nice! Will see what I can adapt
I would recommend to always use vbr for opus
There are 2 modes 1 and 2, not sure why, but 1 resulted in smaller files while taking a bit longer so I use that.
How big are these lossless encodes? I expect HUGE? flac is smaller than some weird dolby formats though.
I really like your shell magic for the concatenation, way more efficient than building a filelist.txt
Also really nice way you handle the extension
-vbr0 means CBR (constant bitrate), 1 means normal VBR (variable bitrate), 2 means constrained VBR, and 1 is the default for most build I think.-acis audio channel. 1 is mono, 2 is stereo, 6/8 are 5.1/7.1 surround, so I think I'll keep it unspecified since some movies or Dolby Atmos things use >2 channels.Interesting! Yeah I use ffmpegs default matrix to downmix to stereo to save a lot of data as I dont have a surround system and never will. I prefer to watch movies with good open back headphones and doubt that a surround system will come close.
Thanks for your recommendation.
Regarding lossless encoding, I find flac much smaller than wav, another lossless format, while lossless AV1 is quite huge in size when converting from H264/H265.
Yes wav is uncompressed and flac is lossless compressed. For example an empty wav should be the same size than one with content, while an empty flac would be very small.
Some people in the forums etc convert audio to wav which is really stupid...