8133c915dd746061b8aea975130cd4a1212fae9a
[id3fs.git] / lib / ID3FS / AudioFile / Mp3.pm
1 # id3fs - a FUSE-based filesystem for browsing audio metadata
2 # Copyright (C) 2010  Ian Beckwith <ianb@erislabs.net>
3 #
4 # This program is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation, either version 3 of the License, or
7 # (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
17 package ID3FS::AudioFile::Mp3;
18
19 use strict;
20 use warnings;
21 use MP3::Tag;
22
23 sub new
24 {
25     my $proto=shift;
26     my $class=ref($proto) || $proto;
27     my $self={};
28     bless($self,$class);
29
30     $self->{path}=shift;
31     $self->{mp3}=MP3::Tag->new($self->{path});
32     $self->get_tags();
33     $self->{v1}=undef;
34     $self->{v1}=$self->{mp3}->{ID3v1} if(exists($self->{mp3}->{ID3v1}));
35     $self->{v2}=undef;
36     $self->{v2}=$self->{mp3}->{ID3v2} if(exists($self->{mp3}->{ID3v2}));
37
38     $self->{tags}={};
39
40     return $self;
41 }
42
43 sub choose
44 {
45     my ($self, $func)=@_;
46     my $thing=undef;
47     if(defined($self->{v2}))
48     {
49         $thing=$self->{v2}->$func();
50     }
51     if(defined($self->{v1}) && (!defined($thing) || !length($thing)))
52     {
53         $thing=$self->{v1}->$func();
54     }
55     return $thing;
56 }
57
58 sub artist    { shift->choose("artist"); }
59 sub album     { shift->choose("album");  }
60 # We don't care if year is not set
61 sub year      { shift->choose("year");   }
62 sub audiotype { return "mp3";            }
63 sub haspic    { return undef;            } # NEXTVERSION
64
65 sub v1genre
66 {
67     my($self)=@_;
68     my $genre=undef;
69     $genre=$self->{v1}->genre() if(defined($self->{v1}));
70     return $genre;
71 }
72
73 sub tags
74 {
75     my $self=shift;
76     return() unless(exists($self->{mp3}->{ID3v2}) && defined($self->{mp3}->{ID3v2}));
77     return($self->{mp3}->{ID3v2}->genre());
78 }
79
80 sub get_tags
81 {
82     my ($self)=@_;
83     # MP3::Tag->get_tags shows cryptic debug info via print when it finds
84     # an unhandled id3v2 version, in addition to the warning, so use
85     # select to send prints to /dev/null
86     my $oldout=undef;
87     if(open(NULL,">/dev/null"))
88     {
89         $oldout=select(NULL);
90     }
91     eval { $self->{mp3}->get_tags; };
92     warn("$self->{path}: $@\n") if($@);
93     if(defined($oldout))
94     {
95         select($oldout);
96         close(NULL);
97     }
98 }
99
100 1;