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