Registry / serialization / mutagen

mutagen

JSON →
library1.48.1pypypi✓ verified 25d ago

Mutagen is a Python library to read and write audio tags for many formats, including MP3, FLAC, Ogg Vorbis/Opus/FLAC, M4A, ASF, and more. It provides both high-level access for common tags and low-level access to manipulate specific frame types. The library is actively maintained, with minor versions released every few months, currently at 1.47.0.

pip install mutagen
INSTALL
IMPORT
SIG · MUTAGEN
M
mutagen
serializationpythonv1.48.1
Install
1.6s avg
Import
18ms
Disk
17MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.93.13
musl
3.93.13
Install & Compatibility
Where this runs
tested against v1.48.1 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.103.95 runs
installs and imports cleanly · install 0.0s · import 0.020s · 19.2MB
glibc
py 3.103.95 runs
installs and imports cleanly · install 1.6s · import 0.016s · 20MB
17MB installed
● package 17MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

File
from mutagen import File
Primary entry point for opening any supported audio file type.
MP3
from mutagen.mp3 import MP3
For working specifically with MP3 files and their underlying ID3 tags.
EasyID3
from mutagen.easyid3 import EasyID3
Simplified interface for common ID3 tags (MP3s), often preferred for ease of use.
ID3
from mutagen.id3 import ID3
For direct manipulation of ID3 tags and frames.
ID3NoHeaderError
from mutagen.id3 import ID3NoHeaderError
Exception raised when an MP3 file lacks an ID3 header.

This quickstart demonstrates how to create a dummy MP3 file, add ID3 tags using `mutagen.id3.ID3` frame objects, save them, then read and update tags using the simpler `mutagen.File(..., easy=True)` interface. Remember to always call `.save()` to persist changes.

import os import mutagen from mutagen.id3 import ID3, TIT2, TPE1, TALB from mutagen.mp3 import MP3 # --- Create a dummy MP3 file for demonstration --- # In a real scenario, you would use an actual audio file. # This creates a minimal, valid-ish MP3 structure that mutagen can parse. temp_mp3_path = "temp_quickstart_audio.mp3" try: with open(temp_mp3_path, "wb") as f: f.write(b'\xFF\xFB\x30\x00' + b'\x00' * 1024) # --- Initializing and Adding Tags (using ID3 frames) --- # mutagen.File() is the primary entry point; for MP3s, it returns an MP3 object. audio_file = mutagen.File(temp_mp3_path) if audio_file is None: raise ValueError("Could not open dummy MP3 file.") # If the file has no ID3 tags, create a new ID3 object for it. if audio_file.tags is None: audio_file.tags = ID3() # Set common tags using ID3 frame objects audio_file.tags.add(TIT2(encoding=3, text=["My New Track Title"])) # Title audio_file.tags.add(TPE1(encoding=3, text=["Example Artist"])) # Artist audio_file.tags.add(TALB(encoding=3, text=["Demo Album"])) # Album audio_file.save() # Crucial: Saves changes to the file print(f"Tags written to '{temp_mp3_path}' using ID3 frames.") # --- Reading Tags (using EasyID3 for simpler access) --- # Open the file again, using easy=True for a dictionary-like interface easy_audio = mutagen.File(temp_mp3_path, easy=True) if easy_audio is None: raise ValueError("Could not re-open dummy MP3 with easy=True.") print("\n--- Reading Tags (using EasyID3) ---") print(f"Title: {easy_audio.get('title', ['N/A'])[0]}") print(f"Artist: {easy_audio.get('artist', ['N/A'])[0]}") print(f"Album: {easy_audio.get('album', ['N/A'])[0]}") # --- Updating Tags (using EasyID3) --- easy_audio["artist"] = ["Updated Artist Name"] easy_audio.save() # Save the update reloaded_easy_audio = mutagen.File(temp_mp3_path, easy=True) print(f"\nEasyID3 Artist (updated): {reloaded_easy_audio.get('artist', ['N/A'])[0]}") except Exception as e: print(f"An error occurred: {e}") print("Ensure you have write permissions in the current directory and the file can be created/accessed.") finally: # Clean up the dummy file if os.path.exists(temp_mp3_path): os.remove(temp_mp3_path) print(f"\nCleaned up '{temp_mp3_path}'.")
Debug
Known issues
breakingPython 3.6 support was dropped.
fix
Upgrade to Python 3.7 or newer to use mutagen 1.45.0+.
affects: >=1.45.0
gotchaThe `mutagen.File()` function returns `None` if the specified file does not exist or cannot be opened/parsed as an audio file.
fix
Always check for `None` after calling `mutagen.File()`: `audio = mutagen.File('path.mp3'); if audio is None: print('File not found or invalid.')`
affects: >=1.39
deprecatedUsing `MP3.add_tags()` to add ID3 tags to an MP3 file is deprecated.
fix
Instead of `audio = MP3('path.mp3'); audio.add_tags()`, directly assign a new `ID3` object if `audio.tags` is `None`: `audio = MP3('path.mp3'); if audio.tags is None: audio.tags = ID3()`.
affects: >=1.44.0
gotchaWhen creating a new `mutagen.id3.ID3` object, it no longer automatically populates with default frames. You must explicitly add all desired frames.
fix
When initializing new ID3 tags (`audio.tags = ID3()`), make sure to then `audio.tags.add(...)` all required frames (e.g., `TIT2`, `TPE1`, etc.) or assign them directly.
affects: >=1.43.0
gotchaChanges made to audio tags are not persisted to the file system until the `.save()` method is explicitly called on the audio object.
fix
Always remember to call `audio_file.save()` after modifying tags: `audio_file['title'] = ['New Title']; audio_file.save()`.
affects: All versions
gotchaSaving audio files can fail with 'can't sync to MPEG frame' if the file structure is corrupt, if invalid data is written, or due to file system permission issues.
fix
Ensure the audio file being modified is valid and not corrupt. If creating a new file or adding tags, verify that the data (especially image data or custom frames) is correctly formatted and within expected limits. Always confirm write permissions for the target file and directory.
affects: All versions
gotchaAn error 'can't sync to MPEG frame' indicates that Mutagen failed to find or parse a valid MPEG audio frame in the file. This typically happens with corrupted or malformed MP3 files, or if there's an issue during writing that results in an invalid file structure.
fix
Verify the integrity of your MP3 file. If reading, try a different, known-good MP3 file. If writing, ensure the data you are writing is valid for the MP3 format and that the file system permissions allow for proper file creation/modification.
affects: All versions
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'mutagen'
The 'mutagen' package is not installed in the Python environment being used, or the Python interpreter cannot find it in its search path.
fix
Install the library using pip: `python -m pip install mutagen` or `pip install mutagen` if your PATH is configured correctly.
KeyError: 'TXXX:SERIES' (or similar tag key like 'artist', 'title')
This error occurs when attempting to access a specific tag (like 'TXXX:SERIES' for a custom series tag or 'artist'/'title' using the low-level ID3 API) that does not exist in the audio file's metadata.
fix
Use a `try-except` block to handle missing keys or use the `.get()` method, which allows specifying a default value if the key is not found: 
```python
from mutagen.id3 import ID3

audio = ID3('audio.mp3')

# Using .get() method
series = audio.get('TXXX:SERIES')
if series: # Check if series is not None
    print(series.text)
else:
    print('No series tag found')

# Or using try-except
try:
    print(audio['TXXX:SERIES'].text)
except KeyError:
    print('No series tag found')
```
TypeError: unbound method pprint() must be called with Frame instance as first argument (got str instance instead)
This `TypeError` typically arises when directly assigning a plain string value to a tag in the low-level `mutagen.mp3.MP3` or `mutagen.id3.ID3` object, which expects a `mutagen.id3.Frame` object (or a list of them) for complex tags, instead of using the `EasyID3` interface for simpler key-value assignments.
fix
For simpler tag manipulation with common keys, use `mutagen.easyid3.EasyID3`. For advanced control with the low-level `ID3` API, create appropriate `mutagen.id3.Frame` objects:

```python
# Fix using EasyID3 for simple tags
from mutagen.easyid3 import EasyID3

audio = EasyID3('audio.mp3')
audio['title'] = 'My Song Title'
audio['artist'] = 'My Artist'
audio.save()

# Fix using ID3 Frame objects for low-level API
from mutagen.id3 import ID3, TIT2, TPE1

audio = ID3('audio.mp3')
audio['TIT2'] = TIT2(encoding=3, text=['My Song Title'])
audio['TPE1'] = TPE1(encoding=3, text=['My Artist'])
audio.save()
```
AttributeError: 'NoneType' object has no attribute 'add'
This error occurs when `mp3file.add_tags()` is called on an `MP3` object that does not have existing ID3 tags, and it returns `None`. Subsequent attempts to call `.add()` on this `None` object will raise the `AttributeError`.
fix
Ensure that `add_tags()` is called on a file that either already has tags or where you explicitly handle the possibility of `None` being returned. A common pattern is to check the return value or initialize tags if they don't exist: 
```python
from mutagen.mp3 import MP3
from mutagen.id3 import ID3, TIT2

filename = 'audio.mp3'

mp3file = MP3(filename)

tags = mp3file.tags
if tags is None:
    tags = ID3()
    mp3file.tags = tags

tags.add(TIT2(encoding=3, text=['New Title']))
mp3file.save()
```
Upgrade
Version history
1.48.1latest on PyPI · released Jun 25, 2026
Audit
Dependencies

No dependency data recorded yet.

Agent activity
7 hits · last 30 days
node
6
Resources