c5dac342a97cd59505a802953a5b9510ed6d271f
[id3fs.git] / lib / ID3FS / File / 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     # FIXME
23     $self->{tags}={};
24
25     return $self;
26 }
27
28 sub choose
29 {
30     my ($self, $func, $verbose)=@_;
31     my $thing=undef;
32     if(defined($self->{v2}))
33     {
34         $thing=$self->{v2}->$func();
35     }
36     if(defined($self->{v1}) && (!defined($thing) || !length($thing)))
37     {
38         $thing=$self->{v1}->$func();
39     }
40     if(!defined($thing) || !length($thing))
41     {
42         warn("$self->{path}: no $func defined in ID3 tags\n") if($verbose);
43         return undef;
44     }
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     if(defined($self->{v1}))
58     {
59         return $self->{v1}->genre();
60     }
61 }
62
63 sub tags
64 {
65     my $self=shift;
66     return({}) unless(exists($self->{mp3}->{ID3v2}) && defined($self->{mp3}->{ID3v2}));
67     my $genre=$self->{mp3}->{ID3v2}->genre();
68     return({}) unless(defined($genre) && length($genre));
69     my @tags=split(/\s*,\s*/, $genre);
70     for my $tag (@tags)
71     {
72         if($tag=~/([^\/]+)\/(.*)/)
73         {
74             my $tagname=$1;
75             my $tagval=$2;
76             $tagval=~s/\//-/g;
77             $self->{tags}->{$tagname}=$tagval;
78         }
79         else
80         {
81             $self->{tags}->{$tag}=undef;
82         }
83     }
84     return $self->{tags};
85 }
86
87 sub get_tags
88 {
89     my ($self)=@_;
90     # MP3::Tag->get_tags shows cryptic debug info via print when it finds
91     # an unhandled id3v2 version, in addition to the warning, so use
92     # select to send prints to /dev/null
93     my $oldout=undef;
94     if(open(NULL,">/dev/null"))
95     {
96         $oldout=select(NULL);
97     }
98     eval { $self->{mp3}->get_tags; };
99     warn("$self->{path}: $@\n") if($@);
100     if(defined($oldout))
101     {
102         select($oldout);
103         close(NULL);
104     }
105 }
106
107 1;
108