feat: add flac2opus_collection.bash
This commit is contained in:
commit
66c860bcc5
2 changed files with 220 additions and 0 deletions
25
README.md
Normal file
25
README.md
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
# scripts
|
||||||
|
|
||||||
|
This repository contains some of my scripts. Feel free to use, modify or share as you wish.
|
||||||
|
Quality of the script and or code might or might not be questionable. I am not responsible
|
||||||
|
for any accidental rimraffing of your home or any other directories nor for any other damage.
|
||||||
|
|
||||||
|
## Index
|
||||||
|
|
||||||
|
### `flac2opus_collection.bash`
|
||||||
|
|
||||||
|
This script converts a copy of a directory containing `.flac` files and converts them all to opus.
|
||||||
|
The source folder remains unmodified and the whole directory structure, including non-flac files, will
|
||||||
|
be simply copied over to the output directory. This serves the purpose of being able to compress
|
||||||
|
your whole lossless library to copy over to devices which are storage limited and or unable to playback
|
||||||
|
the lossless files at a quality where they are distinguishable from the compressed files.
|
||||||
|
|
||||||
|
#### Overview of arguments
|
||||||
|
```
|
||||||
|
arguments:
|
||||||
|
in [input directory] (required) <The flac directory> {default: none}
|
||||||
|
out [output directory] (required) <The opus directory> {default: none}
|
||||||
|
verify [on/off] (optional) <Check converted files for corruption> {default: on}
|
||||||
|
vbr [on/off] (optional) <Toggle variable bit rate> {default: on}
|
||||||
|
bitrate [{bitrate}k] (optional) <Set the bitrate to be passed to ffmpeg> {default: 128k}
|
||||||
|
```
|
195
flac2opus_collection.bash
Executable file
195
flac2opus_collection.bash
Executable file
|
@ -0,0 +1,195 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# This code is thrown together lazily to just work and never be touched again.
|
||||||
|
# Do NOT try to learn from this piece of shit
|
||||||
|
|
||||||
|
check_dep() {
|
||||||
|
if [ -z "$(command -v "$1")" ]; then
|
||||||
|
echo "'$1' is required but not installed."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
check_deps() {
|
||||||
|
deps=("ffmpeg" "opusinfo" "xargs")
|
||||||
|
for dep in "${deps[@]}"; do
|
||||||
|
check_dep "$dep"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
args() {
|
||||||
|
while [ -n "$1" ];do
|
||||||
|
case "$1" in
|
||||||
|
"help")
|
||||||
|
printf "\n\
|
||||||
|
arguments:\n\
|
||||||
|
in [input directory] (required) <The flac directory> {default: none}\n\
|
||||||
|
out [output directory] (required) <The opus directory> {default: none}\n\
|
||||||
|
verify [on/off] (optional) <Check converted files for corruption> {default: on}
|
||||||
|
vbr [on/off] (optional) <Toggle variable bit rate> {default: on}
|
||||||
|
bitrate [{bitrate}k] (optional) <Set the bitrate to be passed to ffmpeg> {default: 128k}\n\n"
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
"in")
|
||||||
|
if [ -z "$2" ]; then
|
||||||
|
echo "option '$1' requires an additional argument."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
INPUT_DIR="$(realpath "$2")"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
"out")
|
||||||
|
if [ -z "$2" ]; then
|
||||||
|
echo "option '$1' requires an additional argument."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
OUTPUT_DIR="$(realpath "$2")"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
"vbr")
|
||||||
|
if [ -z "$2" ]; then
|
||||||
|
echo "option '$1' requires an additional argument."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$2" != "on" ] && [ "$2" != "off" ]; then
|
||||||
|
echo "Invalid option '$2' for $1. Only accepted options are 'on' or 'off'."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
VBR="$2"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
"verify")
|
||||||
|
if [ -z "$2" ]; then
|
||||||
|
echo "option '$1' requires an additional argument."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$2" != "on" ] && [ "$2" != "off" ]; then
|
||||||
|
echo "Invalid option '$2' for $1. Only accepted options are 'on' or 'off'."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
VERIFY="$2"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
"bitrate")
|
||||||
|
if [ -z "$2" ]; then
|
||||||
|
echo "option '$1' requires an additional argument."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
BITRATE="$2"
|
||||||
|
if [[ ! $2 =~ ^[0-9]+k$ ]]; then
|
||||||
|
echo "Invalid bitrate '$2', only accepts string matching pattern '[0-9]\\+k'"
|
||||||
|
fi
|
||||||
|
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Invalid argument '$1', skipping"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -z "$INPUT_DIR" ]; then
|
||||||
|
echo "Missing input directory"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$OUTPUT_DIR" ]; then
|
||||||
|
echo "Missing input directory"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$BITRATE" ]; then
|
||||||
|
BITRATE="128k"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$VBR" ]; then
|
||||||
|
VBR="on"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$VERIFY" ]; then
|
||||||
|
VERIFY="on"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
get_total_count() {
|
||||||
|
local -n ref_total_count="$2"
|
||||||
|
total_count="$ref_total_count"
|
||||||
|
|
||||||
|
local dir="$1"
|
||||||
|
for item in "$dir"/*; do
|
||||||
|
if [ -f "$item" ]; then
|
||||||
|
new_file="${item/"$INPUT_DIR"/"$OUTPUT_DIR"}"
|
||||||
|
new_file="${new_file/".flac"/".opus"}"
|
||||||
|
if [ ! -f "$new_file" ] && [[ "$item" == *".flac" ]]; then
|
||||||
|
((total_count+=1))
|
||||||
|
elif [[ "$item" == *".flac" ]]; then
|
||||||
|
if [ "$VERIFY" = "on" ]; then
|
||||||
|
printf "Checking \e[93m'%s'\e[0m: " "$(basename "$new_file")"
|
||||||
|
if ! opusinfo "$new_file" > /dev/null 2>&1; then
|
||||||
|
((total_count+=1))
|
||||||
|
printf "\e[31mbad\e[0m\n"
|
||||||
|
rm "$new_file"
|
||||||
|
else
|
||||||
|
printf "\e[32mgood\e[0m\n"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
elif [ -d "$item" ]; then
|
||||||
|
get_total_count "$item" "total_count"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
iterate_dirs() {
|
||||||
|
local dir="$1"
|
||||||
|
local conversions=()
|
||||||
|
local -n ref_count="$2"
|
||||||
|
local total_count="$3"
|
||||||
|
count="$ref_count"
|
||||||
|
for item in "$dir"/*; do
|
||||||
|
item="${item/\$/"\\$"}"
|
||||||
|
if [ -f "$item" ]; then
|
||||||
|
new_file="${item/"$INPUT_DIR"/"$OUTPUT_DIR"}"
|
||||||
|
new_file="${new_file/".flac"/".opus"}"
|
||||||
|
if [ ! -f "$new_file" ]; then
|
||||||
|
if [[ "$item" == *".flac" ]]; then
|
||||||
|
((count+=1))
|
||||||
|
conversions+=("printf '[%s/%s] \e[92m%s\e[0m -> \e[93m%s\e[0m\n' $count $total_count \
|
||||||
|
\"$item\" \"$new_file\" && ffmpeg -hide_banner -loglevel error -i \"$item\" -vbr \"$VBR\" -b:a \"$BITRATE\" \"$new_file\" > /dev/null")
|
||||||
|
else
|
||||||
|
echo "Copied $(basename "$item")"
|
||||||
|
cp -f "$item" "$new_file"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
elif [ -d "$item" ]; then
|
||||||
|
new_dir="${item/"$INPUT_DIR"/"$OUTPUT_DIR"}"
|
||||||
|
mkdir -p "$new_dir"
|
||||||
|
iterate_dirs "$item" "count" "$total_count"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ ${#conversions[@]} -gt 0 ]; then
|
||||||
|
printf '%s\0' "${conversions[@]}" | xargs -0 -P "$(nproc)" -I {} bash -c '{}'
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
main () {
|
||||||
|
check_deps
|
||||||
|
|
||||||
|
args "$@"
|
||||||
|
|
||||||
|
count="0"
|
||||||
|
total_count="0"
|
||||||
|
get_total_count "$INPUT_DIR" "total_count"
|
||||||
|
iterate_dirs "$INPUT_DIR" "count" "$total_count"
|
||||||
|
}
|
||||||
|
|
||||||
|
set -e
|
||||||
|
main "$@"
|
||||||
|
|
Loading…
Reference in a new issue