2023-07-04 23:14:53 +02:00
|
|
|
#!/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
|
|
|
|
|
2023-07-05 13:48:37 +02:00
|
|
|
print_help() {
|
|
|
|
printf "Help: not implemented yet"
|
|
|
|
}
|
2023-07-04 23:14:53 +02:00
|
|
|
|
2023-07-08 00:06:12 +02:00
|
|
|
delete="false"
|
2023-07-07 23:23:58 +02:00
|
|
|
while getopts 'e:dh' flag; do
|
2023-07-05 13:48:37 +02:00
|
|
|
case "${flag}" in
|
|
|
|
e) extension+=("$OPTARG");;
|
2023-07-07 23:23:58 +02:00
|
|
|
d) delete="true";;
|
2023-07-05 13:48:37 +02:00
|
|
|
h) print_help
|
|
|
|
exit 0;;
|
|
|
|
*) exit 1 ;;
|
|
|
|
esac
|
2023-07-04 23:14:53 +02:00
|
|
|
done
|
|
|
|
|
2023-07-08 00:06:12 +02:00
|
|
|
echo "$delete"
|
|
|
|
|
2023-07-04 23:14:53 +02:00
|
|
|
# write array into string
|
|
|
|
extension="${extension[*]}"
|
|
|
|
# change separator
|
|
|
|
extension=${extension// /|}
|
|
|
|
|
|
|
|
for file in **/*.@($extension); do
|
|
|
|
|
2023-07-06 23:06:41 +02:00
|
|
|
# array over the number of channels of all streams
|
|
|
|
readarray -t channels <<<"$(ffprobe -v error -select_streams a -show_entries stream=channels -of compact=p=0:nk=1 "$file")"
|
|
|
|
# array over the bitrates of all streams
|
2023-07-07 22:01:04 +02:00
|
|
|
readarray -t bitrates <<<"$(ffprobe -v error -select_streams a -show_entries stream=bit_rate -of compact=p=0:nk=1 "$file")"
|
2023-07-06 23:06:41 +02:00
|
|
|
|
|
|
|
# set a channel dependend bitrate for every audio stream
|
|
|
|
# https://wiki.xiph.org/Opus_Recommended_Settings
|
|
|
|
# to use ffmpegs default just comment out this block
|
2023-07-07 23:23:58 +02:00
|
|
|
for ((index=0; index<${#channels[@]};index++)); do
|
2023-07-06 23:06:41 +02:00
|
|
|
if [[ ${channels[index]} -eq 1 ]]; then
|
2023-07-07 22:01:04 +02:00
|
|
|
if [[ $bitrates == 'N/A' || ${bitrates[index]} -gt 64000 ]]; then bitrate_settings="$bitrate_settings-b:a:$index 64k "; fi
|
2023-07-06 23:06:41 +02:00
|
|
|
elif [[ ${channels[index]} -eq 2 ]]; then
|
2023-07-07 22:01:04 +02:00
|
|
|
if [[ $bitrates == 'N/A' || ${bitrates[index]} -gt 128000 ]]; then bitrate_settings="$bitrate_settings-b:a:$index 128k "; fi
|
2023-07-06 23:06:41 +02:00
|
|
|
elif [[ ${channels[index]} -lt 6 ]]; then
|
2023-07-07 22:01:04 +02:00
|
|
|
if [[ $bitrates == 'N/A' || ${bitrates[index]} -gt 256000 ]]; then bitrate_settings="$bitrate_settings-b:a:$index 256k "; fi
|
|
|
|
elif [[ $bitrates == 'N/A' || ${bitrates[index]} -gt 450000 ]]; then bitrate_settings="$bitrate_settings-b:a:$index 450k "; fi
|
2023-07-06 23:06:41 +02:00
|
|
|
done
|
2023-07-04 23:14:53 +02:00
|
|
|
|
2023-07-07 22:01:04 +02:00
|
|
|
# check if it contains video streams (Thumbnails etc. will be ignored)
|
|
|
|
# use mkv for videos and for multiple audio streams
|
|
|
|
is_video=$(ffprobe -v error -select_streams V -show_entries stream=codec_type "$file")
|
|
|
|
if [[ ${#channels[@]} -gt 1 || -n "$is_video" ]]; then
|
2023-07-07 23:23:58 +02:00
|
|
|
ffmpeg -i "$file" -map 0 -map -0:d -map -0:t -c copy -c:a libopus $bitrate_settings-v info -hide_banner "${file%.*}.mkv" &&
|
2023-07-08 00:06:12 +02:00
|
|
|
if [[ "$delete"=true ]]; then rm "$file"; fi
|
2023-07-04 23:14:53 +02:00
|
|
|
else
|
2023-07-07 23:23:58 +02:00
|
|
|
ffmpeg -i "$file" $bitrate_settings-v info -hide_banner "${file%.*}.opus" &&
|
2023-07-08 00:06:12 +02:00
|
|
|
if [[ "$delete"=true ]]; then rm "$file"; fi
|
2023-07-04 23:14:53 +02:00
|
|
|
fi
|
|
|
|
done
|
|
|
|
|
|
|
|
exit 0
|