media-tools/to_opus.sh

79 lines
2.1 KiB
Bash

#!/bin/bash
# set shopt-options used by this shell-script
# Note, 0 (true) from shopt -q is "false" in a math context.
shopt -q globstar; globstar_set=$?
((globstar_set)) && shopt -s globstar
shopt -q extglob; extglob_set=$?
((extglob_set)) && shopt -s extglob
# return default shopt-options
function finish {
((globstar_set)) && shopt -u globstar
((extglob_set)) && shopt -u extglob
}
trap finish EXIT
print_help() {
printf "Help: not implemented yet"
}
while getopts 'e:' flag; do
case "${flag}" in
e) extension+=("$OPTARG");;
h) print_help
exit 0;;
*) exit 1 ;;
esac
done
# write array into string
extension="${extension[*]}"
# remove leading space
extension="${extension##+([[:space:]])}"
# change separator
extension=${extension// /|}
for file in **/*.@($extension); do
#set a channel-dependent bitrate for every audio stream
command=$(
ffprobe "$file" -v 0 -show_entries stream=channels,bit_rate -select_streams a -of compact=p=0:nk=1:s="\ " |
awk -v file="$file" -v file_output="${file%.*}.opus" '
BEGIN{
ORS=" ";
print "ffmpeg -i \""file"\" -map 0:a -c:a libopus"
}
{ # https://wiki.xiph.org/Opus_Recommended_Settings
if($1==1) {
if($2>=64000) print "-b:a:"NR-1" 64k"
}
else if($1==2) {
if($2>=128000) print "-b:a:"NR-1" 128k"
}
else if($1<=6) {
if ($2>=256000) print "-b:a:"NR-1" 256k"
}
else if ($2>=450000) print "-b:a:"NR-1" 450k"
}
END{
print "\""file_output"\" -v info -hide_banner"
}')
is_video=$(ffprobe -i Hair.m4v -v fatal -select_streams V -show_entries stream=codec_type)
if [[ -n "$is_video" ]]; then
echo "$file contains a video stream and will not be converted"
#an Example for converting the audiostreams in a container while copying subtitles and videostreams.
#ffmpeg -i Hair.m4v -map 0:a -map 0:s -map 0:v -c:a libopus -c:v copy -c:s copy Hair.mkv -hide_banner -v info
#for extracting the audiostreams of a video file just use "eval "$command"".
#it is recommended to check the result before deleting the original file.
else
eval "$command" #&& rm "$file"
fi
done
exit 0