Vorbis.pm 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. #------------------------------------------------------------------------------
  2. # File: Vorbis.pm
  3. #
  4. # Description: Read Ogg Vorbis audio meta information
  5. #
  6. # Revisions: 2006/11/10 - P. Harvey Created
  7. # 2011/07/12 - PH Moved Ogg to a separate module and added Theora
  8. #
  9. # References: 1) http://www.xiph.org/vorbis/doc/
  10. # 2) http://flac.sourceforge.net/ogg_mapping.html
  11. # 3) http://www.theora.org/doc/Theora.pdf
  12. #------------------------------------------------------------------------------
  13. package Image::ExifTool::Vorbis;
  14. use strict;
  15. use vars qw($VERSION);
  16. use Image::ExifTool qw(:DataAccess :Utils);
  17. $VERSION = '1.08';
  18. sub ProcessComments($$$);
  19. # Vorbis header types
  20. %Image::ExifTool::Vorbis::Main = (
  21. NOTES => q{
  22. Information extracted from Ogg Vorbis files. See
  23. L<http://www.xiph.org/vorbis/doc/> for the Vorbis specification.
  24. },
  25. 1 => {
  26. Name => 'Identification',
  27. SubDirectory => { TagTable => 'Image::ExifTool::Vorbis::Identification' },
  28. },
  29. 3 => {
  30. Name => 'Comments',
  31. SubDirectory => { TagTable => 'Image::ExifTool::Vorbis::Comments' },
  32. },
  33. );
  34. %Image::ExifTool::Vorbis::Identification = (
  35. PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
  36. GROUPS => { 2 => 'Audio' },
  37. 0 => {
  38. Name => 'VorbisVersion',
  39. Format => 'int32u',
  40. },
  41. 4 => 'AudioChannels',
  42. 5 => {
  43. Name => 'SampleRate',
  44. Format => 'int32u',
  45. },
  46. 9 => {
  47. Name => 'MaximumBitrate',
  48. Format => 'int32u',
  49. RawConv => '$val || undef',
  50. PrintConv => 'ConvertBitrate($val)',
  51. },
  52. 13 => {
  53. Name => 'NominalBitrate',
  54. Format => 'int32u',
  55. RawConv => '$val || undef',
  56. PrintConv => 'ConvertBitrate($val)',
  57. },
  58. 17 => {
  59. Name => 'MinimumBitrate',
  60. Format => 'int32u',
  61. RawConv => '$val || undef',
  62. PrintConv => 'ConvertBitrate($val)',
  63. },
  64. );
  65. %Image::ExifTool::Vorbis::Comments = (
  66. PROCESS_PROC => \&ProcessComments,
  67. GROUPS => { 2 => 'Audio' },
  68. NOTES => q{
  69. The tags below are only some common tags found in the Vorbis comments of Ogg
  70. Vorbis and Ogg FLAC audio files, however ExifTool will extract values from
  71. any tag found, even if not listed here.
  72. },
  73. vendor => { Notes => 'from comment header' },
  74. TITLE => { Name => 'Title' },
  75. VERSION => { Name => 'Version' },
  76. ALBUM => { Name => 'Album' },
  77. TRACKNUMBER=>{ Name => 'TrackNumber' },
  78. ARTIST => { Name => 'Artist', Groups => { 2 => 'Author' }, List => 1 },
  79. PERFORMER => { Name => 'Performer', Groups => { 2 => 'Author' }, List => 1 },
  80. COPYRIGHT => { Name => 'Copyright', Groups => { 2 => 'Author' } },
  81. LICENSE => { Name => 'License', Groups => { 2 => 'Author' } },
  82. ORGANIZATION=>{Name => 'Organization', Groups => { 2 => 'Author' } },
  83. DESCRIPTION=>{ Name => 'Description' },
  84. GENRE => { Name => 'Genre' },
  85. DATE => { Name => 'Date', Groups => { 2 => 'Time' } },
  86. LOCATION => { Name => 'Location', Groups => { 2 => 'Location' } },
  87. CONTACT => { Name => 'Contact', Groups => { 2 => 'Author' }, List => 1 },
  88. ISRC => { Name => 'ISRCNumber' },
  89. COVERARTMIME => { Name => 'CoverArtMIMEType' },
  90. COVERART => {
  91. Name => 'CoverArt',
  92. Groups => { 2 => 'Preview' },
  93. Notes => 'base64-encoded image',
  94. ValueConv => q{
  95. require Image::ExifTool::XMP;
  96. Image::ExifTool::XMP::DecodeBase64($val);
  97. },
  98. },
  99. REPLAYGAIN_TRACK_PEAK => { Name => 'ReplayGainTrackPeak' },
  100. REPLAYGAIN_TRACK_GAIN => { Name => 'ReplayGainTrackGain' },
  101. REPLAYGAIN_ALBUM_PEAK => { Name => 'ReplayGainAlbumPeak' },
  102. REPLAYGAIN_ALBUM_GAIN => { Name => 'ReplayGainAlbumGain' },
  103. # observed in "Xiph.Org libVorbis I 20020717" ogg:
  104. ENCODED_USING => { Name => 'EncodedUsing' },
  105. ENCODED_BY => { Name => 'EncodedBy' },
  106. COMMENT => { Name => 'Comment' },
  107. # in Theora documentation (ref 3)
  108. DIRECTOR => { Name => 'Director' },
  109. PRODUCER => { Name => 'Producer' },
  110. COMPOSER => { Name => 'Composer' },
  111. ACTOR => { Name => 'Actor' },
  112. );
  113. # Vorbis composite tags
  114. %Image::ExifTool::Vorbis::Composite = (
  115. Duration => {
  116. Require => {
  117. 0 => 'Vorbis:NominalBitrate',
  118. 1 => 'FileSize',
  119. },
  120. RawConv => '$val[0] ? $val[1] * 8 / $val[0] : undef',
  121. PrintConv => 'ConvertDuration($val) . " (approx)"', # (only approximate)
  122. },
  123. );
  124. # add our composite tags
  125. Image::ExifTool::AddCompositeTags('Image::ExifTool::Vorbis');
  126. #------------------------------------------------------------------------------
  127. # Process Vorbis Comments
  128. # Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
  129. # Returns: 1 on success, otherwise returns 0 and sets a Warning
  130. sub ProcessComments($$$)
  131. {
  132. my ($et, $dirInfo, $tagTablePtr) = @_;
  133. my $dataPt = $$dirInfo{DataPt};
  134. my $dataPos = $$dirInfo{DataPos};
  135. my $pos = $$dirInfo{DirStart} || 0;
  136. my $end = $$dirInfo{DirLen} ? $pos + $$dirInfo{DirLen} : length $$dataPt;
  137. my ($num, $index);
  138. SetByteOrder('II');
  139. for (;;) {
  140. last if $pos + 4 > $end;
  141. my $len = Get32u($dataPt, $pos);
  142. last if $pos + 4 + $len > $end;
  143. my $start = $pos + 4;
  144. my $buff = substr($$dataPt, $start, $len);
  145. $pos = $start + $len;
  146. my ($tag, $val);
  147. if (defined $num) {
  148. $buff =~ /(.*?)=(.*)/s or last;
  149. ($tag, $val) = ($1, $2);
  150. # Vorbis tag ID's are all capitals, so they may conflict with our internal tags
  151. # --> protect against this by adding a trailing underline if necessary
  152. $tag .= '_' if $Image::ExifTool::specialTags{$tag};
  153. } else {
  154. $tag = 'vendor';
  155. $val = $buff;
  156. $num = ($pos + 4 < $end) ? Get32u($dataPt, $pos) : 0;
  157. $et->VPrint(0, " + [Vorbis comments with $num entries]\n");
  158. $pos += 4;
  159. }
  160. # add tag to table unless it exists already
  161. unless ($$tagTablePtr{$tag}) {
  162. my $name = ucfirst(lc($tag));
  163. # remove invalid characters in tag name and capitalize following letters
  164. $name =~ s/[^\w-]+(.?)/\U$1/sg;
  165. $name =~ s/([a-z0-9])_([a-z])/$1\U$2/g;
  166. AddTagToTable($tagTablePtr, $tag, { Name => $name });
  167. }
  168. $et->HandleTag($tagTablePtr, $tag, $et->Decode($val, 'UTF8'),
  169. Index => $index,
  170. DataPt => $dataPt,
  171. DataPos => $dataPos,
  172. Start => $start,
  173. Size => $len,
  174. );
  175. # all done if this was our last tag
  176. $num-- or return 1;
  177. $index = (defined $index) ? $index + 1 : 0;
  178. }
  179. $et->Warn('Format error in Vorbis comments');
  180. return 0;
  181. }
  182. 1; # end
  183. __END__
  184. =head1 NAME
  185. Image::ExifTool::Vorbis - Read Ogg Vorbis audio meta information
  186. =head1 SYNOPSIS
  187. This module is used by Image::ExifTool
  188. =head1 DESCRIPTION
  189. This module contains definitions required by Image::ExifTool to extract meta
  190. information from Ogg Vorbis audio headers.
  191. =head1 AUTHOR
  192. Copyright 2003-2016, Phil Harvey (phil at owl.phy.queensu.ca)
  193. This library is free software; you can redistribute it and/or modify it
  194. under the same terms as Perl itself.
  195. =head1 REFERENCES
  196. =over 4
  197. =item L<http://www.xiph.org/vorbis/doc/>
  198. =item L<http://flac.sourceforge.net/ogg_mapping.html>
  199. =item L<http://www.theora.org/doc/Theora.pdf>
  200. =back
  201. =head1 SEE ALSO
  202. L<Image::ExifTool::TagNames/Vorbis Tags>,
  203. L<Image::ExifTool::TagNames/Ogg Tags>,
  204. L<Image::ExifTool(3pm)|Image::ExifTool>
  205. =cut