s/File/AudioFile/: rename files
[id3fs.git] / lib / ID3FS / AudioFile / Mp3.pm
1 package ID3FS::File::Mp3;
2
3 use strict;
4 use warnings;
5 use MP3::Tag;
6
7 sub new
8 {
9     my $proto=shift;
10     my $class=ref($proto) || $proto;
11     my $self={};
12     bless($self,$class);
13
14     $self->{path}=shift;
15     $self->{mp3}=MP3::Tag->new($self->{path});
16     $self->get_tags();
17     $self->{v1}=undef;
18     $self->{v1}=$self->{mp3}->{ID3v1} if(exists($self->{mp3}->{ID3v1}));
19     $self->{v2}=undef;
20     $self->{v2}=$self->{mp3}->{ID3v2} if(exists($self->{mp3}->{ID3v2}));
21
22     $self->{tags}={};
23
24     return $self;
25 }
26
27 sub choose
28 {
29     my ($self, $func, $verbose)=@_;
30     my $thing=undef;
31     if(defined($self->{v2}))
32     {
33         $thing=$self->{v2}->$func();
34     }
35     if(defined($self->{v1}) && (!defined($thing) || !length($thing)))
36     {
37         $thing=$self->{v1}->$func();
38     }
39     if(!defined($thing) || !length($thing))
40     {
41         warn("$self->{path}: no $func defined in ID3 tags\n") if($verbose);
42         return undef;
43     }
44     $thing=~s/\//-/g; # drop slashes
45     return $thing;
46 }
47
48 sub artist    { shift->choose("artist", 1); }
49 sub album     { shift->choose("album", 1);  }
50 # We don't care if year is not set
51 sub year      { shift->choose("year", 0);   }
52 sub audiotype { return "mp3";               }
53 sub haspic    { return undef;               } # FIXME
54 sub v1genre
55 {
56     my($self)=@_;
57     my $genre=undef;
58     if(defined($self->{v1}))
59     {
60         $genre=$self->{v1}->genre();
61         $genre =~ s/\//-/g if(defined($genre));
62     }
63     return $genre;
64 }
65
66 sub tags
67 {
68     my $self=shift;
69     return({}) unless(exists($self->{mp3}->{ID3v2}) && defined($self->{mp3}->{ID3v2}));
70     my $genre=$self->{mp3}->{ID3v2}->genre();
71     return({}) unless(defined($genre) && length($genre));
72     my @tags=split(/\s*,\s*/, $genre);
73     for my $tag (@tags)
74     {
75         if($tag=~/([^\/]+)\/(.*)/)
76         {
77             my $tagname=$1;
78             my $tagval=$2;
79             $tagval=~s/\//-/g;
80             $self->{tags}->{$tagname}=$tagval;
81         }
82         else
83         {
84             $self->{tags}->{$tag}=undef;
85         }
86     }
87     return $self->{tags};
88 }
89
90 sub get_tags
91 {
92     my ($self)=@_;
93     # MP3::Tag->get_tags shows cryptic debug info via print when it finds
94     # an unhandled id3v2 version, in addition to the warning, so use
95     # select to send prints to /dev/null
96     my $oldout=undef;
97     if(open(NULL,">/dev/null"))
98     {
99         $oldout=select(NULL);
100     }
101     eval { $self->{mp3}->get_tags; };
102     warn("$self->{path}: $@\n") if($@);
103     if(defined($oldout))
104     {
105         select($oldout);
106         close(NULL);
107     }
108 }
109
110 1;
111