MP3-Tag

 view release on metacpan or  search on metacpan

lib/MP3/Tag.pm  view on Meta::CPAN

Checks that extension is (case-insensitively) in the list given by
configuration variable C<writable_extensions>.

=cut

sub can_write ($) {
    my $self = shift;
    my @wr = @{ $self->get_config('is_writable') };	# Make copy
    return $wr[0] if @wr == 1 and not $wr[0] =~ /\D/;
    my $meth = shift @wr;
    $self->$meth(@wr);
}

sub writable_by_extension ($) {
    my $self = shift;
    my $wr = $self->get_config('writable_extensions');	# Make copy
    $self->extension_is(@$wr);
}

sub die_cant_write ($$) {
    my($self, $what) = (shift, shift);
    die $what, $self->interpolate("File %F is not writable per `is_writable' confuration variable, current value is `"),
		join(', ', @{$self->get_config('is_writable')}), "'";
}

sub can_write_or_die ($$) {
    my($self, $what) = (shift, shift);
    my $wr = $self->can_write;
    return $wr if $wr;
    $self->die_cant_write($what);
}

=item update_tags( [ $data,  [ $force2 ]] )

  $mp3 = MP3::Tag->new($filename);
  $mp3->update_tags();			# Fetches the info, and updates tags

  $mp3->update_tags({});		# Updates tags if needed/changed

  $mp3->update_tags({title => 'This is not a song'});	# Updates tags

This method updates ID3v1 and ID3v2 tags (the latter only if in-memory copy
contains any data, or $data does not fit ID3v1 restrictions, or $force2
argument is given)
with the the information about title, artist, album, year, comment, track,
genre from the hash reference $data.  The format of $data is the same as
one returned from autoinfo() (with or without the optional argument 'from').
The fields which are marked as coming from ID3v1 or ID3v2 tags are not updated
when written to the same tag.

If $data is not defined or missing, C<autoinfo('from')> is called to obtain
the data.  Returns the object reference itself to simplify chaining of method
calls.

This is probably the simplest way to set data in the tags: populate
$data and call this method - no further tinkering with subtags is
needed.

=cut

sub update_tags {
    my ($mp3, $data, $force2, $wr2) = (shift, shift, shift);

    $mp3->get_tags;
    $data = $mp3->autoinfo('from') unless defined $data;

#    $mp3->new_tag("ID3v1") unless $wr1 = exists $mp3->{ID3v1};
    unless (exists $mp3->{ID3v1}) {
	$mp3->can_write_or_die('update_tags() doing ID3v1: ');
	$wr2 = 1;
	$mp3->new_tag("ID3v1");
    }
    my $elt;
    for $elt (qw/title artist album year comment track genre/) {
	my $d = $data->{$elt};
	next unless defined $d;
	$d = [$d, ''] unless ref $d;
        $mp3->{ID3v1}->$elt( $d->[0] ) if $d->[1] ne 'ID3v1';
    }				# Skip what is already there...
    $mp3->{ID3v1}->write_tag;

    my $do_length
      = (defined $mp3->{ms}) ? ($mp3->get_config('update_length'))->[0] : 0;

    return $mp3
      if not $force2 and $mp3->{ID3v1}->fits_tag($data)
	and not exists $mp3->{ID3v2} and $do_length < 2;

#    $mp3->new_tag("ID3v2") unless exists $mp3->{ID3v2};
    unless (exists $mp3->{ID3v2}) {
	if (defined $wr2) {
	    $mp3->die_cant_write('update_tags() doing ID3v2: ') unless $wr2;
	} else {
	    $mp3->can_write_or_die('update_tags() doing ID3v2: ');
	}
	$mp3->new_tag("ID3v2");
    }
    for $elt (qw/title artist album year comment track genre/) {
	my $d = $data->{$elt};
	next unless defined $d;
	$d = [$d, ''] unless ref $d;
        $mp3->{ID3v2}->$elt( $d->[0] ) if $d->[1] ne 'ID3v2';
    }				# Skip what is already there...
    # $mp3->{ID3v2}->comment($data->{comment}->[0]);

    $mp3->set_id3v2_frame('TLEN', $mp3->{ms})
      if $do_length and not $mp3->have_id3v2_frame('TLEN');
    $mp3->{ID3v2}->write_tag;
    return $mp3;
}

sub _massage_genres ($;$) {   # Thanks to neil verplank for the prototype
    require MP3::Tag::ID3v1;
    my($data, $how) = (shift, shift);
    my $firstnum = (($how || 0) eq 'num');
    my $prefer_num = (($how || 0) eq 'prefer_num');
    my (%seen, @genres);	# find all genres in incoming data
    $data = $data->[0] if ref $data;
    # clean and split line on both null and parentheses
    $data =~ s/\s+/ /g;
    $data =~ s/\s*\0[\0\s]*/\0/g;



( run in 1.601 second using v1.01-cache-2.11-cpan-39bf76dae61 )