Compare commits

...

5 Commits
v1.4.7 ... main

Author SHA1 Message Date
yosh 1253d60e45 better diagnostic output 2024-02-02 17:33:25 -05:00
yosh 9fbbc2fbb6 don't bother with symlinks when updating 2024-02-02 17:28:08 -05:00
yosh 66ffa456eb aaaaaa why I use printf and not errecho for those 2024-02-02 12:48:50 -05:00
yosh 201a3916cd oops update readme 2024-02-02 12:40:13 -05:00
yosh 513267edab a lot of changes, some breaking. see extended comment
- no more "releases". they don't work well for a shell script of this small scope
- updates are checked against latest commit, and can be applied automatically
  if  the user doesn't have git installed
- for real now, the script will not automatically convert and rather show usage
  if a directory isn't entered. I accidentally ran the script once and had
  like 30 opus files spew out and had not a fun time cleaning it up
- for some reason, while I made a comment about not supporting filenames
  with newlines, I never had a user-friendly notification or check for this.
  now I do! so it'll notify you if the filepath has a newline in it
- keepkeys and removekeys can be comma separated instead of pipe separated now.
  a bit friendlier to type now. you can still use pipes and it works fine!
2024-02-01 23:26:03 -05:00
2 changed files with 62 additions and 33 deletions

View File

@ -1,25 +1,25 @@
# flacconv
flacconv is a (hopefully) 100% POSIX and portable[^1] shell script that recursively converts directories of flac files to opus/mp3.
flacconv is a 100% POSIX and (hopefully) 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
with no flags, it recursively converts flac files in the specified directory (or directories) to opus with a bitrate of 128k, retaining all metadata and not deleting the original flac files
it also has options for you to change the bitrate, use a variable quality for mp3, keep/remove metadata, and parallel processing
## 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`
- `flac` and `metaflac` (usually bundled together)
- `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)
- [`opustags`](https://github.com/fmang/opustags) (optional, to use the -e option)
- `curl` (optional, for checking for updates)
## usage
```
usage: flacconv [-huvVipe3] [-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
DIRECTORY can be specified multiple times
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)
@ -36,15 +36,15 @@ IF ENCODING TO MP3, -k AND -r WILL NOT WORK. the only metadata that will be kept
-l <LEVEL> mp3 only: use specified mp3 variable quality (0-9). integer only
OVERRIDES -b
-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')
keys can be seen using metaflac --export-tags-to=- file.flac
argument is a comma or pipe-separated list of keys, case-insensitive
(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" (with capitalization), all keys are removed
-p remove embedded picture in output files
-e remove the "encoder" tags that automatically gets applied with opusenc
-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
@ -57,14 +57,14 @@ recursively convert a directory of flacs to opus 128k, removing the picture and
recursively convert the current directory to mp3 320k
`flacconv -b 320 -3`
`flacconv -b 320 -3 .`
recursively convert current directory to opus 160k, while removing any COMMENT or DESCRIPTION tags
`flacconv -b 160 -r "COMMENT|DESCRIPTION"`
`flacconv -b 160 -r comment,description .`
recursively convert current directory to mp3 v0, removing all pictures
`flacconv -3 -l 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,5 @@
#!/bin/sh
VERSION=1.4.6
RED="$(printf '\033[38;5;9m')"
GREEN="$(printf '\033[38;5;10m')"
YELLOW="$(printf '\033[38;5;11m')"
@ -9,14 +8,12 @@ set -euf
BN="${0##*/}"
NL='
'
export POSIXLY_CORRECT=1
if [ -n "${NO_COLOR:-}" ]; then
RED="" GREEN="" YELLOW="" RESET=""
fi
errecho() {
>&2 echo "$*$RESET"
>&2 printf '%s\n' "$*$RESET"
}
fail() {
@ -28,15 +25,43 @@ warn() {
errecho "${YELLOW}warning: $BN: $*"
if [ -z "$IGNOREWARNINGS" ]; then
errecho 'you can ignore stopping for warnings in the future with -i'
errecho 'press enter to continue, or C-c to quit'
errecho 'press enter to continue, or Ctrl-c to quit'
read -r __
fi
}
cleanup() {
[ -f "${tmpupdate:-}" ] && rm "$tmpupdate"
:
}
trap "cleanup" INT HUP QUIT TERM EXIT
checkupdate() {
errecho "you are running version ${GREEN}${VERSION}"
errecho "until I learn if forgejo has an equivalent for github's latest release download shenanigans just check to see if this version matches the latest release"
errecho "https://git.unix.dog/yosh/flacconv/releases/latest"
errecho "checking for updates from https://git.unix.dog/yosh/flacconv/src/branch/main/flacconv..."
errecho
tmpupdate=$(mktemp)
curl -s -o "$tmpupdate" 'https://git.unix.dog/yosh/flacconv/raw/branch/main/flacconv' || fail "curl request failed! retry probably"
if cmp -s "$tmpupdate" "$0"; then
errecho "you are updated!"
else
errecho "the latest commit differs from the current version. if you use git, please git pull the repo for the update"
errecho "you can see the changes here: https://git.unix.dog/yosh/flacconv/commits/branch/main"
printf '%s' "if you don't use git, apply update directly? [y/n] " >&2
read -r choice
case "$choice" in
[Yy])
if [ -L "$0" ]; then
errecho "${RED}your flacconv patch is a symbolic link."
errecho "while it is possible to resolve them in a POSIX manner, it's a weird amount of code"
errecho "so I humbly ask that you update it manually"
exit 1
fi
mv -f "$tmpupdate" "$0"
errecho "updated!"
;;
*) errecho "not applying update!" ;;
esac
fi
exit 0
}
@ -155,11 +180,10 @@ process_file() {
usage() {
cat >&2 <<-EOF
flacconv $VERSION
usage: $BN [-huvVipe3] [-b BITRATE] [-l LEVEL] [-k KEYS] [-r KEYS] [-j THREADS] [--] [DIRECTORY...]
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
DIRECTORY can be specified multiple times
by default, this script outputs opus with variable bitrate 128k
${RED}IF ENCODING TO MP3, -k AND -r WILL NOT WORK.${RESET} the only metadata that will be kept is the following:
${YELLOW}TITLE, ARTIST, ALBUM, ALBUMARTIST, DATE, GENRE, TRACKNUMBER, COMMENT, and the cover picture${RESET}
@ -177,9 +201,9 @@ usage() {
-l <LEVEL> mp3 only: use specified mp3 variable quality (0-9). integer only
${YELLOW}OVERRIDES -b${RESET}
-k <KEYS> keep specified flac metadata KEYS in output file
keys can be checked with metaflac --export-tags-to=- FILE
option argument is a ${YELLOW}PIPE-separated${RESET} list of keys to keep, case-insensitive
(i.e. -k "artist|title|albumartist|album|date")
keys can be seen using metaflac --export-tags-to=- file.flac
argument is a ${YELLOW}comma or pipe-separated${RESET} list of keys, case-insensitive
(i.e. -k "artist,title,albumartist,album,date")
${YELLOW}if both -k and -r are not present, all keys are kept.${RESET}
-r <KEYS> remove specified flac metadata KEYS in output file
option argument is of the same format as -k
@ -219,8 +243,8 @@ while getopts :huvVid3peb:l:k:r:j: OPT; do
e) RMENCTAG=1 ;;
b) BITRATE="$OPTARG" ;;
l) VLVL="$OPTARG" ;;
k) KEEPKEYS="$OPTARG" ;;
r) REMOVEKEYS="$OPTARG" ;;
k) KEEPKEYS="$(printf '%s' "$OPTARG" | tr ',' '|')" ;;
r) REMOVEKEYS="$(printf '%s' "$OPTARG" | tr ',' '|')" ;;
j) THREADS="$OPTARG" ;;
*) fail "unknown option: -$OPTARG. run $BN -h to see all options" ;;
esac
@ -237,8 +261,8 @@ else
fi
[ -n "$RMENCTAG" ] && { command -v opustags 1>/dev/null 2>&1 || fail 'opustags is not installed! this is required for -e (opustags)' ; }
# if no arg provided, use cwd
[ "$#" -eq 0 ] && set -- .
# if no directory provided, show usage
[ "$#" -eq 0 ] && usage && errecho "${NL}to convert the current working directory, use \"flacconv .\"" && exit 1
# this script assumes you aren't using newlines in path names
# I do not want to change it to account for this
FLACFILES="$(find "$@" -type f -name "*.[fF][lL][aA][cC]")"
@ -271,7 +295,12 @@ run_in_parallel() {
errecho "${YELLOW}using ${RESET}$THREADS${YELLOW} threads"
mk_parallel_fd
while read -r file; do
run_in_parallel process_file "$file"
if ! [ -f "$file" ]; then
errecho "${YELLOW}skipping the file ${RESET}"$file"${YELLOW} because it doesn't exist."
errecho "${YELLOW}this most likely means you have a newline in the pathname. fix that!"
continue
fi
run_in_parallel process_file "$file"
done <<-EOF
$FLACFILES
EOF