Read/Write MP3 Tags with Perl

Discussion in 'Perl' started by pradeep, May 7, 2007.

  1. pradeep

    pradeep Team Leader

    Joined:
    Apr 4, 2005
    Messages:
    1,645
    Likes Received:
    87
    Trophy Points:
    0
    Occupation:
    Programmer
    Location:
    Kolkata, India
    Home Page:
    http://blog.pradeep.net.in

    Introduction



    If you're like most people, you probably have a bunch of MP3s scattered around your hard disk. And if you're like most people, you probably also have on your to-do list a plan to inspect and catalog them so that you know exactly what you're listening to. It's just that you haven't gotten around to it yet.

    Well, with a little help from Perl, it's possible for you to finally cross that item off your list. CPAN comes with an MP3::Tag module, which provides ready-made tools to read and extract metadata from MP3 files, making it a simple matter to identify the title, artist, and genre of a particular MP3 track. This can then be used with Perl's file functions to efficiently (and automatically) build an index of all your MP3 content. And if you'd like to, you can even edit the file metadata with built-in module functions.

    This article will discuss both functions, showing you how to use the MP3::Tag module to read and write MP3 file metadata. It assumes that you have a working Perl installation with the MP3::Tag module installed; if you don't have this module, you can download it from CPAN.

    Reading MP3 tags



    Let's start with the basics: reading ID3 tags embedded in MP3 files. Snippet A is a simple example, which demonstrates how this may be done with MP3::Tag:

    Snippet A
    Code:
       #!/usr/bin/perl
       
       use MP3::Tag;
       $mp3 = MP3::Tag->new('track1.mp3'); # create object
       
       $mp3->get_tags(); # read tags
       
       if (exists $mp3->{ID3v1}) { # print track information
       print "Filename: $filename\n";
       print "Artist: " . $mp3->{ID3v1}->artist . "\n";
       print "Title: " . $mp3->{ID3v1}->title . "\n";
       print "Album: " . $mp3->{ID3v1}->album . "\n";
       print "Year: " . $mp3->{ID3v1}->year . "\n";
       print "Genre: " . $mp3->{ID3v1}->genre . "\n";
       }
       
       $mp3->close(); # destroy object
    Nothing too complicated here. First, a new MP3::Tag object is created, with the filename and location of the MP3 file passed to the object constructor as an argument. Next, the object's get_tags() method is used to read the metadata embedded in the file headers and represent it as object properties. These properties can then be accessed and printed in the normal way. Here's a sample of the output:
    Code:
       Filename: track1.mp3
       Artist: Udit Narayan
       Title: Pehla Nasha
       Album: Joh Jeeta Wohi Sikander
       Year: 1992
       Genre: Soundtrack
    This capability makes it particularly easy to do what I promised I'd show you at the beginning of this article--create a printable catalog of all your music files. All you need to do is place the code above in a loop, run it on all your *.mp3 files, and format the output for easy readability. Snippet B shows you how.

    Snippet B
    Code:
       #!/usr/bin/perl
       
       use MP3::Tag; # import module
       
       @files = <*.mp3>; # find MP3 files in current directory
       
       # loop over file list
       # print tag information
       foreach (@files) {
       $mp3 = MP3::Tag->new($_);
       $mp3->get_tags();
       
       if (exists $mp3->{ID3v1}) {
       print $_, "\t", $mp3->{ID3v1}->artist, "\t", $mp3->{ID3v1}->title, "\n";
       }
       
       $mp3->close();
       }
    In this case, the list of MP3 files in the current directory is stored in the @files array. A foreach loop then iterates over this array, using the get_tags() method to retrieve and print detailed metadata for each file.

    And there you have it--an automatically generated MP3 catalog! As you add new music files to your collection, simply rerun the script above, and they will automatically show up in the catalog listing. Isn't that neat?

    Writing MP3 tags



    Of course, it doesn't just stop there--you can just as easily use MP3::Tag to write new metadata to an MP3 file. Snippet C is an example of how you might do this.

    Snippet C
    Code:
       #!/usr/bin/perl
      
       use MP3::Tag;
       $mp3 = MP3::Tag->new('track2.mp3'); # create object
       
       $mp3->get_tags(); # read tags
       
       if (exists $mp3->{ID3v1}) { # save track information
       $mp3->{ID3v1}->title("Roothke Humse Kahi");
       $mp3->{ID3v1}->artist("Joh Jeeta Wohi Sikander");
       $mp3->{ID3v1}->album("Various");
       $mp3->{ID3v1}->year("1992");
       $mp3->{ID3v1}->write_tag();
       }
       
       $mp3->close(); # destroy object
    If you look closely, you'll see some similarities between this and the previous scripts. As before, the first step is to initialize an object of the MP3::Tag class by passing the object constructor the name of the MP3 file you wish to alter. The get_tags() method is then used to retrieve the current file metadata. Altering this metadata becomes as simple as assigning new values to the appropriate object properties and then saving the new values to the file with a call to the write_tag() method.

    Of course, in the real world, it's highly likely that you won't be hard-wiring metadata into your script. Instead, you're more likely to need an interactive application, one that prompts the user for artist, track, and title information and then writes this data to the MP3 file. Luckily, this application is easy to build, knowing what you know now about MP3::Tag. Take a look at Snippet D.

    Snippet D
    Code:
       #!/usr/bin/perl
       
       use MP3::Tag;
       
       $filename = shift; # get filename from command line
       $mp3 = MP3::Tag->new($filename);
       $mp3->get_tags(); # read tags
       
       print "Enter track title: "; # prompt for title
       chomp ($title = <>);
       
       print "Enter artist: "; # prompt for artist
       chomp ($artist = <>);
       
       print "Enter album: "; # prompt for album name
       chomp ($album = <>);
       
       print "Enter year: "; # prompt for year
       chomp ($year = <>);
       
       if (exists $mp3->{ID3v1}) { # save track information
       $mp3->{ID3v1}->title($title);
       $mp3->{ID3v1}->artist($artist);
       $mp3->{ID3v1}->album($album);
       $mp3->{ID3v1}->year($year);
       $mp3->{ID3v1}->write_tag();
       }
       
       $mp3->close(); # destroy object
    When invoked on the command line, this script expects to be passed the name of the MP3 file to be edited. It then instantiates a new MP3::Tag object for this file and retrieves available tag information. Next, a series of prompts is generated, for the user to interactively enter title, artist, album, and year information. This data is then written back to the MP3 file via the write_tag() method discussed previously.

    The scripts above should have given you some idea of what you can do with MP3::Tag and perhaps even helped you organize your music collection.
     
    shabbir likes this.

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice