Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris

comment on

( #3333=superdoc: print w/replies, xml ) Need Help??

I recently purchased an Android 2.0 phone, I was shocked to find that none of my mp3 files worked correctly. This short script fixed the problem.

# Android 2.0 reads mp3 song information # from the ID3v1 tag. Most modern # systems use the more flexible ID3v2 tags. # This means that mp3 files that work perfectly # well on iTunes and other modern systems are # shown as being by "Unknown Artist". # # This script finds all the mp3 files within # a directory and makes sure that the ID3v1 tags # and the ID3v2 tags are both filled in. # # This fixes the issue on my Motorola Milestone # (that is the Motorola Droid in the US) # use strict; use warnings; use MP3::Tag; use Carp; # We parse the command line to pick a directory, # this is easier my $start_dir = "."; foreach my $file_name (list_mp3_files($start_dir)) { # No point in doing anything if we can't # write to the file if(!-w $file_name) { carp("Cannot write to $file_name"); next; } my $mp3 = MP3::Tag->new($file_name); if(!defined $mp3) { carp("Failed to read tags from $file_name"); next; } $mp3->get_tags(); # Do we have the two tag types? my($id3v1,$id3v2); if(defined $mp3->{ID3v1}) { $id3v1 = $mp3->{ID3v1}; } else { $id3v1 = $mp3->new_tag("ID3v1"); } if(defined $mp3->{ID3v2}) { $id3v2 = $mp3->{ID3v2}; } else { $id3v2 = $mp3->new_tag("ID3v2"); } # The ID3v1 tag just provides methods, # so rather than doing some Perlish magic # to have a single piece of code that # uses the ID3v2 flag ("TIT2" or whatever) # I take the simplest (but most long # winded) approach # Read the artist my $artist = $id3v2->artist(); $artist = $id3v1->artist() if(!defined $artist); if(!defined $artist) { carp("Cannot get artist for $file_name"); $artist = "Artist of $file_name"; } # Save the artist $id3v2->artist($artist); $id3v1->artist($artist); my $album = $id3v2->album(); $album = $id3v1->album() if(!defined $album); if(!defined $album) { carp("Cannot get album for $file_name"); $album = "Album of $file_name"; } $id3v2->album($album); $id3v1->album($album); my $track = $id3v2->track(); $track = $id3v1->track() if(!defined $track); if(!defined $track) { carp("Cannot get track for $file_name"); # Magic track num to tell us we had # unknown value $track = 99; } $id3v2->track($track); $id3v1->track($track); my $year = $id3v2->year(); $year = $id3v1->year() if(!defined $year); if(!defined $year) { carp("Cannot get year for $file_name"); # If we don't have a year just ignore } else { $id3v2->year($year); $id3v1->year($year); } # The song() method is depreciated, but works # for ID2v1 my $title = $id3v2->title(); $title = $id3v1->song() if(!defined $title); if(!defined $title) { carp("Cannot get title for $file_name"); $title = "Song: $file_name"; } $id3v2->title($title); $id3v1->song($title); # Finally save the tags $id3v1->write_tag(); $id3v2->write_tag(); } # All done exit 0; sub list_mp3_files { # List all the mp3 files my($dir) = @_; local(*DIR); my @results; # Make sure we complete the dir scan before # doing any recursive calls opendir(DIR,$dir); my @files = readdir(DIR); closedir(DIR); foreach my $file (@files) { # Ignore . and .. next if($file =~ /^\.\.?$/); if(-d "$dir/$file") { # If we encounter a subdir then scan it push @results,list_mp3_files("$dir/$file"); next; } # We just match files that have \.mp3 at the # end of the name if($file =~ /\.mp3$/i) { push @results,"$dir/$file"; } } return @results; }

In reply to Fixing mp3 tags for Android 2.0 by hawtin

Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":

  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or or How to display code and escape characters are good places to start.
Log In?

What's my password?
Create A New User
Domain Nodelet?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (3)
As of 2022-05-16 19:59 GMT
Find Nodes?
    Voting Booth?
    Do you prefer to work remotely?

    Results (63 votes). Check out past polls.