Fix metadata for audio files using AcoustID and MusicBrainz
Project description
Music Metadata Fixer
Automatically fix audio file metadata using AcoustID fingerprinting and MusicBrainz database. Supports MP3, FLAC, and M4A formats with both CLI and optional GUI interfaces.
Features
- ๐ต Automatic Identification โ Fingerprints audio files using AcoustID
- ๐๏ธ Metadata Lookup โ Fetches comprehensive metadata from MusicBrainz
- ๐ Multi-Format Support โ MP3 (ID3), FLAC (Vorbis), M4A (MP4 tags)
- ๐๏ธ Dual Interface โ Command-line or Tkinter GUI (optional)
- ๐ Batch Processing โ Process entire folders at once
- โธ๏ธ Cancellation โ Stop processing cleanly at any time
- ๐ง Configurable โ Customize API keys, timeouts, preview duration
- ๐ Full Logging โ Detailed error tracking and debugging
- ๐งช Well-Tested โ Comprehensive test coverage including edge cases
Quick Start
Installation
From PyPI (Recommended)
pip install music-metadata-fixer
From Source
git clone https://github.com/yourusername/music-metadata-fixer.git
cd music-metadata-fixer
pip install -e .[dev]
Setup
-
Get AcoustID API Key (free): https://acoustid.org/api
-
Create config file:
cp config.json.example config.json
-
Edit
config.jsonand add your API key:{ "acoustid_api_key": "YOUR_KEY_HERE", "preview_duration_ms": 30000, ... }
Usage
Command Line
# Interactive mode (prompts for confirmation on each file)
music-metadata-fixer --directory /path/to/music
# Batch mode (no prompts, requires --batch flag)
music-metadata-fixer --directory /path/to/music --batch
# Disable audio preview
music-metadata-fixer --directory /path/to/music --no-audio
# GUI mode (if available)
music-metadata-fixer --gui
Python API
from config import Config
from providers import AcoustIDProvider
from engine import MetadataFixerEngine
# Initialize
config = Config('config.json')
provider = AcoustIDProvider(config.get('acoustid_api_key'))
engine = MetadataFixerEngine(provider)
# Process folder
results = engine.batch_process(
directory='/path/to/music',
interactive=False,
auto_confirm=True
)
print(f"Success: {results['success']}, Failed: {results['failed']}")
Requirements
System Dependencies
-
ffmpeg โ For audio conversion (optional but recommended)
- macOS:
brew install ffmpeg - Ubuntu:
sudo apt install ffmpeg - Windows: Download from https://ffmpeg.org/download.html
- macOS:
-
fpcalc โ AcoustID fingerprint calculator
- macOS:
brew install chromaprint - Ubuntu:
sudo apt install libchromaprint-tools - Windows: Download from https://acoustid.org/chromaprint
- macOS:
Python Dependencies
All installed automatically via pip install:
- pyacoustid โฅ 1.2.2
- musicbrainzngs โฅ 0.7
- mutagen โฅ 1.46.0
- pydub โฅ 0.25.1
- pygame โฅ 2.1.0 (audio playback, optional)
Configuration
config.json
{
"acoustid_api_key": "YOUR_API_KEY", # Required: AcoustID API key
"preview_duration_ms": 30000, # Audio preview duration (ms)
"log_file": "music_fixer_errors.log", # Log file path
"supported_formats": [".mp3", ".flac", ".m4a"], # File formats to process
"feature_preview": true, # Enable audio playback
"feature_auto_identify": true, # Auto-identify files
"feature_manual_edit": true, # Allow manual editing
"console_log": false, # Log to console
"log_level": "INFO" # Logging level (DEBUG, INFO, WARNING, ERROR)
}
Architecture
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ CLI / GUI โ
โ (music_fixer.py / gui_interface.py) โ
โโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโ
โ MetadataFixerEngine โ
โ (orchestrates identify โ fetch โ apply) โ
โโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโ
โโโโโโโโโโโโโโโผโโโโโโโโโโโโโโ
โ โ โ
โโโโโผโโโ โโโโโโโผโโโโโโ โโโโโโผโโโโโ
โProvider โFileHandler โ โAudioPlayer
โ(AcoustID โ (MP3, โ โ(Preview)
โ+Brainz) โFLAC,M4A) โ โ
โโโโโโโโ โโโโโโโโโโโโโ โโโโโโโโโโโ
Module Overview
| Module | Purpose |
|---|---|
music_fixer.py |
CLI entry point & argument handling |
engine.py |
Core processing workflow orchestration |
providers.py |
AcoustID + MusicBrainz integration |
file_handler.py |
Format-specific tag readers/writers |
config.py |
Configuration file management |
audio_player.py |
Audio preview with pygame |
gui_interface.py |
Optional Tkinter GUI |
logger.py |
Centralized logging |
cancellable.py |
Cancellation token for clean shutdown |
Testing
# Run all tests
pytest
# Run with coverage
pytest --cov=. --cov-report=html
# Run specific test file
pytest tests/test_engine.py -v
# Run specific test class
pytest tests/test_providers.py::ProviderCancellationTests -v
Test Coverage
- โ Engine workflow (identify โ fetch โ apply)
- โ Provider retries, timeouts, and error handling
- โ Cancellation token propagation
- โ Batch processing with partial failures
- โ File format handlers (MP3, FLAC, M4A)
- โ GUI components and threading
- โ Configuration loading and validation
Development
Setup Development Environment
pip install -e .[dev]
pre-commit install
Code Quality
# Type checking
mypy .
# Linting
flake8 .
pylint music_fixer.py
# Auto-formatting
black .
Adding New Provider
See DEVELOPMENT.md
Adding File Format Support
See DEVELOPMENT.md
Troubleshooting
"Missing external tools" warning
Install ffmpeg and fpcalc:
# macOS
brew install ffmpeg chromaprint
# Ubuntu/Debian
sudo apt install ffmpeg libchromaprint-tools
# Or download Windows binaries from respective websites
"API key not found"
Ensure config.json has acoustid_api_key field populated:
cp config.json.example config.json
# Edit config.json with your key
Files not being identified
- Check file format is supported (MP3, FLAC, M4A)
- Ensure file is a valid audio file (try playing in media player)
- Verify AcoustID API is responding (check log file)
- Try with
--no-audioflag (some systems have audio issues)
GUI doesn't start
Tkinter may not be installed:
# Ubuntu/Debian
sudo apt install python3-tk
# macOS
# Should be included; if not: brew install python-tk
# Windows
# Should be included with Python; reinstall Python and select Tcl/Tk
Metadata lookup returns "Unknown"
- File may not be in MusicBrainz database
- Fingerprint calculation may have failed
- Network connectivity issue (check logs)
- Use
--batch --no-audiofor faster processing
Examples
Process single folder
music-metadata-fixer --directory ~/Music/unsorted
Batch process multiple folders
for folder in ~/Music/Artist1 ~/Music/Artist2; do
music-metadata-fixer --directory "$folder" --batch
done
Process with logging
music-metadata-fixer --directory ~/Music --no-audio > processing.log 2>&1
GUI with custom timeout
Edit config.json:
{
"acoustid_api_key": "YOUR_KEY",
"timeout": 20 // Longer timeout for slow connections
}
Then run: music-metadata-fixer --gui
Performance
- Typical file processing: 3-5 seconds (fingerprint + lookup + write)
- Batch processing: ~100 files in 5-10 minutes (depending on network)
- Memory usage: ~50MB idle, ~200MB during batch processing
- Can be reduced by using
--no-audioflag
Known Limitations
- GUI is Tkinter-only (not PyQt/PySide)
- Cannot process multiple folders simultaneously
- Requires specific audio file formats (no WAV, OGG, etc. yet)
- Interactive mode requires user input for each file
- No proxy support for MusicBrainz API
Contributing
Contributions welcome! Please:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Add tests for new functionality
- Ensure tests pass (
pytest) - Submit a pull request
See DEVELOPMENT.md for detailed guidelines.
Version History
v0.4.0 (Current)
- Full type hints across all modules
- Comprehensive test suite (cancellation, failures, GUI)
- Package entry point (
music-metadata-fixercommand) - Optional dev dependencies for testing/linting
- GUI validation and documentation
v0.2.0
- Added FLAC and M4A support
- Improved error handling and retries
- Configuration management system
v0.1.0
- Initial release
- MP3 support with ID3 tags
- AcoustID + MusicBrainz integration
- CLI interface
License
MIT License โ see LICENSE for details
Credits
Built with:
- pyacoustid โ AcoustID fingerprinting
- musicbrainzngs โ MusicBrainz API
- mutagen โ Audio metadata handling
- pydub โ Audio processing
Support
- ๐ Documentation
- ๐ Report Issues
- ๐ฌ Discussions
Questions? Check out the FAQ or troubleshooting guide.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file music_metadata_fixer-0.4.0.tar.gz.
File metadata
- Download URL: music_metadata_fixer-0.4.0.tar.gz
- Upload date:
- Size: 30.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d72a99268fe339b6324b585899a6dae9aa29b4dbd58a71e12d0626699168fb28
|
|
| MD5 |
f17ad4f7d4b41022bea4387dc81076a3
|
|
| BLAKE2b-256 |
48dcfb91d2b4ac21e734e88ec2fb6ed426e6565648f43dd0d4b1ee67ff484f84
|
File details
Details for the file music_metadata_fixer-0.4.0-py3-none-any.whl.
File metadata
- Download URL: music_metadata_fixer-0.4.0-py3-none-any.whl
- Upload date:
- Size: 23.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
75279bee222a0aed89b9ed46ac33d9aef930edd96115a5067aba32e5e740924d
|
|
| MD5 |
fc3fcd5045a73e7220b38d78db639937
|
|
| BLAKE2b-256 |
44746a9b5314472ce48dd17743be413a33c17b1393a1d60105a299ad52bfd4dd
|