mudio
mudio is a powerful, friendly command-line music metadata editor and Python library. It provides a unified API for handling metadata across MP3, FLAC, M4A, and more, making batch processing and automation simple and safe.
- For full command details, see the CLI Reference.
- For code API details, see the API Reference.
Features
- Unified API: Write code once, run it on MP3, FLAC, M4A, WAV, OGG, and OPUS.
- Batch Processing: robust CLI for processing thousands of files.
- Parallel Execution: Automatically uses multi-threading for large batches.
- Safety First: Built-in backup system, dry-run mode, and careful validation.
- Powerful Operations:
- Find & Replace: Regex-supported search and replace in tags.
- Mass Edits: Set, overwrite, append, prefix, or clear tags.
- Filtering: Apply changes only to files matching specific criteria (e.g.
artist="The Beatles").
Supported Formats
- MP3 (
.mp3) - ID3v2.3/v2.4 - FLAC (
.flac) - Vorbis Comments - M4A / MP4 (
.m4a,.mp4) - MP4 Tags - Ogg Vorbis (
.ogg) - Opus (
.opus) - WAV (
.wav)
Installation
pip install mudio
CLI Usage
Simple: Update metadata for files
# Set album name for all MP3 files
mudio *.mp3 --operation write --fields album --value "Greatest Hits"
Advanced: Conditional batch processing with backup
# Fix title formatting for 1990s Rock tracks, with backups and regex
mudio /music --recursive --backup ./backups \
--filter-regex --filter "date=^199" --filter "genre=Rock" \
--operation find-replace --fields title --find "\s+" --replace " " --regex
💡 Tip: Use
--dry-runto preview changes before applying them.
Python Library Usage
Simple: Read and write metadata
from mudio.processor import process_file
from mudio.operations import write
# Update a single file with automatic verification
result = process_file(
"song.mp3",
ops=[write('artist', 'The Beatles')]
)
print(f"Success: {result['passed']}") # True if successful
Advanced: Batch processing with operations
from mudio.processor import process_files
from mudio.operations import write, enlist, find_replace
from pathlib import Path
# Process multiple files with complex operations
results = process_files(
Path('music').rglob('*.flac'),
ops=[
enlist('genre', 'Rock;Classic'), # Add genres if not present
find_replace('title', r'\s+', ' ', regex=True), # Normalize whitespace
write('albumartist', 'Various Artists')
],
filters=[('date', '^199', True)], # Only 1990s tracks (regex)
backup_dir='./backups',
max_workers=4
)
print(f"Updated {sum(r['passed'] for r in results)} files")
Environment Variables
You can configure mudio's default behavior using environment variables:
MUDIO_SCHEMA: Set default schema for reading metadata (canonical,extended, orraw). Default:extended.MUDIO_MAX_WORKERS: Default thread count for parallel processing.MUDIO_VERBOSE: Default verbosity (0or1).MUDIO_NAMESPACE: Namespace for custom MP4/M4A fields (default:com.apple.iTunes). Setting this to something else (e.g.org.myproject) allows isolating your custom tags.
# Example: Use extended schema by default (canonical + custom fields)
export MUDIO_SCHEMA=extended
python your_script.py
Behavior Notes
Field Handling (All Formats)
mudio normalizes metadata to a case-insensitive canonical schema and applies consistent rules across formats.
Reading
- Canonical fields: Tags are normalized to standard names (e.g.,
TIT2→title). - Strict whitespace handling: All values are stripped of leading/trailing whitespace. Empty or whitespace-only values are dropped.
- Empty field representation: If a field exists but all values are empty after stripping, it returns
[''](a list with a single empty string). - Deduplication: All field values are deduplicated case-insensitively, and identical frames are merged.
Writing
- Canonical fields: Written to format-specific native tags.
- Strict whitespace handling: Values are stripped; empty strings are dropped from lists.
- Smart empty: A single
[''](e.g. fromclear()) is preserved and written, allowing explicit "empty" tags. - Deletion: Writing
[](empty list) deletes the field entirely. - All fields are multi-valued: All unique values are written.
- Custom fields: Keys are sanitized to caps snake case (e.g.,
MY_CUSTOM_FIELD).
Example - Custom Field Writing:
# Writing with various custom key formats
sm.write_fields({
'my-custom-field': ['value1'], # Written as: MY_CUSTOM_FIELD
'AnotherField': ['value2'], # Written as: ANOTHERFIELD
})
Canonical Fields
The following canonical fields are recognized by mudio across all audio formats:
title · artist · album · albumartist · genre · comment · composer · performer · date · track · totaltracks · disc · totaldiscs
Note: All field names are case-insensitive. Common variations (e.g., album_artist, tracknumber, discnumber) are automatically mapped to their canonical form.
Comparison with Alternatives
vs. Mutagen
- Mutagen is the low-level library that
mudiouses. It is powerful but requires learning different APIs for ID3, Vorbis, and MP4 tags. - mudio abstracts these differences. Use
mudioif you want a simple, unified API (e.g.sm.write_fields({'title': ...})works on everything). Usemutagenif you need byte-level control or support for obscure frame types.
vs. music_tag
- music_tag is a library primarily for Python scripts, offering a dictionary-like interface. It is excellent for simple script usage.
- mudio offers similar library features but includes a robust CLI for batch processing, filtering, and safety operations (backups, dry-runs) out of the box.
vs. Beets
- Beets is a complete library manager with a centralized database, autotagger, and plugin system. It implies a workflow where it "owns" your library.
- mudio is a stateless tool. It modifies files directly without a database. Use
mudiofor quick fixes, batch scripting, or if you prefer managing your file structure manually.
vs. Picard
- MusicBrainz Picard is a GUI application focused on matching files to the MusicBrainz database.
- mudio is a CLI/Library tool. It's better for automation, headless servers, or mass-editing tags based on patterns rather than database matching.
vs. EyeD3
- EyeD3 is excellent but specific to MP3/ID3.
- mudio supports FLAC, M4A, OGG, and more with the same commands.
Development
# Install dependencies
pip install -e ".[dev]"
# Run tests
pytest
Metadata
Release files for mudio 3.3.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| mudio-3.3.2.tar.gz | 46.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| mudio-3.3.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 85.6 kB
Release files / mudio-3.3.2.tar.gz
| Download URL | mudio-3.3.2.tar.gz |
|---|---|
| Size | 46.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
3aa6ba7b6d05aabafeddefd60828e7abed2d75a51a531432136c4273ab1769a4
|
|
BLAKE2b-256 checksum How to use checksums |
f44231bd644cfdc8984fedaef4d396a56b27b292ea44ba1ab1e2a3d09ea801d5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.3
|
Release files / mudio-3.3.2-py3-none-any.whl
| Download URL | mudio-3.3.2-py3-none-any.whl |
|---|---|
| Size | 39.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
8fd759698c944a6d12ed6ee4010e4190c123ec305b5e7ef85f2d8689b93f9edf
|
|
BLAKE2b-256 checksum How to use checksums |
f38a531acbb4838555def32bd4fb7c499f4f003faf517b0a13ab3375bce3ecde
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.3
|