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;
}
-
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 How to display code and escape characters
are good places to start.
|