X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2FID3FS%2FAudioFile%2FMp3.pm;h=d51e0b0d45a11e9719980f80502438cf92e5202b;hb=c90fade565eeffaff51cc240c30e05f6e1f6e196;hp=2ed8e24e5a7f5c6c279c0de8426818400b727e6b;hpb=c59f9ef4a820793a58120c25d0c1a773afed79f8;p=id3fs.git diff --git a/lib/ID3FS/AudioFile/Mp3.pm b/lib/ID3FS/AudioFile/Mp3.pm index 2ed8e24..d51e0b0 100644 --- a/lib/ID3FS/AudioFile/Mp3.pm +++ b/lib/ID3FS/AudioFile/Mp3.pm @@ -1,4 +1,20 @@ -package ID3FS::File::Mp3; +# id3fs - a FUSE-based filesystem for browsing audio metadata +# Copyright (C) 2010 Ian Beckwith +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +package ID3FS::AudioFile::Mp3; use strict; use warnings; @@ -14,77 +30,72 @@ sub new $self->{path}=shift; $self->{mp3}=MP3::Tag->new($self->{path}); $self->get_tags(); - $self->{v1}=undef; - $self->{v1}=$self->{mp3}->{ID3v1} if(exists($self->{mp3}->{ID3v1})); - $self->{v2}=undef; - $self->{v2}=$self->{mp3}->{ID3v2} if(exists($self->{mp3}->{ID3v2})); - $self->{tags}={}; return $self; } -sub choose +sub set { - my ($self, $func, $verbose)=@_; - my $thing=undef; - if(defined($self->{v2})) + my ($self, $func, $value)=@_; + return $self->choose($func) unless($value); + unless(exists($self->{mp3}->{ID3v1})) + { + $self->{mp3}->new_tag("ID3v1"); + } + unless(exists($self->{mp3}->{ID3v2})) { - $thing=$self->{v2}->$func(); + $self->{mp3}->new_tag("ID3v2"); } - if(defined($self->{v1}) && (!defined($thing) || !length($thing))) + my $method=$func . "_set"; + $self->{mp3}->$method($value, 1); + return $value; +} + +sub choose +{ + my($self, $func)=@_; + my $thing=undef; + if(exists($self->{mp3}->{ID3v2})) { - $thing=$self->{v1}->$func(); + $thing=$self->{mp3}->{ID3v2}->$func(); } - if(!defined($thing) || !length($thing)) + if(exists($self->{mp3}->{ID3v1}) && (!defined($thing) || !length($thing))) { - warn("$self->{path}: no $func defined in ID3 tags\n") if($verbose); - return undef; + $thing=$self->{mp3}->{ID3v1}->$func(); } - $thing=~s/\//-/g; # drop slashes return $thing; } -sub artist { shift->choose("artist", 1); } -sub album { shift->choose("album", 1); } -# We don't care if year is not set -sub year { shift->choose("year", 0); } -sub audiotype { return "mp3"; } -sub haspic { return undef; } # FIXME +sub year { return(shift->set("year", @_)); } +sub artist { return(shift->set("artist", @_)); } +sub album { return(shift->set("album", @_)); } +sub track { return(shift->set("title", @_)); } +sub tracknum { return(shift->set("track", @_)); } +sub comment { return(shift->set("comment", @_)); } + +sub audiotype { return "mp3"; } +sub haspic { return undef; } # NEXTVERSION + sub v1genre { - my($self)=@_; - my $genre=undef; - if(defined($self->{v1})) + my($self, $val)=@_; + if($val) { - $genre=$self->{v1}->genre(); - $genre =~ s/\//-/g if(defined($genre)); + $self->{mp3}->new_tag("ID3v1") unless(defined($self->{mp3}->{ID3v1})); + $self->{mp3}->{ID3v1}->genre($val); + return $val; } + my $genre=undef; + $genre=$self->{ID3v1}->genre() if(defined($self->{ID3v1})); return $genre; } sub tags { my $self=shift; - return({}) unless(exists($self->{mp3}->{ID3v2}) && defined($self->{mp3}->{ID3v2})); - my $genre=$self->{mp3}->{ID3v2}->genre(); - return({}) unless(defined($genre) && length($genre)); - my @tags=split(/\s*,\s*/, $genre); - for my $tag (@tags) - { - if($tag=~/([^\/]+)\/(.*)/) - { - my $tagname=$1; - my $tagval=$2; - $tagval=~s/\//-/g; - $self->{tags}->{$tagname}=$tagval; - } - else - { - $self->{tags}->{$tag}=undef; - } - } - return $self->{tags}; + return() unless(exists($self->{mp3}->{ID3v2}) && defined($self->{mp3}->{ID3v2})); + return($self->{mp3}->{ID3v2}->genre()); } sub get_tags @@ -107,5 +118,129 @@ sub get_tags } } -1; +sub add_tags +{ + my($self, @tags)=@_; + my $existing=$self->tags(); + my @existing=split(/\s*,\s*/, $existing) if($existing); + my @merged=$self->uniq(@tags, @existing); + my $genre=join(', ', @merged); + return($self->set("genre", $genre)); +} + + +sub write +{ + my $self=shift; + $self->{mp3}->update_tags(); +} + +sub delete_artist { shift->delete("artist"); } +sub delete_album { shift->delete("album"); } +sub delete_track { shift->delete("song"); } +sub delete_tracknum { shift->delete("track"); } +sub delete_year { shift->delete("year"); } +sub delete_v1genre { shift->delete("v1genre"); } +sub delete_comment { shift->delete("comment"); } +sub delete_genre { shift->delete("genre"); } + +sub delete_tags +{ + my($self, @tags)=@_; + my $current=$self->tags(); + my @current=split(/\s*,\s*/, $current); + my %hash=(); + @hash{@current}=(); + for my $tag (@tags) + { + delete($hash{$tag}) if(exists($hash{$tag})); + } + my @tagsout=sort keys(%hash); + my $genre=join(', ', @tagsout); + if(length($genre)) + { + return($self->set("genre", $genre)); + } + else + { + return($self->delete_genre()); + } +} + +sub delete_all +{ + my($self)=@_; + if(exists($self->{mp3}->{ID3v1})) + { + $self->{mp3}->{ID3v1}->remove_tag; + } + if(exists($self->{mp3}->{ID3v2})) + { + $self->{mp3}->{ID3v2}->remove_tag; + } +} + +sub delete +{ + my($self, $thing)=@_; + + if(exists($self->{mp3}->{ID3v1}) && $thing ne "genre") + { + my $action=$thing; + $action="genre" if($action eq "v1genre"); + if($action eq "track") + { + $self->{mp3}->{ID3v1}->track("00"); + } + else + { + $self->{mp3}->{ID3v1}->$action(" "); + } + } + + if(exists($self->{mp3}->{ID3v2})) + { + print "2: remove: $thing\n"; + if($thing eq "artist") + { + $self->{mp3}->{ID3v2}->remove_frame("TPE1"); + $self->{mp3}->{ID3v2}->remove_frame("TPE2"); + } + elsif($thing eq "album") + { + $self->{mp3}->{ID3v2}->remove_frame("TALB"); + } + elsif($thing eq "song") + { + $self->{mp3}->{ID3v2}->remove_frame("TIT2"); + } + elsif($thing eq "track") + { + $self->{mp3}->{ID3v2}->remove_frame("TRCK"); + } + elsif($thing eq "year") + { + $self->{mp3}->{ID3v2}->remove_frame("TYER"); + $self->{mp3}->{ID3v2}->remove_frame("TDRC"); + } + elsif($thing eq "comment") + { + $self->{mp3}->{ID3v2}->remove_frame("COMM"); + } + elsif($thing eq "genre") + { + $self->{mp3}->{ID3v2}->remove_frame("TCON"); + } + } +} +sub uniq +{ + my ($self, @things)=@_; + my %hash=(); + @hash{@things}=(); + return(sort keys(%hash)); +} + + +1;