1
0

pkgs/convert-flac-dir-to-mp3: Add script for coverting music libraries

This commit is contained in:
2025-09-21 17:06:36 +02:00
parent 23629e0662
commit ce99bb114b
3 changed files with 105 additions and 0 deletions

View File

@@ -0,0 +1,96 @@
#!/usr/bin/env python
import argparse
from pathlib import Path
from progress.bar import Bar
import shutil
import subprocess
def files_and_dirs_for_directory(path):
filepaths = []
dirpaths = []
for dirpath, dirnames, filenames in path.walk():
dirpaths.append(dirpath)
for filename in filenames:
filepath = dirpath / filename
filepaths.append(filepath)
return set(filepaths), set(dirpaths)
def make_paths_relative(paths, relative_to_path):
return set(path.relative_to(relative_to_path) for path in paths)
def replace_suffix(path, suffix):
return path.with_name(path.stem + suffix)
def convert_filepath(path):
if path.suffix == ".flac":
return replace_suffix(path, ".mp3")
return path
def ffmpeg_flac_to_mp3(in_path, out_path):
print("")
subprocess.run(["ffmpeg", "-hide_banner", "-loglevel", "warning", "-stats", "-i", in_path, "-ab", "320k", "-map_metadata", "0", "-id3v2_version", "3", out_path], check=True)
print("")
if __name__ == "__main__":
parser = argparse.ArgumentParser(prog="convert-flac-dir-to-mp3")
parser.add_argument("from_dir", type=Path)
parser.add_argument("to_dir", type=Path)
args = parser.parse_args()
from_path = args.from_dir.absolute()
to_path = args.to_dir.absolute()
if not from_path.exists():
raise Exception("from_path does not exist")
if not to_path.exists():
raise Exception("to_path does not exist")
if not from_path.is_dir():
raise Exception("from_path is not a directory")
if not to_path.is_dir():
raise Exception("to_path is not a directory")
print(f"Converting {from_path} to {to_path}")
from_filepaths, from_dirpaths = files_and_dirs_for_directory(from_path)
to_filepaths, to_dirpaths = files_and_dirs_for_directory(to_path)
relative_from_filepaths = make_paths_relative(from_filepaths, from_path)
relative_to_filepaths = make_paths_relative(to_filepaths, to_path)
converted_from_filepaths = set(convert_filepath(filepath) for filepath in relative_from_filepaths)
filepaths_missing_in_to_path = converted_from_filepaths - relative_to_filepaths
relative_from_dirpaths = make_paths_relative(from_dirpaths, from_path)
relative_to_dirpaths = make_paths_relative(to_dirpaths, to_path)
dirpaths_missing_in_to_path = relative_from_dirpaths - relative_to_dirpaths
print(f"Missing {len(filepaths_missing_in_to_path)} files and {len(dirpaths_missing_in_to_path)} directories")
if len(dirpaths_missing_in_to_path) > 0:
for dirpath in Bar("Creating directories").iter(dirpaths_missing_in_to_path):
(to_path / dirpath).mkdir(parents=True, exist_ok=True)
if len(filepaths_missing_in_to_path) > 0:
for filepath in Bar("Creating files").iter(filepaths_missing_in_to_path):
if filepath in relative_from_filepaths:
# Just copy the file
shutil.copy(from_path / filepath, to_path / filepath)
elif filepath.suffix == ".mp3" and replace_suffix(filepath, ".flac") in relative_from_filepaths:
# Convert from flac
ffmpeg_flac_to_mp3(from_path / replace_suffix(filepath, ".flac"), to_path / filepath)
else:
raise Exception("Unable to figure out how to get {to_path / filepath} from {from_path}")