Audio-M4P

 view release on metacpan or  search on metacpan

lib/Audio/M4P/QuickTime.pm  view on Meta::CPAN



# Get cover art--returns a reference to an array of cover artwork
sub GetCoverArt {
    my ($self) = @_;
    my @covr = $self->FindAtom('covr') or return;
    my @artwork = ();
    foreach my $atm (@covr) {
        my @data_atms = $atm->Contained('data') or next;
        foreach my $dt ( @data_atms ) {
			push @artwork, substr( $dt->data, 8 );
		}
    }
    return \@artwork;
}


# remove all cover art, return number of covers removed
# does not remove an empty covr atom (one without cover data)
# but otherwise will remove covr atoms as well as cover data
sub DeleteAllCoverArt {
    my ($self) = @_;
    my $removed = 0;
    my @covr = $self->FindAtom('covr');
    foreach my $atm (@covr) {
		my @atoms = $atm->Contained('data') or next;
		my $siz  = $atm->size;
		my $pos  = $atm->start;
		$atm->selfDelete() or next;
		$self->FixStco( $siz, $pos );
		$removed += scalar @atoms;	
	}
	return $removed;	
}

# add a single album cover by EITHER adding one covr atom 
# OR adding one cover's data to an existing covr atom
# takes a argument which should be a compatible graphic format binary
# but does NO checks for compatibility with iTunes' cover art display
# type OUGHT TO BE 13 for jpeg, 14 for png graphics format,
# but method DOES NOT CHECK for type except will default to 13 
# if no type argument provided
sub AddCoverArt {
    my ($self, $art, $type) = @_;
    $type = 13 unless $type;
    my $covr = $self->FindAtom('covr');
    if( !$covr )
    {
		my $ilst = $self->FindAtom('ilst') || $self->MakeIlstAtom || return;
        $ilst->insertNew( 'covr', '' );
        $self->FixStco( -8, $ilst->start );
        return unless $covr = $self->FindAtom('covr');
    }
	$covr->insertNew( 'data', pack( 'NN', $type, 0 ) . $art );
	$self->FixStco( -16 - length $art, $covr->start );
	return 1;
}

#-----------------------------------------------------------

# MP3::Tag analogs, but more fields, and allow setting of tags

sub autoinfo {
    my ($self) = @_;
    my $tags = $self->GetMetaInfo;
    return (
        $tags->{TITLE},   $tags->{TRKN}, $tags->{ARTIST}, $tags->{ALBUM},
        $tags->{COMMENT}, $tags->{YEAR}, $tags->{GENRE}
    );
}

sub title {
    my ( $self, $new_tag ) = @_;
    $self->SetMetaInfo( 'TITLE', $new_tag, 1 ) if $new_tag;
    my $tags = $self->GetMetaInfo;
    return $tags->{TITLE} || '';
}

sub album {
    my ( $self, $new_tag ) = @_;
    $self->SetMetaInfo( 'ALBUM', $new_tag, 1 ) if $new_tag;
    my $tags = $self->GetMetaInfo;
    return $tags->{ALBUM} || '';
}

sub artist {
    my ( $self, $new_tag ) = @_;
    $self->SetMetaInfo( 'ARTIST', $new_tag, 1 ) if $new_tag;
    my $tags = $self->GetMetaInfo;
    return $tags->{ARTIST} || '';
}

sub comment {
    my ( $self, $new_tag ) = @_;
    $self->SetMetaInfo( 'COMMENT', $new_tag, 1 ) if $new_tag;
    my $tags = $self->GetMetaInfo;
    return $tags->{COMMENT} || '';
}

sub year {
    my ( $self, $new_tag ) = @_;
    $self->SetMetaInfo( 'YEAR', $new_tag, 1 ) if $new_tag;
    my $tags = $self->GetMetaInfo;
    return $tags->{YEAR} || 0;
}

sub genre {
    my ( $self, $new_tag ) = @_;
    $self->SetMetaInfo( 'GENRE', pack( "n", $new_tag ), 1 ) if $new_tag;
    my $tags = $self->GetMetaInfo;
    return $tags->{GENRE} || '';
}

sub genre_as_text {
    my ( $self, $new_tag ) = @_;
    my ( $i, $genre_num );
    if ($new_tag) {
        $self->genre( genre_text_to_genre_num($new_tag) );
    }
    return genre_num_to_genre_text( $self->genre );
}

lib/Audio/M4P/QuickTime.pm  view on Meta::CPAN


=item B<GetMetaInfo>

 my $hashref = $qt->GetMetaInfo(1);
 while(my($tag, $value) = each %{$hashref}) { 
    print "$tag => $value\n";
 }

Returns a hash reference to meta tag information. Attempts to be compatible 
with tag information formats in MP3::Info and MP4::Info. Potential tags are 
AAID, ALBUM, ARTIST, COMMENT, COM, CPIL, CPRT, YEAR, DISK, GENRE, GRP, NAM,  
RTNG, TMPO, TOO, TRKN, and WRT. Note that, due to preservation of compatibility 
with MP3::Info by returning tag info as a hash reference, duplicate entries of 
the same tag name, such as multiple comment fields, will not be returned in the hash 
reference. An optional second argument, if 1 or true, should convert some 
binary fields to text in the tags, for instance 
 my $hashref = $qt->GetMetaInfo(1);

=item B<GetMP4Info>

 my $hashref = $qt->GetMP4Info;
 while(my($tag, $value) = each %{$hashref}) { 
    print "$tag => $value\n";
 }

Returns a hash reference to MP3 tag audio information. Attempts to be compatible 
with tag information formats in MP3::Info and MP4::Info. Potential tags are 
LAYER (1), VERSION (4), SIZE, SECONDS, SS, MM, and BITRATE. 

=item B<SetMetaInfo>

 my $comment = "After paying for this music file, I have fair use rights to change it.";

 $qt->SetMetaInfo(COMMENT => $comment);
 $qt->SetMetaInfo(GENRE => "Bebop", 1, 'day');

Set a meta information field. The third argument, if given and true, indicates
that the program should replace all instances of meta data of this type with 
the new entry, rather than adding the tag to the existing meta data. The fourth 
argument, if given and true, indicated a tag value before which the new tag is
to be placed in the file. The fifth argument indicates the values are in text 
form, ie for meta type 'trkn', value is something like 'Track 5 of 11'.

=item B<iTMS_MetaInfo>

 my $hashref = $qt->iTMS_MetaInfo;
 
 $hashref->{comments} = "A new comment";
 $qt->iTMS_MetaInfo($hashref);
 
Get or set a meta information field via a hash reference to an Apple iTMS
type dict data structure. Possible fields are copyright, comments, 
songName, genre, playlistArtistName, genreID, composerName, playlistName,
year, trackNumber, trackCount, discNumber, discCount, and artworkURL. iTMS 
meta data entries may not be compatible with MP3::Info type meta data. An
optional second argument, if true, prevents the method from replacing old meta
information, as in $qt->iTMS_MetaInfo($hashref, 1);

Note that although this method of manipulating M4P data tags is closest to the 
way iTMS and iTunes do metadata, it may be less intuitive for most audio tag 
programmers than the MP3::Tag and Audio::TagLib compatible methods below.

=item B<GetCoverArt>

  my $artwork = $qt->GetCoverArt();
  foreach my $pic (@{$artwork}) { 
      # do stuff with art
  }
  
Returns a reference to an array of cover artwork. Note: the artwork routines
were suggested and largely contributed by pucklock. (Thanks!)


=item B<DeleteAllCoverArt>

  $qt->DeleteAllCoverArt;

Delete all cover art from the file. This removes all data from the covr atom, 
if any.  Returns the number of cover data atoms deleted.


=item B<AddCoverArt>


  $qt->AddCoverArt( $jpeg_art, 13 );  # $jpeg_art is an iTunes compatible jpeg 
  $qt->AddCoverArt( $jpeg_art );      # the same as above, defaults to type 13
  $qt->AddCoverArt( $png_art, 14 );   # PNG graphics are data type 14

Add cover artwork to the file. Creates a new covr atom if needed. Returns 1 if 
successful, otherwise null.

The method adds a single album cover by either adding one covr atom or 
by adding one cover's data to an existing covr atom. Takes a argument which 
should be a compatible graphic format binary, but does NO checks for 
compatibility with iTunes' cover art display. The type should be 13 
for jpeg, 14 for png graphics format, but defaults to 13.


=back

=head2 MP3::Tag and Audio::TagLib Compatible Functions

=over 4

=item B<autoinfo>

  my($title, $tracknum, $artist, $album, $comment, $year, $genre) =
    $qt->autoinfo;

Returns an array of tag metadata, similar to the same method in MP3::Tag.

=item B<album>

  my $album = $qt->album;
  $new_album = "My New Album Name";
  $qt->album($new_album);

Get and set title tag data.
Similar to the same method in MP3::TagLib.

Note this and other tag functions below will usually return the empty 
string "" when there is tag data lacking, unless an integer result is expected, 
in which case 0 is returned. This is for compatibility with MP3::Tag and 
Audio::TagLib's implementation of these methods.

=item B<artist>

  my $artist = $qt->artist;
  $new_artist = "My New Artist";
  $qt->artist($new_artist);

Get and set artist tag data.
Similar to the same method in MP3::TagLib.

=item B<comment>

  my $comment = $qt->comment;
  $new_comment = "My Comment Goes Here";
  $qt->comment($new_comment);

Get and set comment tag data.
Similar to the same method in MP3::Tag.

=item B<genre>

  my $genre = $qt->genre;
  $new_genre = 18;
  $qt->genre($new_genre);

Get and set genre tag data BY NUMBER.

=item B<genre_as_text>

  my $text_genre = $qt->genre_as_text;
  $new_genre = "Rock";
  $qt->genre_as_text($new_genre);

Get and set genre tag data as text. Note that the given text tag must exist 
in the genre database to work. See the "our @genre_strings" object in the 
code, which can be imported by the declaration "our @genre_strings;" 
in code using the module.

=item B<title>

  my $title = $qt->title;
  $new_title = "My New One";
  $qt->title($new_title);

Get and set title tag data.
Similar to the same method in MP3::Tag.

=item B<track>

  my $track = $qt->track;
  my $new_track = 3;
  $qt->track($new_track);

Get or set the track number.

=item B<tracks>

  my ($track, $count) = $qt->tracks;
  my $new_track_number = 3;
  my $total_tracks_on_CD = 17;
  $qt->tracks($new_track_number, $total_tracks_on_CD);

Get or set both the track number and the total tracks on the originating media 
work. Not actually an MP3::Tag method, but MP4 files, unlike many MP3 files, 
regularly contain both track number and the total originating CD's track count.

=item B<total>

  my $total = $qt->total;
  my $new_total = 15;
  $qt->total($new_total);

Get or set the track total number.

=item B<year>

  my $year = $qt->year;
  $new_year = "My New One";
  $qt->year($new_year);

Get and set year tag data.
Similar to the same method in MP3::Tag.

=item B<all_tags>

  my $tref = $qt->all_tags( album => "My new album", genre => 21 );
  print $tref->{artist};

Similar to the Audio::File::Tag B<all> method. Set or get all the above tags. 
To set the tags pass a hash reference with the names of the tags as keys and 
the tag values as hash values. Returns a hash reference if no argument is 
specified.

The following tag names are supported by this method:
album
artist
comment
genre   ( the integer value genre )
title
track
total

=back

=head2 Other Audio::TagLib syntactic compatibility 

=over 4

=item The following 'set' methods are equivalent to methods above used with an argument. They are included in this module for Audio::TagLib compatibility:

=item Method     equivalent to

=item ------------------------

=item setAlbum     album

=item setArtist    artist

=item setTitle     title

=item setComment   comment

=item setGenre     genre

=item setTrack     track

=item setTracks    tracks

=item setTotal     total tracks

=back

=head2 Apple m4a personal data removal function

=over 4

=item B<CleanAppleM4aPersonalData>

  my $file_name = "mp4aIDfile.m4a";
  my $qt = Audio::M4P::QuickTime->new(file => $file_name);
  $qt->CleanAppleM4aPersonalData();
  $qt->WriteFile('cleaned' . $file_name);

lib/Audio/M4P/QuickTime.pm  view on Meta::CPAN


=item FixStco

=item GetSampleTable

=item MakeIlstAtom

=item MetaInfo

=item ParseDrms

=item ParseMP4Container

=item ParseMeta

=item ParseStsd

=item ParseMp4a

=item genre_num_to_genre_text

=item genre_text_to_genre_num

=item isMetaDataType

=item Get3GPInfo

=item GetFtype

=item Set3GPInfo

=item asset_language_pack_iso_639_2T

=back

=head1 BUGS

=over 4

The Audio::M4P::* code is not re-entrant on a per-file basis, due to recursive 
changes to containers not being thread-safe. Threaded code using these modules 
may need to lock down all method calls with a semaphore or other serialization 
method, unless only one thread is used to modify any given audio file.

=back

=head1 SEE ALSO WITH THIS MODULE

=over 4

=item L<Audio::M4P>, L<Audio::M4P::Atom>

=back    

=head1 SEE ALSO

=over 4

=item L<LWP::UserAgent::iTMS_Client>, L<iTunes::Sid>

=item L<MP3::Info>, L<MP4::Info>, L<MP3::Tag>, L<Audio::TagLib>, L<Audio::File::Tag>, L<Mac::iTunes>, L<Net::iTMS>, L<LWP::UserAgent::iTMS_Client>

=back

=head1 AUTHOR 

=over 4

William Herrera B<wherrera@skylightview.com>. 

=back

=head1 SUPPORT 

=over 4

Questions, feature requests and bug reports should go to 
<wherrera@skylightview.com>.

=back

=head1 COPYRIGHT 

=over 4

Copyright (c) 2003-2008 William Herrera. All rights reserved.  
This program is free software; you can redistribute it and/or modify 
it under the same terms as Perl itself.

=back

=cut

1;



( run in 1.346 second using v1.01-cache-2.11-cpan-d7a12ab2c7f )