Skip to main content

Fix metadata for audio files using AcoustID and MusicBrainz

Project description

Music Metadata Fixer

Python 3.8+ License: MIT Tests

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

  1. Get AcoustID API Key (free): https://acoustid.org/api

  2. Create config file:

    cp config.json.example config.json
    
  3. Edit config.json and 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)

  • fpcalc โ€“ AcoustID fingerprint calculator

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

  1. Check file format is supported (MP3, FLAC, M4A)
  2. Ensure file is a valid audio file (try playing in media player)
  3. Verify AcoustID API is responding (check log file)
  4. Try with --no-audio flag (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-audio for 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-audio flag

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:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Add tests for new functionality
  4. Ensure tests pass (pytest)
  5. 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-fixer command)
  • 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:

Support


Questions? Check out the FAQ or troubleshooting guide.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

music_metadata_fixer-0.4.0.tar.gz (30.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

music_metadata_fixer-0.4.0-py3-none-any.whl (23.0 kB view details)

Uploaded Python 3

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

Hashes for music_metadata_fixer-0.4.0.tar.gz
Algorithm Hash digest
SHA256 d72a99268fe339b6324b585899a6dae9aa29b4dbd58a71e12d0626699168fb28
MD5 f17ad4f7d4b41022bea4387dc81076a3
BLAKE2b-256 48dcfb91d2b4ac21e734e88ec2fb6ed426e6565648f43dd0d4b1ee67ff484f84

See more details on using hashes here.

File details

Details for the file music_metadata_fixer-0.4.0-py3-none-any.whl.

File metadata

File hashes

Hashes for music_metadata_fixer-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 75279bee222a0aed89b9ed46ac33d9aef930edd96115a5067aba32e5e740924d
MD5 fc3fcd5045a73e7220b38d78db639937
BLAKE2b-256 44746a9b5314472ce48dd17743be413a33c17b1393a1d60105a299ad52bfd4dd

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page