PageRenderTime 40ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/getid3/module.audio-video.nsv.php

http://pumukit.googlecode.com/
PHP | 210 lines | 138 code | 51 blank | 21 comment | 19 complexity | 92d2deeeb14bf80976aaac9fec9eaa08 MD5 | raw file
Possible License(s): LGPL-2.1
  1. <?php
  2. // +----------------------------------------------------------------------+
  3. // | PHP version 5 |
  4. // +----------------------------------------------------------------------+
  5. // | Copyright (c) 2002-2006 James Heinrich, Allan Hansen |
  6. // +----------------------------------------------------------------------+
  7. // | This source file is subject to version 2 of the GPL license, |
  8. // | that is bundled with this package in the file license.txt and is |
  9. // | available through the world-wide-web at the following url: |
  10. // | http://www.gnu.org/copyleft/gpl.html |
  11. // +----------------------------------------------------------------------+
  12. // | getID3() - http://getid3.sourceforge.net or http://www.getid3.org |
  13. // +----------------------------------------------------------------------+
  14. // | Authors: James Heinrich <info?getid3*org> |
  15. // | Allan Hansen <ah?artemis*dk> |
  16. // +----------------------------------------------------------------------+
  17. // | module.audio-video.nsv.php |
  18. // | module for analyzing Nullsoft NSV files |
  19. // | dependencies: NONE |
  20. // +----------------------------------------------------------------------+
  21. //
  22. // $Id: module.audio-video.nsv.php,v 1.3 2006/11/02 10:48:00 ah Exp $
  23. class getid3_nsv extends getid3_handler
  24. {
  25. public function Analyze() {
  26. $getid3 = $this->getid3;
  27. $getid3->info['fileformat'] = 'nsv';
  28. $getid3->info['audio']['dataformat'] = 'nsv';
  29. $getid3->info['video']['dataformat'] = 'nsv';
  30. $getid3->info['audio']['lossless'] = false;
  31. $getid3->info['video']['lossless'] = false;
  32. fseek($getid3->fp, $getid3->info['avdataoffset'], SEEK_SET);
  33. $nsv_header = fread($getid3->fp, 4);
  34. switch ($nsv_header) {
  35. case 'NSVs':
  36. $this->getNSVsHeader();
  37. break;
  38. case 'NSVf':
  39. if ($this->getNSVfHeader()) {
  40. $this->getNSVsHeader($getid3->info['nsv']['NSVf']['header_length']);
  41. }
  42. break;
  43. default:
  44. throw new getid3_exception('Expecting "NSVs" or "NSVf" at offset '.$getid3->info['avdataoffset'].', found "'.$nsv_header.'"');
  45. break;
  46. }
  47. if (!isset($getid3->info['nsv']['NSVf'])) {
  48. $getid3->warning('NSVf header not present - cannot calculate playtime or bitrate');
  49. }
  50. return true;
  51. }
  52. private function getNSVsHeader($file_offset = 0) {
  53. $getid3 = $this->getid3;
  54. fseek($getid3->fp, $file_offset, SEEK_SET);
  55. $nsvs_header = fread($getid3->fp, 28);
  56. $getid3->info['nsv']['NSVs'] = array ();
  57. $info_nsv_NSVs = &$getid3->info['nsv']['NSVs'];
  58. $info_nsv_NSVs['identifier'] = substr($nsvs_header, 0, 4);
  59. if ($info_nsv_NSVs['identifier'] != 'NSVs') {
  60. throw new getid3_exception('expected "NSVs" at offset ('.$file_offset.'), found "'.$info_nsv_NSVs['identifier'].'" instead');
  61. }
  62. $info_nsv_NSVs['offset'] = $file_offset;
  63. getid3_lib::ReadSequence('LittleEndian2Int', $info_nsv_NSVs, $nsvs_header, 4,
  64. array (
  65. 'video_codec' => -4, // string
  66. 'audio_codec' => -4, // string
  67. 'resolution_x' => 2,
  68. 'resolution_y' => 2,
  69. 'framerate_index' => 1,
  70. )
  71. );
  72. if ($info_nsv_NSVs['audio_codec'] == 'PCM ') {
  73. getid3_lib::ReadSequence('LittleEndian2Int', $info_nsv_NSVs, $nsvs_header, 24,
  74. array (
  75. 'bits_channel' => 1,
  76. 'channels' => 1,
  77. 'sample_rate' => 2
  78. )
  79. );
  80. $getid3->info['audio']['sample_rate'] = $info_nsv_NSVs['sample_rate'];
  81. }
  82. $getid3->info['video']['resolution_x'] = $info_nsv_NSVs['resolution_x'];
  83. $getid3->info['video']['resolution_y'] = $info_nsv_NSVs['resolution_y'];
  84. $info_nsv_NSVs['frame_rate'] = getid3_nsv::NSVframerateLookup($info_nsv_NSVs['framerate_index']);
  85. $getid3->info['video']['frame_rate'] = $info_nsv_NSVs['frame_rate'];
  86. $getid3->info['video']['bits_per_sample'] = 24;
  87. $getid3->info['video']['pixel_aspect_ratio'] = (float)1;
  88. return true;
  89. }
  90. private function getNSVfHeader($file_offset = 0, $get_toc_offsets=false) {
  91. $getid3 = $this->getid3;
  92. fseek($getid3->fp, $file_offset, SEEK_SET);
  93. $nsvf_header = fread($getid3->fp, 28);
  94. $getid3->info['nsv']['NSVf'] = array ();
  95. $info_nsv_NSVf = &$getid3->info['nsv']['NSVf'];
  96. $info_nsv_NSVf['identifier'] = substr($nsvf_header, 0, 4);
  97. if ($info_nsv_NSVf['identifier'] != 'NSVf') {
  98. throw new getid3_exception('expected "NSVf" at offset ('.$file_offset.'), found "'.$info_nsv_NSVf['identifier'].'" instead');
  99. }
  100. $getid3->info['nsv']['NSVs']['offset'] = $file_offset;
  101. getid3_lib::ReadSequence('LittleEndian2Int', $info_nsv_NSVf, $nsvf_header, 4,
  102. array (
  103. 'header_length' => 4,
  104. 'file_size' => 4,
  105. 'playtime_ms' => 4,
  106. 'meta_size' => 4,
  107. 'TOC_entries_1' => 4,
  108. 'TOC_entries_2' => 4
  109. )
  110. );
  111. if ($info_nsv_NSVf['playtime_ms'] == 0) {
  112. throw new getid3_exception('Corrupt NSV file: NSVf.playtime_ms == zero');
  113. }
  114. if ($info_nsv_NSVf['file_size'] > $getid3->info['avdataend']) {
  115. $getid3->warning('truncated file - NSVf header indicates '.$info_nsv_NSVf['file_size'].' bytes, file actually '.$getid3->info['avdataend'].' bytes');
  116. }
  117. $nsvf_header .= fread($getid3->fp, $info_nsv_NSVf['meta_size'] + (4 * $info_nsv_NSVf['TOC_entries_1']) + (4 * $info_nsv_NSVf['TOC_entries_2']));
  118. $nsvf_headerlength = strlen($nsvf_header);
  119. $info_nsv_NSVf['metadata'] = substr($nsvf_header, 28, $info_nsv_NSVf['meta_size']);
  120. $offset = 28 + $info_nsv_NSVf['meta_size'];
  121. if ($get_toc_offsets) {
  122. $toc_counter = 0;
  123. while ($toc_counter < $info_nsv_NSVf['TOC_entries_1']) {
  124. if ($toc_counter < $info_nsv_NSVf['TOC_entries_1']) {
  125. $info_nsv_NSVf['TOC_1'][$toc_counter] = getid3_lib::LittleEndian2Int(substr($nsvf_header, $offset, 4));
  126. $offset += 4;
  127. $toc_counter++;
  128. }
  129. }
  130. }
  131. if (trim($info_nsv_NSVf['metadata']) != '') {
  132. $info_nsv_NSVf['metadata'] = str_replace('`', "\x01", $info_nsv_NSVf['metadata']);
  133. $comment_pair_array = explode("\x01".' ', $info_nsv_NSVf['metadata']);
  134. foreach ($comment_pair_array as $comment_pair) {
  135. if (strstr($comment_pair, '='."\x01")) {
  136. list($key, $value) = explode('='."\x01", $comment_pair, 2);
  137. $getid3->info['nsv']['comments'][strtolower($key)][] = trim(str_replace("\x01", '', $value));
  138. }
  139. }
  140. }
  141. $getid3->info['playtime_seconds'] = $info_nsv_NSVf['playtime_ms'] / 1000;
  142. $getid3->info['bitrate'] = ($info_nsv_NSVf['file_size'] * 8) / $getid3->info['playtime_seconds'];
  143. return true;
  144. }
  145. public static function NSVframerateLookup($frame_rate_index) {
  146. if ($frame_rate_index <= 127) {
  147. return (float)$frame_rate_index;
  148. }
  149. static $lookup = array (
  150. 129 => 29.970,
  151. 131 => 23.976,
  152. 133 => 14.985,
  153. 197 => 59.940,
  154. 199 => 47.952
  155. );
  156. return (isset($lookup[$frame_rate_index]) ? $lookup[$frame_rate_index] : false);
  157. }
  158. }
  159. ?>