File Coverage

blib/lib/Music/Tag/M4A.pm
Criterion Covered Total %
statement 90 131 68.7
branch 14 24 58.3
condition 11 28 39.2
subroutine 12 16 75.0
pod 8 8 100.0
total 135 207 65.2


line stmt bran cond sub pod time code
1             package Music::Tag::M4A;
2 1     1   31356 use strict; use warnings; use utf8;
  1     1   2  
  1     1   45  
  1         6  
  1         3  
  1         37  
  1         5  
  1         14  
  1         9  
3             our $VERSION = '0.4101';
4              
5             # Copyright © 2007,2010 Edward Allen III. Some rights reserved.
6             #
7             # You may distribute under the terms of either the GNU General Public
8             # License or the Artistic License, as specified in the README file.
9              
10 1     1   57 use Music::Tag::Generic;
  1         2  
  1         26  
11 1     1   2463 use Audio::M4P::QuickTime;
  1         86572  
  1         279  
12 1     1   132875 use MP4::Info;
  1         32797  
  1         214  
13 1     1   153 use base qw(Music::Tag::Generic);
  1         3  
  1         2842  
14              
15             sub _default_options {
16 0     0   0 { write_m4a => 0 };
17             }
18              
19             sub set_values {
20 0     0 1 0 return qw( album artist bitrate comment compilation composer
21             copyright disc duration encoder filename frequency genre
22             lyrics picture releasedate tempo title
23             totaldiscs totaltracks track year);
24             }
25              
26             sub saved_values {
27 0     0 1 0 return qw( album artist bitrate comment compilation composer
28             disc encoder frequency genre get_info lyrics
29             releasedate tempo title totaldiscs totaltracks track year);
30             }
31              
32             sub get_tag {
33 2     2 1 4963 my $self = shift;
34              
35             #$self->get_tag_mp4_info;
36 2         8 $self->get_tag_qt_info;
37 2         8 return $self;
38             }
39              
40             sub qt {
41 36     36 1 517 my $self = shift;
42 36 100       190 unless ( exists $self->{_qt} ) {
43 2         9 $self->{_qt} =
44             Audio::M4P::QuickTime->new(
45             file => $self->info->get_data('filename') );
46             }
47 36         197445 return $self->{_qt};
48             }
49              
50             sub get_tag_qt_info {
51 2     2 1 5 my $self = shift;
52 2         7 my $filename = $self->info->get_data('filename');
53 2 50       92 unless ( $self->qt ) {
54 0         0 $self->status("Failed to create Audio::M4P::QuickTime object");
55 0         0 return $self;
56             }
57 2         11 my $tinfo = $self->qt->iTMS_MetaInfo;
58 2         57376 my $minfo = $self->qt->GetMP4Info;
59 2         109156 my $ginfo = $self->qt->GetMetaInfo;
60              
61 2         94800 $self->info->set_data( 'album', $ginfo->{ALBUM} );
62 2         180 $self->info->set_data( 'artist', $ginfo->{ARTIST} );
63 2   33     112 my $date = $tinfo->{year} || $ginfo->{DAY};
64 2         9 $date =~ s/T.*$//;
65              
66 2         8 $self->info->set_data( 'releasedate', $date );
67              
68 2         954 $self->info->set_data( 'disc', $tinfo->{discNumber} );
69 2         204 $self->info->set_data( 'totaldiscs', $tinfo->{discCount} );
70 2         90 $self->info->set_data( 'copyright', $tinfo->{copyright} );
71              
72 2         89 $self->info->set_data( 'tempo', $ginfo->{TMPO} );
73 2   50     97 $self->info->set_data( 'encoder', $ginfo->{TOO} || "iTMS" );
74 2         93 $self->info->genre( $self->qt->genre_as_text );
75 2         88679 $self->info->set_data( 'title', $ginfo->{NAM} );
76 2         125 $self->info->set_data( 'composer', $ginfo->{WRT} );
77 2         86 $self->info->set_data( 'track', $self->qt->track );
78 2         90289 $self->info->set_data( 'totaltracks', $self->qt->total );
79 2         92624 $self->info->set_data( 'comment', $ginfo->{COMMENT} );
80 2         218 $self->info->set_data( 'lyrics', $ginfo->{LYRICS} );
81              
82 2         105 $self->info->set_data( 'bitrate', $minfo->{BITRATE} );
83 2         81 $self->info->set_data( 'duration', $minfo->{SECONDS} * 1000 );
84 2 50       83 if ( not $self->info->picture_exists ) {
85 2         61 my $picture = $self->qt->GetCoverArt;
86 2 50 33     2797 if ( ( ref $picture ) && ( @{$picture} ) && ( $picture->[0] ) ) {
  2   33     21  
87 2         7 $self->info->set_data( 'picture',
88             { "MIME type" => "image/jpg", "_Data" => $picture->[0] } );
89             }
90             }
91 2         107 return $self;
92             }
93              
94             sub get_tag_mp4_info {
95 0     0 1 0 my $self = shift;
96 0         0 my $filename = $self->info->get_data('filename');
97 0         0 my $tinfo = get_mp4tag($filename);
98 0         0 my $ftinfo = get_mp4info($filename);
99 0         0 $self->info->set_data( 'album', $tinfo->{ALB} );
100 0         0 $self->info->set_data( 'artist', $tinfo->{ART} );
101 0         0 $self->info->set_data( 'year', $tinfo->{DAY} );
102 0         0 $self->info->set_data( 'disc', $tinfo->{DISK}->[0] );
103 0         0 $self->info->set_data( 'totaldiscs', $tinfo->{DISK}->[1] );
104 0         0 $self->info->set_data( 'genre', $tinfo->{GNRE} );
105 0         0 $self->info->set_data( 'title', $tinfo->{NAM} );
106 0         0 $self->info->set_data( 'compilation', $tinfo->{CPIL} );
107 0         0 $self->info->set_data( 'copyright', $tinfo->{CPRT} );
108 0         0 $self->info->set_data( 'tempo', $tinfo->{TMPO} );
109 0   0     0 $self->info->set_data( 'encoder', $tinfo->{TOO} || "iTMS" );
110 0         0 $self->info->set_data( 'composer', $tinfo->{WRT} );
111 0         0 $self->info->set_data( 'track', $tinfo->{TRKN}->[0] );
112 0         0 $self->info->set_data( 'totaltracks', $tinfo->{TRKN}->[1] );
113 0         0 $self->info->set_data( 'comment', $tinfo->{CMT} );
114 0         0 $self->info->set_data( 'duration', $ftinfo->{SECS} * 1000 );
115 0         0 $self->info->set_data( 'bitrate', $ftinfo->{BITRATE} );
116 0         0 $self->info->set_data( 'frequency', $ftinfo->{FREQUENCY} );
117 0         0 return $self;
118             }
119              
120             sub set_tag {
121 1     1 1 6347 my $self = shift;
122 1         8 my $filename = $self->info->get_data('filename');
123 1 50       41 unless ( $self->qt ) {
124 0         0 $self->status("Failed to create Audio::M4P::QuickTime object");
125 0         0 return $self;
126             }
127 1         4 my $tinfo = $self->qt->iTMS_MetaInfo;
128 1         20255 my $minfo = $self->qt->GetMP4Info;
129 1         49310 my $ginfo = $self->qt->GetMetaInfo;
130 1         45056 my $changed = 0;
131              
132 1 50       10 if ( $self->options->{write_m4a} ) {
133 1         210 $self->status(
134             "Writing M4A files is in development and dangerous if you use iTunes. Only some tags supported."
135             );
136             }
137             else {
138 0         0 $self->status(
139             "Writing M4A files is dangerous. Set write_m4a to true if you want to try."
140             );
141 0         0 return $self;
142             }
143              
144 1         60 my %simple_map = (
145             album => 'album',
146             artist => 'artist',
147             title => 'title',
148             comment => 'comment',
149             genre => 'genre_as_text',
150             track => 'track',
151             totaltracks => 'total',
152             year => 'year',
153             );
154              
155 1         32 while ( my ( $mtm, $qtm ) = each %simple_map ) {
156 8 100 100     70 unless ( ( $self->info->has_data($mtm) )
157             && ( $self->qt->$qtm eq $self->info->get_data($mtm) ) ) {
158 7         309465 $self->status("Storing new tag info for $mtm");
159 7         300 $self->qt->$qtm( $self->info->get_data($mtm) );
160 7         1014247 $changed++;
161             }
162             }
163 1 50 33     48543 unless ( ( $self->info->has_data('tempo') )
164             && ( $ginfo->{TMPO} eq $self->info->get_data('tempo') ) ) {
165 0         0 $self->status("Storing new tag info for tempo");
166 0         0 $self->qt->SetMetaInfo( TMPO => $self->info->get_data('tempo'), 1 );
167 0         0 $changed++;
168             }
169 1 50 33     395 unless ( ( $self->info->has_data('encoder') )
170             && ( $ginfo->{TOO} eq $self->info->get_data('encoder') ) ) {
171 0         0 $self->status("Storing new tag info for encoder");
172 0         0 $self->qt->SetMetaInfo( TOO => $self->info->get_data('encoder'), 1 );
173 0         0 $changed++;
174             }
175 1 50 33     58 unless ( ( $self->info->has_data('composer') )
176             && ( $ginfo->{WRT} eq $self->info->get_data('composer') ) ) {
177 0         0 $self->status("Storing new tag info for composer");
178 0         0 $self->qt->SetMetaInfo( WRT => $self->info->get_data('composer'), 1 );
179 0         0 $changed++;
180             }
181 1 50 33     54 unless ( ( $self->info->has_data('lyrics') )
182             && ( $ginfo->{LYRICS} eq $self->info->get_data('lyrics') ) ) {
183 1         40 $self->status("Storing new tag info for lyrics");
184 1         37 my $lyrics = $self->info->get_data('lyrics');
185 1         208 $lyrics =~ s/\r?\n/\r/g;
186 1         8 $self->qt->SetMetaInfo(
187             LYRICS => $self->info->get_data('lyrics'),
188             1
189             );
190 1         57887 $changed++;
191             }
192 1 50       7 if ($changed) {
193 1         14 $self->status("Writing to $filename...");
194 1         48 $self->qt->WriteFile($filename);
195             }
196 1         1160 return $self;
197             }
198              
199             sub close {
200 2     2 1 4814 my $self = shift;
201 2         8 undef $self->{_qt};
202 2         15 delete $self->{_qt};
203             }
204              
205             1;
206              
207             # vim: tabstop=4
208             __END__