X-Git-Url: https://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2FID3FS%2FAudioFile%2FMp3.pm;h=2b90b5dad1a2e84d94e89e98c46333aa25d1e83b;hb=08717313d5feba3f77f848b6409ec46263ed548e;hp=cce6a29c6fa72ec9f8b54f49fa70ddc89e536405;hpb=261cfc3301a9908e34ef38f3f0792b08a4412ff7;p=id3fs.git diff --git a/lib/ID3FS/AudioFile/Mp3.pm b/lib/ID3FS/AudioFile/Mp3.pm index cce6a29..2b90b5d 100644 --- a/lib/ID3FS/AudioFile/Mp3.pm +++ b/lib/ID3FS/AudioFile/Mp3.pm @@ -19,6 +19,7 @@ package ID3FS::AudioFile::Mp3; use strict; use warnings; use MP3::Tag; +use MP3::Info; sub new { @@ -28,7 +29,8 @@ sub new bless($self,$class); $self->{path}=shift; - $self->{mp3}=MP3::Tag->new($self->{path}); + $self->{mp3tag}=MP3::Tag->new($self->{path}); + $self->{mp3info}=MP3::Info->new($self->{path}); $self->get_tags(); $self->{tags}={}; @@ -39,16 +41,16 @@ sub set { my ($self, $func, $value)=@_; return $self->choose($func) unless($value); - unless(exists($self->{mp3}->{ID3v1})) + unless(exists($self->{mp3tag}->{ID3v1})) { - $self->{mp3}->new_tag("ID3v1"); + $self->{mp3tag}->new_tag("ID3v1"); } - unless(exists($self->{mp3}->{ID3v2})) + unless(exists($self->{mp3tag}->{ID3v2})) { - $self->{mp3}->new_tag("ID3v2"); + $self->{mp3tag}->new_tag("ID3v2"); } my $method=$func . "_set"; - $self->{mp3}->$method($value, 1); + $self->{mp3tag}->$method($value, 1); return $value; } @@ -56,34 +58,54 @@ sub choose { my($self, $func)=@_; my $thing=undef; - if(exists($self->{mp3}->{ID3v2})) + if(exists($self->{mp3tag}->{ID3v2})) { - $thing=$self->{mp3}->{ID3v2}->$func(); + $thing=$self->{mp3tag}->{ID3v2}->$func(); } - if(exists($self->{mp3}->{ID3v1}) && (!defined($thing) || !length($thing))) + if(exists($self->{mp3tag}->{ID3v1}) && (!defined($thing) || !length($thing))) { - $thing=$self->{mp3}->{ID3v1}->$func(); + $thing=$self->{mp3tag}->{ID3v1}->$func(); } return $thing; } -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 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 +# we only set v2 genre +sub genre +{ + my ($self, $value)=@_; + if($value) + { + if(exists($self->{mp3tag}->{ID3v2})) + { + $self->{mp3tag}->{ID3v2}->remove_frame("TCON"); + } + else + { + $self->{mp3tag}->new_tag("ID3v2"); + } + $self->{mp3tag}->{ID3v2}->add_frame("TCON", $value); + + } + return($self->{mp3tag}->{ID3v2}->genre()); +} + sub v1genre { my($self, $val)=@_; if($val) { - $self->{mp3}->new_tag("ID3v1") unless(defined($self->{mp3}->{ID3v1})); - $self->{mp3}->{ID3v1}->genre($val); + $self->{mp3tag}->new_tag("ID3v1") unless(defined($self->{mp3tag}->{ID3v1})); + $self->{mp3tag}->{ID3v1}->genre($val); return $val; } my $genre=undef; @@ -94,8 +116,8 @@ sub v1genre sub tags { my $self=shift; - return() unless(exists($self->{mp3}->{ID3v2}) && defined($self->{mp3}->{ID3v2})); - return($self->{mp3}->{ID3v2}->genre()); + return() unless(exists($self->{mp3tag}->{ID3v2}) && defined($self->{mp3tag}->{ID3v2})); + return($self->{mp3tag}->{ID3v2}->genre()); } sub get_tags @@ -109,7 +131,7 @@ sub get_tags { $oldout=select(NULL); } - eval { $self->{mp3}->get_tags; }; + eval { $self->{mp3tag}->get_tags; }; warn("$self->{path}: $@\n") if($@); if(defined($oldout)) { @@ -118,10 +140,185 @@ sub get_tags } } +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(); + if(exists($self->{mp3tag}->{ID3v1})) + { + my $del=1; + my $artist=$self->{mp3tag}->{ID3v1}->artist(); + $del=0 if($artist && $artist =~ /\S+/); + my $album=$self->{mp3tag}->{ID3v1}->album(); + $del=0 if($album && $album =~ /\S+/); + my $track=$self->{mp3tag}->{ID3v1}->title(); + $del=0 if($track && $track =~ /\S+/); + my $tracknum=$self->{mp3tag}->{ID3v1}->track(); + $del=0 if($tracknum && $tracknum !~ /^0+$/); + my $genre=$self->{mp3tag}->{ID3v1}->genre(); + $del=0 if($genre && $genre =~ /\S+/); + my $comment=$self->{mp3tag}->{ID3v1}->comment(); + $del=0 if($comment && $comment =~ /\S+/); + my $year=$self->{mp3tag}->{ID3v1}->year(); + $del=0 if($year && $year =~ /\S+/ && $year !~ /^0+$/); + if($del) + { + $self->{mp3tag}->{ID3v1}->remove_tag; + } + else + { + $self->{mp3tag}->{ID3v1}->write_tag; + } + } + if(exists($self->{mp3tag}->{ID3v2})) + { + my $frames=$self->{mp3tag}->{ID3v2}->get_frame_ids(); + if($frames && scalar(keys(%$frames))) + { + $self->{mp3tag}->{ID3v2}->write_tag; + } + else + { + $self->{mp3tag}->{ID3v2}->remove_tag; + } + } +} + +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->{mp3tag}->{ID3v1})) + { + $self->{mp3tag}->{ID3v1}->remove_tag; + } + if(exists($self->{mp3tag}->{ID3v2})) + { + $self->{mp3tag}->{ID3v2}->remove_tag; + } +} + +sub delete +{ + my($self, $thing)=@_; + + if(exists($self->{mp3tag}->{ID3v1}) && $thing ne "genre") + { + my $action=$thing; + $action="genre" if($action eq "v1genre"); + if($action eq "track") + { + $self->{mp3tag}->{ID3v1}->track("00"); + } + else + { + $self->{mp3tag}->{ID3v1}->$action(" "); + } + } + + if(exists($self->{mp3tag}->{ID3v2})) + { + if($thing eq "artist") + { + $self->{mp3tag}->{ID3v2}->remove_frame("TPE1"); + $self->{mp3tag}->{ID3v2}->remove_frame("TPE2"); + } + elsif($thing eq "album") + { + $self->{mp3tag}->{ID3v2}->remove_frame("TALB"); + } + elsif($thing eq "song") + { + $self->{mp3tag}->{ID3v2}->remove_frame("TIT2"); + } + elsif($thing eq "track") + { + $self->{mp3tag}->{ID3v2}->remove_frame("TRCK"); + } + elsif($thing eq "year") + { + $self->{mp3tag}->{ID3v2}->remove_frame("TYER"); + $self->{mp3tag}->{ID3v2}->remove_frame("TDRC"); + } + elsif($thing eq "comment") + { + $self->{mp3tag}->{ID3v2}->remove_frame("COMM"); + } + elsif($thing eq "genre") + { + $self->{mp3tag}->{ID3v2}->remove_frame("TCON"); + } + } } +sub uniq +{ + my ($self, @things)=@_; + my %hash=(); + @hash{@things}=(); + return(sort keys(%hash)); +} + +sub channels +{ + my($self)=@_; + return undef unless($self->{mp3info}); + return( ($self->{mp3info}->stereo()) ? 2 : 1 ); +} + +sub bitrate +{ + my($self)=@_; + return undef unless($self->{mp3info}); + return( int($self->{mp3info}->bitrate()) ); +} + +sub samplerate +{ + my($self)=@_; + return undef unless($self->{mp3info}); + return(int($self->{mp3info}->frequency() * 1000)); +} + + 1;