1.4.0 updates

This commit is contained in:
yosh 2023-04-12 12:41:47 -04:00
parent 6bb63d9d74
commit c936bcb704
2 changed files with 40 additions and 27 deletions

View File

@ -1,5 +1,5 @@
# flacconv
flacconv is a 100% POSIX[^1] shell script that recursively converts directories of flac files to opus/mp3.
flacconv is a (hopefully) 100% POSIX and portable[^1] shell script that recursively converts directories of flac files to opus/mp3.
when invoked with no arguments, it recursively converts the current directory's flac files to opus with a bitrate of 128k, retaining all metadata and not deleting the original flac files
@ -7,15 +7,19 @@ it also has options for you to change the bitrate, use a variable quality for mp
## dependencies
- Some implementation of a shell and [POSIX Utilities](https://pubs.opengroup.org/onlinepubs/9699919799/idx/utilities.html) (usually, this is GNU coreutils, which you probably have)
- `mktemp -u` (again, probably have this already)
- `flac`
- `lame` (required for mp3, not required otherwise)
- `opus-tools` (required for opus, not required otherwise)
- `lame` (only if encoding to mp3)
- `opus-tools` (only if encoding to opus)
- [opustags](https://github.com/fmang/opustags) (optional, to use the -e option)
- `curl` (optional, for checking for updates)
## usage
```
usage: flacconv [-huvVip3] [-b BITRATE] [-l LEVEL] [-k KEYS] [-r KEYS] [-j THREADS] [--] [DIRECTORY...]
usage: flacconv [-huvVipe3] [-b BITRATE] [-l LEVEL] [-k KEYS] [-r KEYS] [-j THREADS] [--] [DIRECTORY...]
flacconv recursively converts directories of flac files to opus/mp3
DIRECTORY can be specified multiple times. if omitted, the current directory is used
by default, this script outputs opus with variable bitrate 128k
IF ENCODING TO MP3, -k AND -r WILL NOT WORK. the only metadata that will be kept is the following:
TITLE, ARTIST, ALBUM, ALBUMARTIST, DATE, GENRE, TRACKNUMBER, COMMENT, and the cover picture
(blame id3. just use opus)
@ -38,16 +42,18 @@ IF ENCODING TO MP3, -k AND -r WILL NOT WORK. the only metadata that will be kept
if both -k and -r are not present, all keys are kept.
-r <KEYS> remove specified flac metadata KEYS in output file
option argument is of the same format as -k
if set to 'ALL', all keys are removed
if set to "ALL" (with capitalization), all keys are removed
-p remove embedded picture in output files
-e remove the "encoder" tags that automatically gets applied with opusenc
(requires opustags)
-j <THREADS> use the specified amount of threads for parallel processing
if omitted, CPU core count will be used
```
## examples
recursively convert a directory of flacs to opus 128k, removing the picture for every one
recursively convert a directory of flacs to opus 128k, removing the picture and ENCODER tags for every file
`flacconv -p /path/to/dir`
`flacconv -p -e /path/to/dir`
recursively convert the current directory to mp3 320k
@ -59,6 +65,6 @@ recursively convert current directory to opus 160k, while removing any COMMENT o
recursively convert current directory to mp3 v0, removing all pictures
`flacconv -3 -v 0 -p`
`flacconv -3 -l 0 -p`
[^1]: tested with dash, bash, and yash (set -o posixly-correct) on linux. further testing encouraged

View File

@ -1,6 +1,6 @@
#!/bin/sh
# flacconv 1.3.2 // use https://github.com/yoshiyoshyosh/flacconv for issues
# flacconv 1.4.0 // use https://github.com/yoshiyoshyosh/flacconv for issues
set -euf
BN="${0##*/}"
@ -18,11 +18,11 @@ if [ "${NO_COLOR:-}" ]; then
fi
errecho() {
>&2 echo "$@""$RESET"
>&2 echo "$*$RESET"
}
fail() {
errecho "${RED}error: $BN: $*"
errecho "${RED}error: $BN: $RESET$*"
exit 1
}
@ -90,7 +90,6 @@ _mp3enc() {
"${infile%.*}.mp3"
}
# some code reused from https://gist.github.com/berturion/5377d6653ef93049f4ff54cff2003e11#file-flac2opus-sh
process_file() {
infile="$1"
bname="${infile##*/}"
@ -106,13 +105,13 @@ process_file() {
if [ "$head_bytes" = "ID3" ]; then
warn "invalid id3 tags found in $infile, you should get that fixed!"
# in a previous version this would remove invalid id3 tags automatically
# I have since realized that this is outside the scope of this program
# I have since realized that this is outside the scope of this script
# additionally, some people may have tags only in the id3 values, and as
# such would be lost forever if removed automatically
# therefore, this script only detects id3 tags and alterts the user
fi
# now test if keepkeys or whatever was used, set exported tags
# now test if keepkeys or removekeys was used, set exported tags
if [ "$KEEPKEYS" ]; then
tagnames="$(printf '%s' "$tagnames" | grep -i -E "^$KEEPKEYS")"
fi
@ -130,7 +129,6 @@ process_file() {
# time to encode
if [ "$TYPE" = "opus" ]; then
VLVL=
opustags=""
# build opus comment chain, can't "import" tags like with flac
set --
[ "$tagnames" ] && while read -r name; do
@ -152,6 +150,9 @@ process_file() {
else
_opusenc "$@" 1>/dev/null 2>&1 || convwarn
fi
# remove encoding metadata
[ "$RMENCTAG" ] && opustags -d ENCODER -d ENCODER_OPTIONS -i "${infile%.*}.opus"
else
album="$(metaflac --show-tag=album "$infile")"
artist="$(metaflac --show-tag=artist "$infile")"
@ -169,15 +170,16 @@ process_file() {
_mp3enc 1>/dev/null 2>&1 || convwarn
fi
fi
[ "${pic:-}" ] && rm -f "$pic"
[ -z "${err:-}" ] && errecho "$infile ${GREEN}successfully converted to ${RESET}$TYPE${GREEN} with bitrate/quality ${RESET}${VLVL:-${BITRATE}k}"
[ -z "$DELETE" ] || rm -f "$infile"
[ "$DELETE" ] && rm -f "$infile"
[ "${err:-}" ] || errecho "$infile ${GREEN}successfully converted to ${RESET}$TYPE${GREEN} with bitrate/quality ${RESET}${VLVL:-${BITRATE}k}"
}
usage() {
errecho \
"usage: $BN [-huvVip3] [-b BITRATE] [-l LEVEL] [-k KEYS] [-r KEYS] [-j THREADS] [--] [DIRECTORY...]
$BN recursively converts directories of flac files to opus/mp3
'usage: '"$BN"' [-huvVipe3] [-b BITRATE] [-l LEVEL] [-k KEYS] [-r KEYS] [-j THREADS] [--] [DIRECTORY...]
'"$BN"' recursively converts directories of flac files to opus/mp3
DIRECTORY can be specified multiple times. if omitted, the current directory is used
by default, this script outputs opus with variable bitrate 128k
IF ENCODING TO MP3, -k AND -r WILL NOT WORK. the only metadata that will be kept is the following:
@ -198,14 +200,16 @@ IF ENCODING TO MP3, -k AND -r WILL NOT WORK. the only metadata that will be kept
-k <KEYS> keep specified flac metadata KEYS in output file
keys can be checked with metaflac --export-tags-to=- FILE
option argument is a PIPE-separated list of keys to keep, case-insensitive
(i.e. -k 'artist|title|albumartist|album|date')
(i.e. -k '\''artist|title|albumartist|album|date'\'')
if both -k and -r are not present, all keys are kept.
-r <KEYS> remove specified flac metadata KEYS in output file
option argument is of the same format as -k
if set to 'ALL', all keys are removed
if set to "ALL" (with capitalization), all keys are removed
-p remove embedded picture in output files
-e remove the "encoder" tag that automatically gets applied with opusenc
(requires opustags)
-j <THREADS> use the specified amount of threads for parallel processing
if omitted, CPU core count will be used"
if omitted, CPU core count will be used'
}
VERBOSE=
@ -215,13 +219,15 @@ TYPE=opus
BITRATE=128
VLVL=
RMPIC=
RMENCTAG=
KEEPKEYS=
REMOVEKEYS=
IGNOREWARNINGS=
THREADS="$(getconf _NPROCESSORS_ONLN 2>/dev/null || getconf NPROCESSORS_ONLN)" # linux & freebsd compat I think
THREADS="$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || getconf _NPROCESSORS_ONLN 2>/dev/null)" # hopefully portable enough to not be an issue
! [ $? ] && warn 'unable to find number of cores! defaulting to 1 thread unless otherwise specified...' && THREADS=1
_tempdir # set temp dir
while getopts :huvVid3pb:l:k:r:j: OPT; do
while getopts :huvVid3peb:l:k:r:j: OPT; do
case "$OPT" in
h) usage && exit 0 ;;
u) checkupdate ;;
@ -231,6 +237,7 @@ while getopts :huvVid3pb:l:k:r:j: OPT; do
d) DELETE=1 ;;
3) TYPE=mp3 ;;
p) RMPIC=1 ;;
e) RMENCTAG=1 ;;
b) BITRATE="$OPTARG" ;;
l) VLVL="$OPTARG" ;;
k) KEEPKEYS="$OPTARG" ;;
@ -243,10 +250,9 @@ shift "$((OPTIND - 1))"
[ "$REALLYVERBOSE" ] && set -x
command -v metaflac 1>/dev/null 2>&1 || fail 'flac tools are not installed! (metaflac)'
[ $TYPE = "mp3" ] && { command -v lame 1>/dev/null 2>&1 || fail 'lame is not installed!' ; }
[ $TYPE = "mp3" ] && { command -v lame 1>/dev/null 2>&1 || fail 'lame is not installed! (lame)' ; }
[ $TYPE = "opus" ] && { command -v opusenc 1>/dev/null 2>&1 || fail 'opus-tools is not installed! (opusenc)' ; }
{ [ "$KEEPKEYS" ] && [ "$REMOVEKEYS" ]; } && fail 'don'\''t use -k and -r in the same call!'
[ $RMENCTAG ] && { command -v opustags 1>/dev/null 2>&1 || fail 'opustags is not installed! this is required for -e (opustags)' ; }
# this script assumes you aren't using newlines in path names
# I do not want to change it to account for this
@ -279,6 +285,7 @@ run_in_parallel() {
} &
}
errecho "${YELLOW}using ${RESET}$THREADS${YELLOW} threads"
mk_parallel_fd
while read -r file; do
run_in_parallel process_file "$file"