added tool to fix deprecated id3 tags in flacs
This commit is contained in:
9
compare_flac_opus
Executable file
9
compare_flac_opus
Executable file
@ -0,0 +1,9 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
flac_dir="${HOME}/flac"
|
||||||
|
opus_dir="${HOME}/opus"
|
||||||
|
#
|
||||||
|
printf 'flacs: %s\n' "$(find "$flac_dir" -name '*.flac' -type f | wc -l)"
|
||||||
|
printf 'opuses: %s\n' "$(find "$opus_dir" -name '*.opus' -type f | wc -l)"
|
||||||
|
# find "$opus_dir" -name '*.opus' -type f | sed -e "s,$opus_dir,$flac_dir," -e 's_\.opus$_\.flac_' | sort -V
|
||||||
|
printf 'diff:\n'
|
||||||
|
diff --suppress-common-lines -y <(find "$flac_dir" -name '*.flac' -type f | sort -V) <(find "$opus_dir" -name '*.opus' -type f | sed -e "s,$opus_dir,$flac_dir," -e 's_\.opus$_\.flac_' | sort -V)
|
16
encode_all
16
encode_all
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
src_library="${HOME}/flac"
|
src_library="${HOME}/flac"
|
||||||
output_dir="${HOME}/opus"
|
output_dir="${HOME}/opus"
|
||||||
|
log="${HOME}/encode_log_$(date '+%Y-%m-%d_%H:%M')"
|
||||||
|
|
||||||
function encode() {
|
function encode() {
|
||||||
file="$1"
|
file="$1"
|
||||||
@ -14,6 +15,9 @@ function encode() {
|
|||||||
file_name="$(basename "$file")"
|
file_name="$(basename "$file")"
|
||||||
final_dir="$(sed "s_${HOME}/flac_${HOME}/opus_" <<< "$src_dir")"
|
final_dir="$(sed "s_${HOME}/flac_${HOME}/opus_" <<< "$src_dir")"
|
||||||
final_opus="$(sed -e 's/\.flac$/.opus/' -e "s_${HOME}/flac_${HOME}/opus_" <<< "$file")"
|
final_opus="$(sed -e 's/\.flac$/.opus/' -e "s_${HOME}/flac_${HOME}/opus_" <<< "$file")"
|
||||||
|
if [[ -f "$final_opus" ]]; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
unset tags
|
unset tags
|
||||||
unset dest_dir
|
unset dest_dir
|
||||||
|
|
||||||
@ -39,17 +43,19 @@ function encode() {
|
|||||||
|
|
||||||
[[ -d "$final_dir" ]] || mkdir -p "$final_dir"
|
[[ -d "$final_dir" ]] || mkdir -p "$final_dir"
|
||||||
if [[ -n "${tags[DISK]}" ]]; then
|
if [[ -n "${tags[DISK]}" ]]; then
|
||||||
opusenc \
|
err="$(opusenc --quiet \
|
||||||
--title "${tags[TITLE]}" --artist "${tags[ARTIST]}" \
|
--title "${tags[TITLE]}" --artist "${tags[ARTIST]}" \
|
||||||
--album "${tags[ALBUM]}" --tracknumber "${tags[TRACKNUMBER]}" \
|
--album "${tags[ALBUM]}" --tracknumber "${tags[TRACKNUMBER]}" \
|
||||||
--date "${tags[DATE]}" --comment "DISK=${tags[DISK]}" "$file" "$final_opus"
|
--date "${tags[DATE]}" --comment "DISK=${tags[DISK]}" "$file" "$final_opus" 2>&1)"
|
||||||
else
|
else
|
||||||
opusenc \
|
err="$(opusenc --quiet \
|
||||||
--title "${tags[TITLE]}" --artist "${tags[ARTIST]}" \
|
--title "${tags[TITLE]}" --artist "${tags[ARTIST]}" \
|
||||||
--album "${tags[ALBUM]}" --tracknumber "${tags[TRACKNUMBER]}" \
|
--album "${tags[ALBUM]}" --tracknumber "${tags[TRACKNUMBER]}" \
|
||||||
--date "${tags[DATE]}" "$file" "$final_opus"
|
--date "${tags[DATE]}" "$file" "$final_opus" 2>&1)"
|
||||||
|
fi
|
||||||
|
if [[ -n "$err" ]]; then
|
||||||
|
printf '%s\n' "$err" >> "$log"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
time find "$src_library" -type f -name '*.flac' -print0 | env_parallel -P 0 -0 --bar encode {}
|
time find "$src_library" -type f -name '*.flac' -print0 | env_parallel -P 0 -0 --bar encode {}
|
||||||
|
107
flac_update_id3
Executable file
107
flac_update_id3
Executable file
@ -0,0 +1,107 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import pathlib
|
||||||
|
import pprint
|
||||||
|
import re
|
||||||
|
import shutil
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
import tempfile
|
||||||
|
|
||||||
|
|
||||||
|
comment_re = re.compile(' comment\[[0-9]+\]: (?P<tag_name>[^=]+)=(?P<tag>.*)')
|
||||||
|
|
||||||
|
|
||||||
|
def run(cmd):
|
||||||
|
p = subprocess.run(cmd, capture_output=True)
|
||||||
|
return (p.stdout.decode('UTF-8'), p.stderr.decode('UTF-8'), p.returncode)
|
||||||
|
|
||||||
|
|
||||||
|
def get_tags(filename):
|
||||||
|
tags = {}
|
||||||
|
cmd = ('/usr/bin/metaflac', '--list', '--block-type=VORBIS_COMMENT', filename)
|
||||||
|
stdout, stderr, exit_code = run(cmd)
|
||||||
|
stdout = stdout.split('\n')
|
||||||
|
logging.debug(f'stdout: {stdout}')
|
||||||
|
logging.debug(f'stderr: {stderr}')
|
||||||
|
logging.debug(f'exit: {exit_code}')
|
||||||
|
if exit_code != 0:
|
||||||
|
sys.exit(stderr)
|
||||||
|
for line in stdout:
|
||||||
|
match = comment_re.search(line)
|
||||||
|
if match:
|
||||||
|
tags[match.group('tag_name')] = match.group('tag')
|
||||||
|
return tags
|
||||||
|
|
||||||
|
|
||||||
|
def writable(filename):
|
||||||
|
return os.access(filename, os.R_OK)
|
||||||
|
|
||||||
|
|
||||||
|
def ffmpeg_encode(input_file, output_file):
|
||||||
|
cmd = ('/usr/bin/ffmpeg', '-loglevel', 'error', '-i', input_file, output_file)
|
||||||
|
stdout, stderr, exit_code = run(cmd)
|
||||||
|
if exit_code != 0:
|
||||||
|
logging.fatal(stderr)
|
||||||
|
|
||||||
|
|
||||||
|
def write_flac(input_wav, tags, output_flac):
|
||||||
|
cmd = ['/usr/bin/flac', '-f', '-s', '--best']
|
||||||
|
tags = [f'{tag_type}={tag}' for tag_type, tag in tags.items()]
|
||||||
|
logging.debug(tags)
|
||||||
|
for tag in tags:
|
||||||
|
cmd.append('-T')
|
||||||
|
cmd.append(tag)
|
||||||
|
cmd.append(input_wav)
|
||||||
|
cmd.append('-o')
|
||||||
|
cmd.append(output_flac)
|
||||||
|
_, stderr, exit_code = run(cmd)
|
||||||
|
if exit_code != 0:
|
||||||
|
sys.exit(stderr)
|
||||||
|
|
||||||
|
|
||||||
|
def replace_original(new, old):
|
||||||
|
try:
|
||||||
|
os.rename(new, old)
|
||||||
|
except:
|
||||||
|
logging.error(f'Failed to replace {old} with {new}.')
|
||||||
|
pprint.pprint(get_tags(old))
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
def main():
|
||||||
|
logging.basicConfig(encoding='utf-8', level=logging.DEBUG)
|
||||||
|
if len(sys.argv) != 2:
|
||||||
|
sys.exit('Give a flac with id3 tags.')
|
||||||
|
|
||||||
|
full_flac = pathlib.Path(sys.argv[1]).resolve()
|
||||||
|
|
||||||
|
if not writable(full_flac):
|
||||||
|
sys.exit(f'{full_flac} is not writable.')
|
||||||
|
|
||||||
|
stem = full_flac.stem
|
||||||
|
file = full_flac.name
|
||||||
|
path = full_flac.parent
|
||||||
|
|
||||||
|
logging.debug(f'stem: {stem}')
|
||||||
|
logging.debug(f'file: {file}')
|
||||||
|
logging.debug(f'path: {path}')
|
||||||
|
tags = get_tags(full_flac)
|
||||||
|
|
||||||
|
with tempfile.TemporaryDirectory(dir='/dev/shm') as working_dir:
|
||||||
|
with tempfile.NamedTemporaryFile(dir=path, delete=False) as temp_flac:
|
||||||
|
full_wav = working_dir / pathlib.Path(stem + '.wav')
|
||||||
|
|
||||||
|
ffmpeg_encode(full_flac, full_wav)
|
||||||
|
write_flac(full_wav.as_posix(), tags, temp_flac.name)
|
||||||
|
cmd = ('/usr/bin/flac', '-t', temp_flac.name)
|
||||||
|
stdout, stderr, exit_code = run(cmd)
|
||||||
|
print(f'stdout: {stdout}')
|
||||||
|
print(f'stderr: {stderr}')
|
||||||
|
print(f'exit code: {exit_code}')
|
||||||
|
pprint.pprint(get_tags(temp_flac.name))
|
||||||
|
replace_original(temp_flac.name, full_flac)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
18
update_all_id3
Executable file
18
update_all_id3
Executable file
@ -0,0 +1,18 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
log_file="$1"
|
||||||
|
|
||||||
|
if [[ -z "$log_file" ]]; then
|
||||||
|
printf 'give a log file from encode_all\n' >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [[ ! -r "$log_file" ]]; then
|
||||||
|
printf '%s isnt a readable log file.\n' "$log_file" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
time while read line; do
|
||||||
|
file="/$(cut -d/ -f2- <<< "$line")"
|
||||||
|
printf '%s\n' "$file"
|
||||||
|
|
||||||
|
done < "$log_file" | parallel -P 0 --bar ./flac_update_id3 {}
|
Reference in New Issue
Block a user