96 lines
3.7 KiB
Markdown
96 lines
3.7 KiB
Markdown
# Beautify Audio
|
||
|
||
One-file CLI to make tracks library-ready: convert to 320 kbps MP3, wipe old tags, retag via OneTagger Auto Tag, and rename to `Artist - Title.mp3` with collision safety.
|
||
|
||
What it does:
|
||
- Converts any ffmpeg-readable source to 44.1 kHz stereo 320 kbps CBR MP3 (optional loudness normalization, default -11.5 LUFS).
|
||
- Strips existing metadata before retagging.
|
||
- Runs OneTagger Auto Tag with `onetagger-autotagger.json` (Discogs/Spotify creds can be injected).
|
||
- Renames the result using tagged artist/title; appends `-1`, `-2`, etc. to avoid overwrites.
|
||
|
||
## Quick start
|
||
1) Install Python deps: `pip install -r requirements.txt`
|
||
2) Install `ffmpeg` and ensure it is on PATH.
|
||
3) Install OneTagger CLI (≥1.7). On macOS, build from source and place the resulting `onetagger-cli` on PATH or next to this script. https://github.com/OneTagger/OneTagger
|
||
4) Run: `python beautify-audio.py /path/to/track.wav`
|
||
|
||
## Requirements
|
||
- Python 3.9+.
|
||
- `ffmpeg` on PATH.
|
||
- Python deps from `requirements.txt` (currently `mutagen`).
|
||
- OneTagger CLI on PATH or placed next to the script as `onetagger-cli` (not bundled here because it is GPL-licensed). The Auto Tag profile is provided as `onetagger-autotagger.json`.
|
||
- The helper module `onetagger_integration.py` must remain in the repo root (the script prepends the parent dir to `PYTHONPATH`).
|
||
|
||
## Usage
|
||
```bash
|
||
python beautify-audio.py /path/to/track.wav
|
||
```
|
||
|
||
Useful flags:
|
||
- `--output-dir DIR` – where to place the processed MP3 (default: source folder).
|
||
- `--lufs -9.5` – change loudness target; use `--no-loudness` to disable normalization.
|
||
- `--artist/--title/--album` – seed metadata hints for tagging/renaming.
|
||
- `--onetagger-cli /path/to/onetagger-cli` – override CLI path (otherwise tries script folder or PATH).
|
||
- `--skip-onetagger` – only convert/strip/rename, skip tagging.
|
||
- Auth: `--discogs-token`, `--spotify-id`, `--spotify-secret`, or `--auth-file auth.json`.
|
||
|
||
### Authentication resolution
|
||
Order of precedence:
|
||
1) CLI flags
|
||
2) `--auth-file` JSON with `discogs_token`, `spotify_id`, `spotify_secret`
|
||
3) Environment variables `DISCOGS_TOKEN`, `SPOTIFY_CLIENT_ID`, `SPOTIFY_CLIENT_SECRET`
|
||
4) `auth.json` next to the script (if present)
|
||
|
||
Missing Spotify/Discogs creds cause those platforms to be dropped from the config copy for that run.
|
||
|
||
## Workflow
|
||
1) Pick output path with collision-safe suffixing.
|
||
2) Convert source to MP3 (optional loudness normalization).
|
||
3) Strip all metadata (skipped if `mutagen` is missing).
|
||
4) Optionally rename for better OneTagger filename hints.
|
||
5) Run OneTagger Auto Tag.
|
||
6) Rename final file to a sanitized `Artist - Title.mp3`.
|
||
|
||
## Example (with credentials file)
|
||
```bash
|
||
python beautify-audio.py ~/Downloads/Track.wav \
|
||
--output-dir ~/Music/Prep \
|
||
--lufs -12 \
|
||
--auth-file ~/secrets/onetagger-auth.json
|
||
```
|
||
|
||
## Example for Automator Script (Quick Action)
|
||
```bash
|
||
set -euo pipefail
|
||
|
||
# Where the repo lives
|
||
SCRIPT_ROOT="/path/to/beautify-audio"
|
||
PY_SCRIPT="$SCRIPT_ROOT/beautify-audio.py"
|
||
|
||
# Make sure Homebrew binaries are visible (ffmpeg, etc.)
|
||
export PATH="/opt/homebrew/bin:/usr/local/bin:$PATH"
|
||
|
||
LOG_DIR="$HOME/Library/Logs"
|
||
LOG_FILE="$LOG_DIR/beautify-audio-$(date +%Y%m%d-%H%M%S).log"
|
||
mkdir -p "$LOG_DIR"
|
||
|
||
# Make sure a virtual environment with the requirements installed is available
|
||
source "$SCRIPT_ROOT/.venv/bin/activate"
|
||
|
||
{
|
||
echo "==== $(date) ===="
|
||
for src in "$@"; do
|
||
echo "Processing: $src"
|
||
/usr/bin/env python3 "$PY_SCRIPT" "$src"
|
||
done
|
||
} >>"$LOG_FILE" 2>&1
|
||
|
||
osascript -e "display notification \"Beautify Audio finished for $# file(s).\" with title \"Beautify Audio\""
|
||
|
||
```
|
||
|
||
|
||
## Notes
|
||
- Automator-friendly: one input file in, one clean MP3 out.
|
||
- If OneTagger is missing or fails, conversion and cleanup still run; renaming uses best-effort metadata.
|