Oh, and cover art is a whole different challenge. Here's
how I do it (for ID3v2 and jpg images).
use constant COVERART_LOCATOR => "coverart";
use constant PICTURE_TYPE => "Cover (front)";
use constant PICTURE_COMMENT => "Cover Image";
use constant APIC => "APIC";
sub attach
{
# Find a suitable image and attach it to the suggested mp3 file
my($track,$mp3_file,$image_file) = @_;
return undef
if(!defined $image_file);
if(!-w $mp3_file)
{
# This shouldn't happen but...
chmod 0755,$mp3_file;
}
if(!-w $mp3_file)
{
carp("Cannot write to $mp3_file");
return undef;
}
my $mp3 = MP3::Tag->new($mp3_file);
if(!defined $mp3)
{
carp("Cannot read tags from $mp3_file");
return undef;
}
# Attempt to read the tags
$mp3->get_tags();
if(!defined $mp3->{ID3v2})
{
# Need to create a new set of tags
$mp3->new_tag("ID3v2");
}
if(!defined $mp3->{ID3v2})
{
carp("Cannot create ID3v2 tags in $mp3_file");
return undef;
}
my($mime_type,$image_data) = read_image($image_file);
return undef if(!defined $mime_type);
my $encoding = 0;
my @apic_parts = ($encoding, $mime_type,
picture_type_idx(PICTURE_TYPE),
PICTURE_COMMENT, $image_data);
if(defined $mp3->{ID3v2}->get_frame(APIC))
{
# Modifying an existing image
$mp3->{ID3v2}->change_frame(APIC,@apic_parts);
}
else
{
# Create a new frame
$mp3->{ID3v2}->add_frame(APIC,@apic_parts);
}
$mp3->{ID3v2}->write_tag();
return $image_file;
}
sub read_image
{
# Read the image file
my($file_name) = @_;
my $image_type;
my $image_data;
if(!-f $file_name)
{
error("Cannot read file \"$file_name\"");
return;
}
if($file_name =~ /\.jpg$/i)
{
$image_type = "jpg";
my $ifh = IO::File->new($file_name);
if(!defined $ifh)
{
error("Failed to open \"$file_name\"");
return;
}
binmode $ifh;
$image_data = "";
# This reads the data in 16k chunks, but the images should be
+small anyway
while(!$ifh->eof())
{
my $c = $ifh->read($image_data,1024*16,length($image_data)
+);
}
$ifh = undef;
}
if(!defined $image_type)
{
error("Does not yet support file type for \"$file_name\"");
return;
}
if(!defined $image_data)
{
error("Cannot extract $image_type data from \"$file_name\"");
return;
}
return("image/$image_type",$image_data);
}
sub picture_type_idx
{
# Given a picture type string convert it into a number suitable
# for MP3::Tag
my($picture_type) = @_;
# The picture types that are currently understood (from MP3::Tag::
+ID3v2):
my @picture_types =
("Other", "32x32 pixels 'file icon' (PNG only)", "Other file
+icon",
"Cover (front)", "Cover (back)", "Leaflet page",
"Media (e.g. lable side of CD)", "Lead artist/lead performe
+r/soloist"
,
"Artist/performer", "Conductor", "Band/Orchestra", "Compose
+r",
"Lyricist/text writer", "Recording Location", "During recor
+ding",
"During performance", "Movie/video screen capture",
"A bright coloured fish", "Illustration", "Band/artist logo
+type",
"Publisher/Studio logotype");
# This approach is easy to understand
for(my $i=0;$i<=$#picture_types;$i++)
{
if(lc($picture_type) eq lc($picture_types[$i]))
{
return chr($i);
}
}
error("The picture type \"$picture_type\" is not valid");
return chr(3);
}
Update:
This defines a new subroutine called attach(). The first parameter has
no affect (its important in my script but for your purposes you can ignore
it). Suppose you want to attach a file "foo/cool.jpg" to an mp3
file called "1.mp3" as the front cover, you would just do (untested)
attach("","1.mp3","foo/cool.jpg");
This, of course, requires that you add the appropriate packages and
copy the definition of the subroutine somewhere into your script.
Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
Read Where should I post X? if you're not absolutely sure you're posting in the right place.
Please read these before you post! —
Posts may use any of the Perl Monks Approved HTML tags:
- a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
|
For: |
|
Use: |
| & | | & |
| < | | < |
| > | | > |
| [ | | [ |
| ] | | ] |
Link using PerlMonks shortcuts! What shortcuts can I use for linking?
See Writeup Formatting Tips and other pages linked from there for more info.
|
|