My favorites | Sign in
Project Home Downloads Wiki Issues Source
Search
for
Tutorial  
A brief Mutagen tutorial
Updated Jun 15, 2009 by joe.wreschnig@gmail.com

Mutagen Tutorial

There are two different ways to load files in Mutagen, but both provide similar interfaces. The first is the Metadata API, which deals only in metadata tags. The second is the FileType API, which is a superset of the Metadata API, and contains information about the audio data itself.

Both Metadata and FileType objects present a dict-like interface to edit tags. FileType objects also have an 'info' attribute that gives information about the song length, as well as per-format information. In addition, both support the load(filename), save(filename), and delete(filename) instance methods; if no filename is given to save or delete, the last loaded filename is used.

This tutorial is only an outline of Mutagen's API. For the full details, you should read the docstrings (pydoc mutagen) or source code.

Easy Examples

The following code loads a file, sets its title, prints all tag data, then saves the file, first on a FLAC file, then on a Musepack file. The code is almost identical.

      from mutagen.flac import FLAC
      audio = FLAC("example.flac")
      audio["title"] = "An example"
      audio.pprint()
      audio.save()

      from mutagen.apev2 import APEv2
      audio = APEv2("example.mpc")
      audio["title"] = "An example"
      audio.pprint()
      audio.save()

The following example gets the length and bitrate of an MP3 file:

    from mutagen.mp3 import MP3
    audio = MP3("example.mp3")
    print audio.info.length, audio.info.bitrate

The following deletes an ID3 tag from an MP3 file:

    from mutagen.id3 import ID3
    audio = ID3("example.mp3")
    audio.delete()

Hard Examples: ID3

Unlike Vorbis, FLAC, and APEv2 comments, ID3 data is highly structured. Because of this, the interface for ID3 tags is very different from the APEv2 or Vorbis/FLAC interface. For example, to set the title of an ID3 tag, you need to do the following:

    from mutagen.id3 import ID3, TIT2
    audio = ID3("example.mp3")
    audio.add(TIT2(encoding=3, text=u"An example"))
    audio.save()

If you use the ID3 module, you should familiarize yourself with how ID3v2 tags are stored, by reading the details of the ID3v2 standard.

Easy ID3

Since reading standards is hard, Mutagen also provides a simpler ID3 interface.

    from mutagen.easyid3 import EasyID3
    audio = EasyID3("example.mp3")
    audio["title"] = u"An example"
    audio.save()

Because of the simpler interface, only a few keys can be edited by EasyID3; to see them, use:

    from mutagen.easyid3 import EasyID3
    print EasyID3.valid_keys.keys()

By default, mutagen.mp3.MP3 uses the real ID3 class. You can make it use EasyID3 as follows:

    from mutagen.easyid3 import EasyID3
    from mutagen.mp3 import MP3
    audio = MP3("example.mp3", ID3=EasyID3)
    audio.pprint()

Unicode

Mutagen has full Unicode support for all formats. When you assign text strings, we strongly recommend using Python unicode objects rather than str objects. If you use str objects, Mutagen will assume they are in UTF-8.

(This does not apply to strings that must be interpreted as bytes, for example filenames. Those should be passed as str objectss, and will remain str objects within Mutagen.)

Multiple Values

Most tag formats support multiple values for each key, so when you access then (e.g. audio["title"]) you will get a list of strings rather than a single one ([u"An example"] rather than u"An example"). Similarly, you can assign a list of strings rather than a single one.

Comment by mike.bus...@gmail.com, Apr 25, 2010

This is great (!! :D) but where can I find more documentation & examples?

-Mike

Comment by timoverb...@gmail.com, May 8, 2010

how is audio.info.length formated

Comment by rfkroc...@gmail.com, May 13, 2010

@timoverbeek10 - I think it's in seconds, which is odd. Milliseconds would be nicer for sure.

Comment by brito....@gmail.com, Dec 24, 2010

Could you post an example of how to read the mp3 artist name?

Comment by rasmus.l...@gmail.com, Dec 31, 2010
#!/usr/bin/python

from mutagen.mp3 import MP3
audio = MP3("testfile.mp3")
songtitle = audio["TIT2"]
artist = audio["TPE1"]
album = audio["TALB"]

print songtitle
print artist
print album
Comment by rasmus.l...@gmail.com, Dec 31, 2010

try to :

from mutagen.mp3 import MP3 
audio = MP3("testfile.mp3") 
dir(audio) 

:)

Comment by kevincox...@gmail.com, Jan 31, 2011

It would be nice to have a wrapper that detects the format and automatically reads/writes the right type of tag. Then all tags could be accessed from generic easy to use functions.

Comment by alex.mar...@gmail.com, Feb 12, 2011

There is wrapper that detects the format and automatically reads/writes the right type of tag:

>>> mutagen.File("mutah_resign.mp3", easy=True)
{'date': [u'2011'], 'album': [u'Salary man on holidays'], 'title': [u'Resign'], 'genre': [u'Trip-Hop'], 'artist': [u'Mutah']}
>>> mutagen.File("080208workadub.ogg", easy=True)
{'album': [u''], 'description': [u''], 'artist': [u'Mutah'], 'title': [u'Work a dub'], 'date': [u'2008'], 'genre': [u'']}
>>> mutagen.File("01 - a custom skylark 1.flac", easy=True)
{'album': [u'cd Bea'], 'description': [u''], 'artist': [u'kaffe matthews'], 'title': [u'a custom skylark 1'], 'tracktotal': [u'26'], 
 'musicbrainz_sortname': [u'kaffe matthews'], 'genre': [u'Electro Experimental'], 'tracknumber': [u'1']}
Comment by gabche...@gmail.com, Feb 17, 2011

I encountered an mp3 file with multiple cover images embeded (6 or 7 images in total) but mutagen reads and shows only 2. Are there any special methods of accessing those extra 'hidden' apic frames?

Comment by project member joe.wreschnig@gmail.com, Feb 17, 2011

I suspect the reason Mutagen only finds two is because they have the same content descriptor (description string) and type. If this is the case, there is no way in the normal interface - Mutagen uses these to generate the frame's hash key, which is explicitly allowed by the ID3v2 specification, so the file are technically out of spec.

However, it is possible to subclass mutagen.id3.ID3 and override the 'add' method to intercept any frame, changing its hash key or otherwise special-casing its insertion into the dictionary. This is actually a supported API injection point, so it's unlikely to break - Quod Libet has used it for years to parse a common ID3v2.3 idiom.

Comment by gabche...@gmail.com, Feb 21, 2011

OK. Got the idea. Thanks a lot for the explanation. I'll give it a try.

Comment by reliconb...@gmail.com, May 10, 2011

How can I write a comment field? This doesn't seem to work:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from mutagen.id3 import ID3, TRCK, TIT2, TPE1, TALB, TDRC, TCON, COMM
audio = ID3("example.mp3")

audio.add(TRCK(encoding=3, text=u"1"))
audio.add(TIT2(encoding=3, text=u"Title"))
audio.add(TPE1(encoding=3, text=u"Artist"))
audio.add(TALB(encoding=3, text=u"Album"))
audio.add(TDRC(encoding=3, text=u"2011"))
audio.add(TCON(encoding=3, text=u"Genre"))
audio.add(COMM(encoding=3, text=u"Comment"))

audio.save()

Also I get "ID3NoHeaderError" if the file has no ID3 tag at all. How can I do that?

Comment by yomguyparisson, May 12, 2011

Me too, I've got an error when adding a comment (COMM):

ValueError?: Invalid StringSpec?3? data: 'blabla'

Comment by goo...@mac-guyver.com, May 15, 2011

Using MP3(filename, ID3=EasyID3), I was getting errors if I started with a file with no tags and tried to set tags. Actually, it would let me set tags but errors would happen in pprint() or save(). But, it seems to work the way I want with mutagen.File(filename,easy=True):

>>> import mutagen
>>> src = mutagen.File("You Said it Butch.mp3", easy=True)
>>> dest = mutagen.File("192/You Said it Butch.mp3", easy=True)
>>> for k in src:
...     dest[k] = src[k]
... 
>>> dest.save()
>>> test = mutagen.File("192/You Said it Butch.mp3", easy=True)
>>> print test.pprint()
MPEG 1 layer 3, 192000 bps, 44100 Hz, 248.25 seconds (audio/mp3)
album=The Burst of the West
artist=Harry Potter
encodedby=Fission
performer=Harry Potter
title=You Said it Butch
tracknumber=2/3
>>> 

The dest file was produced by transcoding the src file using lame (which drops ID3 tags). Another way that worked with the MP3(filename, ID3=EasyID3) class, was to tell lame "--tt title" to add one dummy tag. Then mutagen was willing to transfer the tags and save the changes. But that's obscure and kludgy.

So the long-term question is, what's the general way to get mutagen to let me add tags in the "easy" way to a file that starts out tagless?

Comment by project member joe.wreschnig@gmail.com, May 15, 2011

If you have problems opening or saving files using MP3(filename, ID3=EasyID3), please report a ticket.

Comment by goo...@mac-guyver.com, May 15, 2011

Joe-- Okay, I reported it as Problem adding ID3 tags to tagless file opened with MP3(filename, ID3=EasyID3)

Comment by reliconb...@gmail.com, May 16, 2011

yomguyparisson: Use this to put comment to MP3 tags:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

# Imports
from mutagen.id3 import ID3, TRCK, TIT2, TPE1, TALB, TDRC, TCON, COMM

# Set file
audio = ID3("example.mp3")

# Add tags
audio.add(TRCK(encoding=3, text=u"1"))
audio.add(TIT2(encoding=3, text=u"Title"))
audio.add(TPE1(encoding=3, text=u"Artist"))
audio.add(TALB(encoding=3, text=u"Album"))
audio.add(TDRC(encoding=3, text=u"2011"))
audio.add(TCON(encoding=3, text=u"Genre"))
audio.add(COMM(encoding=3, lang="eng", desc="", text="Comment"))

# Save tags
audio.save()

# Print tags
print audio.pprint()

...But I still haven't figured out how to create ID3 header if the file has none.

Comment by project member joe.wreschnig@gmail.com, May 17, 2011

If you are having trouble adding an ID3 tag to a file, please see the FAQ "How do I add an ID3 tag?"

Comment by pericoarmando, Jul 19, 2011

i'm having problems with mp4 cover, with mp3 is fine, but with mp4 i ain't being able to figure out how to set it, anyone has a suggestion ?

thanks a lot

Comment by pericoarmando, Jul 22, 2011

after saving tags with mutagen, the tags just "disappear" and are not being displayed on windows//explorer or wmp.... on itunes is ok, when i pprint the tags are shown, but windows seems to do not like it.... any ideas ?!

thanks

Comment by cornb...@gmail.com, Sep 3, 2011

How would you use Mutagen with StringIO for reading ID3 tags from mp3s stored in strings.

Comment by zee...@gmail.com, Sep 18, 2011

How to get track length for FLAC?

Comment by cijic.pi...@gmail.com, Sep 29, 2011

How I can add APIC tag using some JPG file as picture into MP3 file? If adding an image can be done something like that

audio = ID3(u'P:/How Low_2.mp3')
pic = APIC(3, u'image/jpg', 3, u'Front cover', open(u'cover.jpg', 'rb').read())
audio.add(pic)
audio.save()

then I would like to report an error - the image is added incorrectly or incompletely.

Comment by jehoshu...@gmail.com, Oct 4, 2011

After many hours . . .

I discovered why on save() the information disappears in Windows Explorer and Media Player . . .

. . . Windows Explorer and Media Player only read, and mutagen does NOT write, ID3v1 tags!

And as far as I can tell from the LIMITED documentation, mutagen will READ BUT NOT WRITE ID3v1 tags.

I further discovered, while playing with WINAMP, that it is possible to have BOTH ID3v1 and ID3v2 tags in a file, BUT Windows Explorer and Media Player require the ID3v1 tags to come first!

But there's no way to explicitly ensure that mutagen follows this requirement.

Does anybody know ID3v1 well enough to dive into the source code and fix this?

I'm using Windows 7, Python 2.7, Mutagen 1.20. I really hope this helps someone avoid spending painful amounts time!

Comment by project member joe.wreschnig@gmail.com, Oct 4, 2011
$ pydoc mutagen.id3.ID3.save

Help on method save in mutagen.id3.ID3:

mutagen.id3.ID3.save = save(self, filename=None, v1=1) unbound mutagen.id3.ID3 method
    Save changes to a file.
    
    If no filename is given, the one most recently loaded is used.
    
    Keyword arguments:
    v1 -- if 0, ID3v1 tags will be removed
          if 1, ID3v1 tags will be updated but not added
          if 2, ID3v1 tags will be created and/or updated
Comment by Henry.W...@Yahoo.com, Oct 31, 2011

I would like to scan many files and catch ones that have too small images. I see the APIC element, but no obvious way to determine the length and width. Could someone please post an example of how to determine the image length and width?

Comment by fcastill...@gmail.com, Dec 12, 2011

How can I access the value inside the POPM tag? Using:

from mutagen.mp3 import MP3
audio = MP3("testfile.mp3")
popular = audio["POPM"]

Gives me an error:

File "/usr/lib/pymodules/python2.7/mutagen/_util.py", line 108, in __getitem__
    return self.__dict[key]
KeyError: 'POPM

Sign in to add a comment
Powered by Google Project Hosting