Add project skeleton: CLI pipeline for CD digitization
Modular Python package with Typer CLI (scan/apply/process commands), Pydantic data models, OCR via Tesseract, LLM-based tracklist parsing, mutagen audio tagging, M3U playlist generation, and cover processing. Includes 8 passing tests and ruff lint config. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
225f6b3dbf
commit
3e073250ca
17 changed files with 1027 additions and 0 deletions
57
src/musiksammlung/ripper.py
Normal file
57
src/musiksammlung/ripper.py
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
"""CD-Ripping via abcde."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def rip_disc(
|
||||
device: str,
|
||||
output_dir: Path,
|
||||
audio_format: str = "flac",
|
||||
eject: bool = True,
|
||||
) -> Path:
|
||||
"""Rippt eine CD mit abcde in output_dir.
|
||||
|
||||
Args:
|
||||
device: CD-Laufwerk, z.B. '/dev/cdrom'
|
||||
output_dir: Zielverzeichnis für die gerippten Dateien
|
||||
audio_format: Ausgabeformat (flac, mp3, ogg, opus)
|
||||
eject: CD nach dem Rippen auswerfen
|
||||
|
||||
Returns:
|
||||
Pfad zum Verzeichnis mit den gerippten Dateien
|
||||
"""
|
||||
output_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
cmd = [
|
||||
"abcde",
|
||||
"-n", # kein CDDB-Lookup
|
||||
"-N", # non-interaktiv
|
||||
"-p", # führende Nullen bei Tracknummern
|
||||
"-o", audio_format,
|
||||
"-d", device,
|
||||
"-D", # kein Debug
|
||||
]
|
||||
if eject:
|
||||
cmd.append("-x")
|
||||
|
||||
logger.info("Starte Ripping: %s", " ".join(cmd))
|
||||
|
||||
result = subprocess.run(
|
||||
cmd,
|
||||
cwd=str(output_dir),
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
|
||||
if result.returncode != 0:
|
||||
logger.error("abcde Fehler: %s", result.stderr)
|
||||
raise RuntimeError(f"abcde fehlgeschlagen (exit {result.returncode}): {result.stderr}")
|
||||
|
||||
logger.info("Ripping abgeschlossen: %s", output_dir)
|
||||
return output_dir
|
||||
Loading…
Add table
Add a link
Reference in a new issue