My favorites | Sign in
Logo
                
Search
for
Updated Jul 03, 2009 by steven@strobe.cc
Mutagen  
Mutagen tagging library

Mutagen

Mutagen has moved!

Mutagen is now a separate project on Google Code. This page will remain intact until the new project has moved up in the search results, but updates and issues against Mutagen itself should be part of that project.

What is Mutagen?

Mutagen is a Python module to handle audio metadata. It supports ASF, FLAC, M4A, Monkey's Audio, MP3, Musepack, Ogg FLAC, Ogg Speex, Ogg Theora, Ogg Vorbis, True Audio, WavPack and OptimFROG audio files. All versions of ID3v2 are supported, and all standard ID3v2.4 frames are parsed. It can read Xing headers to accurately calculate the bitrate and length of MP3s. ID3 and APEv2 tags can be edited regardless of audio format. It can also manipulate Ogg streams on an individual packet/page level.

There is a brief tutorial with several API examples.

Where do I get it?

The download page will have the latest version, which is at the current time of writing mutagen-1.15.tar.gz. It can also be checked out from our Subversion repository.

 $ svn co http://svn.sacredchao.net/svn/quodlibet/trunk/mutagen

Why Mutagen?

Quod Libet has more strenuous requirements in an ID3 library than most programs that deal with tags. Furthermore, most tagging libraries suck. Therefore we felt it was necessary to write our own.

Real World Use

Mutagen can load every MP3 we have thrown at it (when it hasn't, we make it do so). Scripts are included so you can run the same tests on your collection.

The following software projects are using Mutagen for tagging:


Comment by znupi69, Oct 09, 2008

Where can we find examples on how to use the Mutagen library?

Comment by char...@clamothe.com, Nov 29, 2008

Any plans for python 3.0 compatibility?

Comment by steven@strobe.cc, Dec 21, 2008

An apparent source of confusion is the relationship between mutagen.mp3, id3, and easyid3. mp3.MP3 should be used to open an MP3 file; in addition to reading ID3v2 tags using either of the two ID3 parsers in Mutagen, it also reads additional information from the actual MPEG stream which may not be in the ID3 tags (like bitrate and duration).

An mp3.MP3 object behaves like a dict, like ID3 and EasyID3; in fact, the methods for getting and setting keys and values on an MP3 appear to simply map to the underlying ID3 parser's. If the ID3 tags you're working are on MP3 files, stick to using mp3.MP3 instead of using ID3 objects directly.

An mp3.MP3 object also has the method add_tags(), which allows you to add ID3 tags to a file that doesn't have any. This is the only way to add ID3 tags within Mutagen, AFAIK.

Comment by steven@strobe.cc, Dec 29, 2008

Also: mp3.add_tags has an optional argument 'ID3', which works just like the same arg on the constructor of an mp3 object, viz:

from mutagen.mp3 import MP3
from mutagen.easyid3 import EasyID3
import mutagen.id3

def test(filename):
   """Example which shows how to automatically add tags to an MP3 using EasyID3."""

   m = MP3(filename, ID3=EasyID3)

   try:
       m.add_tags(ID3=EasyID3)
       print("Added tags to %s" % filename)
   except mutagen.id3.error:
       print("%s already had tags" % filename)

   m['title'] = 'Test!'
   m.save()
   print(m.pprint())
   print('\n')

test('has-tags.mp3')
test('no-tags.mp3')
Comment by Lucian.B...@gmail.com, Jan 17, 2009

Any chance this library could ever be licensed as LGPL?

Comment by dhorn2000, Jan 29, 2009

An example of writing tags to an ASF/WMA file in a format that ffmpeg knows how to decode:

from mutagen.asf import ASF 
audio = ASF("myfilename.wma")
audio["Title"] = "MyTitle"
audio["Author"] = "MyArtist"
audio["WM/AlbumTitle"] = "MyAlbum"
audio["WM/TrackNumber"] = "12"
#print ASF.pprint(audio)
#print ASF.keys(audio)
ASF.save(audio)

I use the "Author" tag for "Artist", as that happens to be the mapping used by musicpd (mpd) when it uses ffmepg AVFormatContext() to get the tags from the wma file.

Comment by hlangos645, Feb 23, 2009

How about a new page for MutagenExamples? ? I'd contribute a simple image extractor:

#!/usr/bin/python
import os
import sys
import locale
from optparse import OptionParser

def main(argv):
    from mutagen.id3 import ID3

    parser = OptionParser()
    (options, args) = parser.parse_args(argv[1:])
    if not args:
        raise SystemExit(parser.print_help() or 1)

    enc = locale.getpreferredencoding()
    for filename in args:
        print "--", filename
        try:
            f = ID3(filename);
            for frame in f.getall("APIC"):
                print frame.pprint().encode(enc, 'replace')
                ext = ".img"
                if (frame.mime == "image/jpeg") or (frame.mime == "image/jpg"): ext = ".jpg"
                if frame.mime == "image/png": ext = ".png"
                if frame.mime == "image/gif": ext = ".gif"
                (proot,pext) = os.path.splitext(filename)
                imgfilename = proot + ext
                if os.path.exists(imgfilename) : print "File " + imgfilename + " exists. Skipping!"
                else:
                    print "Writing image to " + imgfilename + " !"
                    myfile = file(imgfilename, 'wb')
                    myfile.write(frame.data)
                    myfile.close()
        except AttributeError: print "- Unknown file type"
        except KeyboardInterrupt: raise
        except Exception, err: print str(err)
        print

main(sys.argv)
Comment by beatmixed, Mar 26, 2009

I'd like a way to determine if there is an id3v1 tag, even when an id3v2 tag is also present. For example, mutagen.id3.ID3.version will return (2,3,0) when both v1 and v2 tags are present. Any suggestions on how to check if an id3v1 tag is also there? Thanks.

Comment by caslav.i...@gmx.net, Mar 27, 2009

What about COMM tags? As it is now, it converts only tags starting with T, but COMM too can contain text. I personally did something like this to make it work on my MP3s, but have no idea if it makes sense:

Index: mid3iconv
===================================================================
--- mid3iconv   (revision 4351)
+++ mid3iconv   (working copy)
@@ -62,9 +62,9 @@
                 print str(err)
             continue

-        for tag in filter(lambda t: t.startswith("T"), id3):
+        for tag in id3:
             frame = id3[tag]
-            if isinstance(frame, mutagen.id3.TimeStampTextFrame): # non-unicode fields
+            if isinstance(frame, mutagen.id3.TimeStampTextFrame) or not hasattr(frame, "text"): # non-unicode fields
                 continue

             try:
Comment by hybrid.basis, May 06, 2009

Is there any way to read data from an MP3 file that is already in memory, stored in a file-like object? I've managed to pass the object to MPEGInfo just fine, but have been unable to do so for MP3 - which has made retrieving the ID3 information kind of difficult.

Comment by r3inforce, Jul 24, 2009

Hi, here a quick hint how to add iTunes compatible lyrics to an MP3:

lyrics = u"""
Some text
here
does not really
mattah
"""

tagg = id3.ID3("some.mp3")
tagg[u"USLT::'eng'"] = id3.USLT()     # add a new unsynchronized lyrics element
tagg[u"USLT::'eng'"].text = lyrics
tagg[u"USLT::'eng'"].encoding=1       # i guess it means utf8
tagg[u"USLT::'eng'"].lang='eng'       # seems to be used for everything
tagg[u"USLT::'eng'"].desc=u''         # dont know what the description is good for
tagg.save()

Works for me, didnt took the time to read the specs.

Comment by gbrabelo, Oct 16, 2009

Hey r3inforce... adding lyrics that way to an mp3 does not work if the lenght of the lyrics is bigger than (somewhat) characters...at least iTunes shows blank lyrics. Do u know another way?


Sign in to add a comment
Hosted by Google Code