#!/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[^=]+)=(?P.*)') 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()