PageRenderTime 39ms CodeModel.GetById 12ms RepoModel.GetById 1ms app.codeStats 0ms

/getid3/module.audio-video.swf.php

https://bitbucket.org/holyfield/getid3
PHP | 145 lines | 87 code | 34 blank | 24 comment | 13 complexity | 46e04c92e805ce3fcc3e6db2268df0eb MD5 | raw file
Possible License(s): GPL-2.0
  1. <?php
  2. /////////////////////////////////////////////////////////////////
  3. /// getID3() by James Heinrich <info@getid3.org> //
  4. // available at http://getid3.sourceforge.net //
  5. // or http://www.getid3.org //
  6. /////////////////////////////////////////////////////////////////
  7. // See readme.txt for more details //
  8. /////////////////////////////////////////////////////////////////
  9. // //
  10. // module.audio-video.swf.php //
  11. // module for analyzing Shockwave Flash files //
  12. // dependencies: NONE //
  13. // ///
  14. /////////////////////////////////////////////////////////////////
  15. class getid3_swf extends getid3_handler {
  16. var $ReturnAllTagData = false;
  17. function Analyze() {
  18. $info = &$this->getid3->info;
  19. $info ['fileformat'] = 'swf';
  20. $info ['video'] ['dataformat'] = 'swf';
  21. // http://www.openswf.org/spec/SWFfileformat.html
  22. fseek ( $this->getid3->fp, $info ['avdataoffset'], SEEK_SET );
  23. $SWFfileData = fread ( $this->getid3->fp, $info ['avdataend'] - $info ['avdataoffset'] ); // 8 + 2 + 2 + max(9) bytes NOT including Frame_Size RECT data
  24. $info ['swf'] ['header'] ['signature'] = substr ( $SWFfileData, 0, 3 );
  25. switch ($info ['swf'] ['header'] ['signature']) {
  26. case 'FWS' :
  27. $info ['swf'] ['header'] ['compressed'] = false;
  28. break;
  29. case 'CWS' :
  30. $info ['swf'] ['header'] ['compressed'] = true;
  31. break;
  32. default :
  33. $info ['error'] [] = 'Expecting "FWS" or "CWS" at offset ' . $info ['avdataoffset'] . ', found "' . getid3_lib::PrintHexBytes ( $info ['swf'] ['header'] ['signature'] ) . '"';
  34. unset ( $info ['swf'] );
  35. unset ( $info ['fileformat'] );
  36. return false;
  37. break;
  38. }
  39. $info ['swf'] ['header'] ['version'] = getid3_lib::LittleEndian2Int ( substr ( $SWFfileData, 3, 1 ) );
  40. $info ['swf'] ['header'] ['length'] = getid3_lib::LittleEndian2Int ( substr ( $SWFfileData, 4, 4 ) );
  41. if ($info ['swf'] ['header'] ['compressed']) {
  42. $SWFHead = substr ( $SWFfileData, 0, 8 );
  43. $SWFfileData = substr ( $SWFfileData, 8 );
  44. if (($decompressed = @gzuncompress ( $SWFfileData )) != false) {
  45. $SWFfileData = $SWFHead . $decompressed;
  46. } else {
  47. $info ['error'] [] = 'Error decompressing compressed SWF data (' . strlen ( $SWFfileData ) . ' bytes compressed, should be ' . ($info ['swf'] ['header'] ['length'] - 8) . ' bytes uncompressed)';
  48. return false;
  49. }
  50. }
  51. $FrameSizeBitsPerValue = (ord ( substr ( $SWFfileData, 8, 1 ) ) & 0xF8) >> 3;
  52. $FrameSizeDataLength = ceil ( (5 + (4 * $FrameSizeBitsPerValue)) / 8 );
  53. $FrameSizeDataString = str_pad ( decbin ( ord ( substr ( $SWFfileData, 8, 1 ) ) & 0x07 ), 3, '0', STR_PAD_LEFT );
  54. for($i = 1; $i < $FrameSizeDataLength; $i ++) {
  55. $FrameSizeDataString .= str_pad ( decbin ( ord ( substr ( $SWFfileData, 8 + $i, 1 ) ) ), 8, '0', STR_PAD_LEFT );
  56. }
  57. list ( $X1, $X2, $Y1, $Y2 ) = explode ( "\n", wordwrap ( $FrameSizeDataString, $FrameSizeBitsPerValue, "\n", 1 ) );
  58. $info ['swf'] ['header'] ['frame_width'] = getid3_lib::Bin2Dec ( $X2 );
  59. $info ['swf'] ['header'] ['frame_height'] = getid3_lib::Bin2Dec ( $Y2 );
  60. // http://www-lehre.informatik.uni-osnabrueck.de/~fbstark/diplom/docs/swf/Flash_Uncovered.htm
  61. // Next in the header is the frame rate, which is kind of weird.
  62. // It is supposed to be stored as a 16bit integer, but the first byte
  63. // (or last depending on how you look at it) is completely ignored.
  64. // Example: 0x000C -> 0x0C -> 12 So the frame rate is 12 fps.
  65. // Byte at (8 + $FrameSizeDataLength) is always zero and ignored
  66. $info ['swf'] ['header'] ['frame_rate'] = getid3_lib::LittleEndian2Int ( substr ( $SWFfileData, 9 + $FrameSizeDataLength, 1 ) );
  67. $info ['swf'] ['header'] ['frame_count'] = getid3_lib::LittleEndian2Int ( substr ( $SWFfileData, 10 + $FrameSizeDataLength, 2 ) );
  68. $info ['video'] ['frame_rate'] = $info ['swf'] ['header'] ['frame_rate'];
  69. $info ['video'] ['resolution_x'] = intval ( round ( $info ['swf'] ['header'] ['frame_width'] / 20 ) );
  70. $info ['video'] ['resolution_y'] = intval ( round ( $info ['swf'] ['header'] ['frame_height'] / 20 ) );
  71. $info ['video'] ['pixel_aspect_ratio'] = ( float ) 1;
  72. if (($info ['swf'] ['header'] ['frame_count'] > 0) && ($info ['swf'] ['header'] ['frame_rate'] > 0)) {
  73. $info ['playtime_seconds'] = $info ['swf'] ['header'] ['frame_count'] / $info ['swf'] ['header'] ['frame_rate'];
  74. }
  75. //echo __LINE__.'='.number_format(microtime(true) - $start_time, 3).'<br>';
  76. // SWF tags
  77. $CurrentOffset = 12 + $FrameSizeDataLength;
  78. $SWFdataLength = strlen ( $SWFfileData );
  79. while ( $CurrentOffset < $SWFdataLength ) {
  80. //echo __LINE__.'='.number_format(microtime(true) - $start_time, 3).'<br>';
  81. $TagIDTagLength = getid3_lib::LittleEndian2Int ( substr ( $SWFfileData, $CurrentOffset, 2 ) );
  82. $TagID = ($TagIDTagLength & 0xFFFC) >> 6;
  83. $TagLength = ($TagIDTagLength & 0x003F);
  84. $CurrentOffset += 2;
  85. if ($TagLength == 0x3F) {
  86. $TagLength = getid3_lib::LittleEndian2Int ( substr ( $SWFfileData, $CurrentOffset, 4 ) );
  87. $CurrentOffset += 4;
  88. }
  89. unset ( $TagData );
  90. $TagData ['offset'] = $CurrentOffset;
  91. $TagData ['size'] = $TagLength;
  92. $TagData ['id'] = $TagID;
  93. $TagData ['data'] = substr ( $SWFfileData, $CurrentOffset, $TagLength );
  94. switch ($TagID) {
  95. case 0 : // end of movie
  96. break 2;
  97. case 9 : // Set background color
  98. //$info['swf']['tags'][] = $TagData;
  99. $info ['swf'] ['bgcolor'] = strtoupper ( str_pad ( dechex ( getid3_lib::BigEndian2Int ( $TagData ['data'] ) ), 6, '0', STR_PAD_LEFT ) );
  100. break;
  101. default :
  102. if ($this->ReturnAllTagData) {
  103. $info ['swf'] ['tags'] [] = $TagData;
  104. }
  105. break;
  106. }
  107. $CurrentOffset += $TagLength;
  108. }
  109. return true;
  110. }
  111. }