For Programmers: Free Programming Magazines  


Home > Archive > PERL Beginners > October 2006 > MP3::Tag and Reading values from a Hash









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author MP3::Tag and Reading values from a Hash
Gav Ford

2006-10-22, 9:56 pm


Hello,

I'm just starting out here and hope someone can help, I think I've
gotten all over how to read values from a Hash.

Or it could be I've just got totally the wrong end of the stick.

The data in question is the album art attached to an MP3 file. I'm
trying to read it from the MP3 and save it as a file. I'm using a
module I got from cpan called MP3::Tag.

Here is my program so far, see if this makes things clearer.



#!/usr/bin/perl -w

use MP3::Tag;

chomp ($filename = $ARGV[0]);

print "Getting art for $filename \n";

$mp3 = MP3::Tag->new($filename);

$mp3->get_tags();

$tagdata = $mp3->{ID3v2} if exists $mp3->{ID3v2};

$title = ($tagdata->get_frame("TIT2"));
$artist = ($tagdata->get_frame("TPE1"));
$album = ($tagdata->get_frame("TALB"));

print "This is $title by $artist\, from the album $album.\n";
print "So I'll call the artwork file: $album\.jpg \n";


%artinfo = $tagdata->get_frame("PIC"); # doesn't seem to work?

$mp3->close();

$art = $artinfo{"_Data"}; # or it could fault


# write the art to file
open ARTWORK, ">$album.jpg" or die "File $album.jpg could not be opened.\n";
print ARTWORK $art;
close ARTWORK;



Things seem fine, It can read the artist, album and track names and all
this goes well. The documentation tells me that get->frame() will
return simple strings I can use and this is so.

For PIC it should return a Hash containing keys called 'Image Format',
'Picture Type', '_Data', 'Description' and 'encoding' and a string

The data I want is attached to the key '_Data'.

However it seems to return two strings 'HASH(0x8356294)' and 'Attached
picture' when I read it to an array or a set of comma separated scalars.

I feel that the value HASH(0x8356294) is somehow a clue, but I can't
figure out how to access what I want from it.

Please could somebody point me in the right direction?

-Gav

Xavier Mas

2006-10-23, 3:57 am

A Diumenge 22 Octubre 2006 18:38, Gav Ford va escriure:
> Hello,
>
> I'm just starting out here and hope someone can help, I think I've
> gotten all over how to read values from a Hash.
>
> Or it could be I've just got totally the wrong end of the stick.
>
> The data in question is the album art attached to an MP3 file. I'm
> trying to read it from the MP3 and save it as a file. I'm using a
> module I got from cpan called MP3::Tag.
>
> Here is my program so far, see if this makes things clearer.
>
>
>
> #!/usr/bin/perl -w
>
> use MP3::Tag;
>
> chomp ($filename = $ARGV[0]);
>
> print "Getting art for $filename \n";
>
> $mp3 = MP3::Tag->new($filename);
>
> $mp3->get_tags();
>
> $tagdata = $mp3->{ID3v2} if exists $mp3->{ID3v2};
>
> $title = ($tagdata->get_frame("TIT2"));
> $artist = ($tagdata->get_frame("TPE1"));
> $album = ($tagdata->get_frame("TALB"));
>
> print "This is $title by $artist\, from the album $album.\n";
> print "So I'll call the artwork file: $album\.jpg \n";
>
>
> %artinfo = $tagdata->get_frame("PIC"); # doesn't seem to work?
>
> $mp3->close();
>
> $art = $artinfo{"_Data"}; # or it could fault
>
>
> # write the art to file
> open ARTWORK, ">$album.jpg" or die "File $album.jpg could not be
> opened.\n"; print ARTWORK $art;
> close ARTWORK;
>
>
>
> Things seem fine, It can read the artist, album and track names and all
> this goes well. The documentation tells me that get->frame() will
> return simple strings I can use and this is so.
>
> For PIC it should return a Hash containing keys called 'Image Format',
> 'Picture Type', '_Data', 'Description' and 'encoding' and a string
>
> The data I want is attached to the key '_Data'.
>
> However it seems to return two strings 'HASH(0x8356294)' and 'Attached
> picture' when I read it to an array or a set of comma separated scalars.
>
> I feel that the value HASH(0x8356294) is somehow a clue, but I can't
> figure out how to access what I want from it.
>
> Please could somebody point me in the right direction?
>
> -Gav

to assing values to a (key of ) hash do as: $hash_name{$key_name} =
$value_name. to read same pair key/value use each function into a while loop:
while (($key_name, $value_name)) = each %hash_name). sign % indicates the
whole hash.

cheers,

--
Xavier Mas
kens

2006-10-23, 7:57 am


Gav Ford wrote:
> Hello,
>
> I'm just starting out here and hope someone can help, I think I've
> gotten all over how to read values from a Hash.
>
> Or it could be I've just got totally the wrong end of the stick.
>
> The data in question is the album art attached to an MP3 file. I'm
> trying to read it from the MP3 and save it as a file. I'm using a
> module I got from cpan called MP3::Tag.
>
> Here is my program so far, see if this makes things clearer.
>
>
>
> #!/usr/bin/perl -w
>
> use MP3::Tag;
>
> chomp ($filename = $ARGV[0]);
>
> print "Getting art for $filename \n";
>
> $mp3 = MP3::Tag->new($filename);
>
> $mp3->get_tags();
>
> $tagdata = $mp3->{ID3v2} if exists $mp3->{ID3v2};
>
> $title = ($tagdata->get_frame("TIT2"));
> $artist = ($tagdata->get_frame("TPE1"));
> $album = ($tagdata->get_frame("TALB"));
>
> print "This is $title by $artist\, from the album $album.\n";
> print "So I'll call the artwork file: $album\.jpg \n";
>
>
> %artinfo = $tagdata->get_frame("PIC"); # doesn't seem to work?
>
> $mp3->close();
>
> $art = $artinfo{"_Data"}; # or it could fault
>
>
> # write the art to file
> open ARTWORK, ">$album.jpg" or die "File $album.jpg could not be opened.\n";
> print ARTWORK $art;
> close ARTWORK;
>
>
>
> Things seem fine, It can read the artist, album and track names and all
> this goes well. The documentation tells me that get->frame() will
> return simple strings I can use and this is so.
>
> For PIC it should return a Hash containing keys called 'Image Format',
> 'Picture Type', '_Data', 'Description' and 'encoding' and a string
>
> The data I want is attached to the key '_Data'.
>
> However it seems to return two strings 'HASH(0x8356294)' and 'Attached
> picture' when I read it to an array or a set of comma separated scalars.
>
> I feel that the value HASH(0x8356294) is somehow a clue, but I can't
> figure out how to access what I want from it.
>
> Please could somebody point me in the right direction?
>
> -Gav


Actually, I was just playing around withthis module yesterday.
Here is the script I was using - thrown together pretty quickly, so
I hope it is clear. Takes a file name as command line argument.

Look at the code after the examples on complex frames for your specific
problem (dereferencing a hash reference).

use strict;
use warnings;
use MP3::Tag;

my $filename = shift;
die "No file name given\n" unless defined $filename;
die "$filename does not exist\n" unless -e $filename;

my $mp3 = MP3::Tag->new($filename);

my $info_hashref = $mp3->autoinfo();

foreach (keys %{$info_hashref})
{
printf "%10s: ${$info_hashref}{$_}\n", $_;
}

my $id3v2 = $mp3->{ID3v2} if exists $mp3->{ID3v2};

die unless $id3v2;

my @someDataIds = qw(TIT1 TIT2 IPLS TIT2 TCOM TMCL TIPL TLEN TORY TPE1
TPE2 TPE3 TPE4 TPPUB TRCK TYER);
foreach ( @someDataIds )
{
my ($info, $long) = $id3v2->get_frame($_);
print "$long\n $info\n" if $info;
}

#--------------------------------------------------------------------------------
# Example of getting a complex frame
#--------------------------------------------------------------------------------
my $commentsHashRef = $id3v2->get_frame('COMM');

foreach (keys %{$commentsHashRef})
{
printf "%10s: ${$commentsHashRef}{$_}\n", $_;
}

#----------------------------------------------------------------------------------
# Example referencing a field in a complex frame
#----------------------------------------------------------------------------------
print "COMMENTS TEXT: $commentsHashRef->{Text}\n" if
$commentsHashRef->{Text};

HTH,
Ken

Gav Ford

2006-10-23, 7:57 am

xavier mas wrote:
> to assing values to a (key of ) hash do as: $hash_name{$key_name} =
> $value_name. to read same pair key/value use each function into a while loop:
> while (($key_name, $value_name)) = each %hash_name). sign % indicates the
> whole hash.
>


Thanks for the help, I"m sorry if I'm a bit slow. With your help I've
got it working now.

So I can't access a value from the hash directly? I have to step though
until I hit the key I want?

The other mistake I was making seemed to be I was trying read the Hash
as just %artinfo instead of assigning to it as $artinfo and read from it
as %$artinfo.

I don't really understand when to use %$ and when to use % or $ to read
and write from and to a Hash. Would someone be so kind as to giving me
a simple explanation?

-Gav



Here is the working version of my program:


#!/usr/bin/perl -w

use MP3::Tag;

chomp ($filename = $ARGV[0]);

print "Getting art for $filename \n";

$mp3 = MP3::Tag->new($filename);

$mp3->get_tags();

$tagdata = $mp3->{ID3v2} if exists $mp3->{ID3v2};

$title = ($tagdata->get_frame("TIT2"));
$artist = ($tagdata->get_frame("TPE1"));
$album = ($tagdata->get_frame("TALB"));

print "This is $title by $artist\, from the album $album.\n";
print "So I'll call the artwork file: $album\.jpg \n";


$artinfo = $tagdata->get_frame("PIC"); # doesn't seem to work?

$mp3->close();

while (($key, $value) = each (%$artinfo)) {

if ($key eq "_Data") {

$art = $value;

}

}


# write the art to file
open ARTWORK, ">$album.jpg" or die "File $album.jpg could not be opened.\n";
print ARTWORK $art;
close ARTWORK;



kens

2006-10-23, 6:57 pm


Gav Ford wrote:
> xavier mas wrote:
>
> Thanks for the help, I"m sorry if I'm a bit slow. With your help I've
> got it working now.
>
> So I can't access a value from the hash directly? I have to step though
> until I hit the key I want?


No, in my case I had the following line to access a field directly:
print "COMMENTS TEXT: $commentsHashRef->{Text}\n" if
$commentsHashRef->{Text};

In your case, it appears, you would use:
$artinfo->{_Data}

>
> The other mistake I was making seemed to be I was trying read the Hash
> as just %artinfo instead of assigning to it as $artinfo and read from it
> as %$artinfo.
>
> I don't really understand when to use %$ and when to use % or $ to read
> and write from and to a Hash. Would someone be so kind as to giving me
> a simple explanation?
>


$mp3->{ID3v2} is a "reference" to a hash, not a hash, so you could not
use the
% operator with it. The documentation for MP3::Tag should note this.
And, when you saw values of HASH(...) that would also indicate you have
a
has reference.

For info on references, issue the following command to see the
documentation.

perldoc perlref

Ken

> -Gav
>
>
>
> Here is the working version of my program:
>
>
> #!/usr/bin/perl -w
>
> use MP3::Tag;
>
> chomp ($filename = $ARGV[0]);
>
> print "Getting art for $filename \n";
>
> $mp3 = MP3::Tag->new($filename);
>
> $mp3->get_tags();
>
> $tagdata = $mp3->{ID3v2} if exists $mp3->{ID3v2};
>
> $title = ($tagdata->get_frame("TIT2"));
> $artist = ($tagdata->get_frame("TPE1"));
> $album = ($tagdata->get_frame("TALB"));
>
> print "This is $title by $artist\, from the album $album.\n";
> print "So I'll call the artwork file: $album\.jpg \n";
>
>
> $artinfo = $tagdata->get_frame("PIC"); # doesn't seem to work?
>
> $mp3->close();
>
> while (($key, $value) = each (%$artinfo)) {
>
> if ($key eq "_Data") {
>
> $art = $value;
>
> }
>
> }
>
>
> # write the art to file
> open ARTWORK, ">$album.jpg" or die "File $album.jpg could not be opened.\n";
> print ARTWORK $art;
> close ARTWORK;


Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com