dokeos
[ class tree: dokeos ] [ index: dokeos ] [ all elements ]

Source for file module.audio-video.flv.php

Documentation is available at module.audio-video.flv.php

  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.archive.gzip.php                                              |
  18. // | module for analyzing GZIP files                                      |
  19. // | dependencies: NONE                                                   |
  20. // +----------------------------------------------------------------------+
  21. // | FLV module by Seth Kaufman <sethØwhirl-i.gig*com>                    |
  22. // |                                                                      |
  23. // | * version 0.1 (26 June 2005)                                         |
  24. // |                                                                      |
  25. // | minor modifications by James Heinrich <infoØgetid3*org>              |
  26. // | * version 0.1.1 (15 July 2005)                                       |
  27. // |                                                                      |
  28. // | Support for On2 VP6 codec and meta information by                    |
  29. // | Steve Webster <steve.websterØfeaturecreep*com>                       |
  30. // | * version 0.2 (22 February 2006)                                     |
  31. // |                                                                      |
  32. // | Modified to not read entire file into memory                         |
  33. // | by James Heinrich <infoØgetid3*org>                                  |
  34. // | * version 0.3 (15 June 2006)                                         |
  35. // |                                                                      |
  36. // | Modifications by Allan Hansen <ahØartemis*dk>                        |
  37. // | Adapted module for PHP5 and getID3 2.0.0.                            |
  38. // +----------------------------------------------------------------------+
  39. //
  40. // $Id: module.audio-video.flv.php,v 1.7 2006/11/10 11:20:12 ah Exp $
  41.  
  42.  
  43.  
  44. class getid3_flv extends getid3_handler
  45. {
  46.     
  47.     const TAG_AUDIO    =  8;
  48.     const TAG_VIDEO    =  9;
  49.     const TAG_META     = 18;
  50.  
  51.     const VIDEO_H263   = 2;
  52.     const VIDEO_SCREEN = 3;
  53.     const VIDEO_VP6    = 4;
  54.  
  55.     
  56.     public function Analyze()
  57.     {
  58.         $info &$this->getid3->info;
  59.         
  60.         $info['flv'array ();
  61.         $info_flv &$info['flv'];
  62.         
  63.         fseek($this->getid3->fp$info['avdataoffset']SEEK_SET);
  64.  
  65.         $flv_data_length $info['avdataend'$info['avdataoffset'];
  66.         $flv_header fread($this->getid3->fp5);
  67.  
  68.         $info['fileformat''flv';
  69.         $info_flv['header']['signature'=                           substr($flv_header03);
  70.         $info_flv['header']['version']   getid3_lib::BigEndian2Int(substr($flv_header31));
  71.         $type_flags                      getid3_lib::BigEndian2Int(substr($flv_header41));
  72.  
  73.         $info_flv['header']['hasAudio'= (bool) ($type_flags 0x04);
  74.         $info_flv['header']['hasVideo'= (bool) ($type_flags 0x01);
  75.  
  76.         $frame_size_data_length getid3_lib::BigEndian2Int(fread($this->getid3->fp4));
  77.         $flv_header_frame_length 9;
  78.         if ($frame_size_data_length $flv_header_frame_length{
  79.             fseek($this->getid3->fp$frame_size_data_length $flv_header_frame_lengthSEEK_CUR);
  80.         }
  81.  
  82.         $duration 0;
  83.         while ((ftell($this->getid3->fp1$info['avdataend']{
  84.             
  85.             $this_tag_header fread($this->getid3->fp16);
  86.  
  87.             $previous_tag_length getid3_lib::BigEndian2Int(substr($this_tag_header,  04));
  88.             $tag_type            getid3_lib::BigEndian2Int(substr($this_tag_header,  41));
  89.             $data_length         getid3_lib::BigEndian2Int(substr($this_tag_header,  53));
  90.             $timestamp           getid3_lib::BigEndian2Int(substr($this_tag_header,  83));
  91.             $last_header_byte    getid3_lib::BigEndian2Int(substr($this_tag_header151));
  92.             $next_offset         ftell($this->getid3->fp$data_length;
  93.  
  94.             switch ($tag_type{
  95.                 
  96.                 case getid3_flv::TAG_AUDIO:
  97.                     if (!isset($info_flv['audio']['audioFormat'])) {
  98.                         $info_flv['audio']['audioFormat']     =  $last_header_byte 0x07;
  99.                         $info_flv['audio']['audioRate']       ($last_header_byte 0x300x10;
  100.                         $info_flv['audio']['audioSampleSize'($last_header_byte 0x400x40;
  101.                         $info_flv['audio']['audioType']       ($last_header_byte 0x800x80;
  102.                     }
  103.                     break;
  104.  
  105.  
  106.                 case getid3_flv::TAG_VIDEO:
  107.                     if (!isset($info_flv['video']['videoCodec'])) {
  108.                         $info_flv['video']['videoCodec'$last_header_byte 0x07;
  109.  
  110.                         $flv_video_header fread($this->getid3->fp11);
  111.  
  112.                         if ($info_flv['video']['videoCodec'!= getid3_flv::VIDEO_VP6{
  113.  
  114.                             $picture_size_type (getid3_lib::BigEndian2Int(substr($flv_video_header32))) >> 7;
  115.                             $picture_size_type $picture_size_type 0x0007;
  116.                             $info_flv['header']['videoSizeType'$picture_size_type;
  117.                             
  118.                             switch ($picture_size_type{
  119.                                 case 0:
  120.                                     $picture_size_enc getid3_lib::BigEndian2Int(substr($flv_video_header52));
  121.                                     $picture_size_enc <<= 1;
  122.                                     $info['video']['resolution_x'($picture_size_enc 0xFF00>> 8;
  123.                                     $picture_size_enc getid3_lib::BigEndian2Int(substr($flv_video_header62));
  124.                                     $picture_size_enc <<= 1;
  125.                                     $info['video']['resolution_y'($picture_size_enc 0xFF00>> 8;
  126.                                     break;
  127.  
  128.                                 case 1:
  129.                                     $picture_size_enc getid3_lib::BigEndian2Int(substr($flv_video_header54));
  130.                                     $picture_size_enc <<= 1;
  131.                                     $info['video']['resolution_x'($picture_size_enc 0xFFFF0000>> 16;
  132.  
  133.                                     $picture_size_enc getid3_lib::BigEndian2Int(substr($flv_video_header74));
  134.                                     $picture_size_enc <<= 1;
  135.                                     $info['video']['resolution_y'($picture_size_enc 0xFFFF0000>> 16;
  136.                                     break;
  137.  
  138.                                 case 2:
  139.                                     $info['video']['resolution_x'352;
  140.                                     $info['video']['resolution_y'288;
  141.                                     break;
  142.  
  143.                                 case 3:
  144.                                     $info['video']['resolution_x'176;
  145.                                     $info['video']['resolution_y'144;
  146.                                     break;
  147.  
  148.                                 case 4:
  149.                                     $info['video']['resolution_x'128;
  150.                                     $info['video']['resolution_y'96;
  151.                                     break;
  152.  
  153.                                 case 5:
  154.                                     $info['video']['resolution_x'320;
  155.                                     $info['video']['resolution_y'240;
  156.                                     break;
  157.  
  158.                                 case 6:
  159.                                     $info['video']['resolution_x'160;
  160.                                     $info['video']['resolution_y'120;
  161.                                     break;
  162.  
  163.                                 default:
  164.                                     $info['video']['resolution_x'0;
  165.                                     $info['video']['resolution_y'0;
  166.                                     break;
  167.                             }
  168.                         }
  169.                     }
  170.                     break;
  171.  
  172.  
  173.                 // Meta tag
  174.                 case getid3_flv::TAG_META:
  175.  
  176.                     fseek($this->getid3->fp-1SEEK_CUR);
  177.                     $reader new AMFReader(new AMFStream(fread($this->getid3->fp$data_length)));
  178.                     $event_name $reader->readData();
  179.                     $info['meta'][$event_name$reader->readData();
  180.                     unset($reader);
  181.  
  182.                     $info['video']['frame_rate']   @$info['meta']['onMetaData']['framerate'];
  183.                     $info['video']['resolution_x'@$info['meta']['onMetaData']['width'];
  184.                     $info['video']['resolution_y'@$info['meta']['onMetaData']['height'];
  185.                     break;
  186.  
  187.                 default:
  188.                     // noop
  189.                     break;
  190.             }
  191.  
  192.             if ($timestamp $duration{
  193.                 $duration $timestamp;
  194.             }
  195.  
  196.             fseek($this->getid3->fp$next_offsetSEEK_SET);
  197.         }
  198.  
  199.         if ($info['playtime_seconds'$duration 1000{
  200.             $info['bitrate'($info['avdataend'$info['avdataoffset']$info['playtime_seconds'];
  201.         }
  202.  
  203.         if ($info_flv['header']['hasAudio']{
  204.             $info['audio']['codec']           $this->FLVaudioFormat($info_flv['audio']['audioFormat']);
  205.             $info['audio']['sample_rate']     $this->FLVaudioRate($info_flv['audio']['audioRate']);
  206.             $info['audio']['bits_per_sample'$this->FLVaudioBitDepth($info_flv['audio']['audioSampleSize']);
  207.  
  208.             $info['audio']['channels']   $info_flv['audio']['audioType'1// 0=mono,1=stereo
  209.             $info['audio']['lossless']   ($info_flv['audio']['audioFormat'false true)// 0=uncompressed
  210.             $info['audio']['dataformat''flv';
  211.         }
  212.         if (@$info_flv['header']['hasVideo']{
  213.             $info['video']['codec']      $this->FLVvideoCodec($info_flv['video']['videoCodec']);
  214.             $info['video']['dataformat''flv';
  215.             $info['video']['lossless']   false;
  216.         }
  217.  
  218.         return true;
  219.     }
  220.  
  221.  
  222.     public static function FLVaudioFormat($id{
  223.         
  224.         static $lookup array(
  225.             => 'uncompressed',
  226.             => 'ADPCM',
  227.             => 'mp3',
  228.             => 'Nellymoser 8kHz mono',
  229.             => 'Nellymoser',
  230.         );
  231.         return (@$lookup[$id@$lookup[$idfalse);
  232.     }
  233.  
  234.  
  235.     public static function FLVaudioRate($id{
  236.         
  237.         static $lookup array(
  238.             =>  5500,
  239.             => 11025,
  240.             => 22050,
  241.             => 44100,
  242.         );
  243.         return (@$lookup[$id@$lookup[$idfalse);
  244.     }
  245.  
  246.  
  247.     public static function FLVaudioBitDepth($id{
  248.         
  249.         static $lookup array(
  250.             =>  8,
  251.             => 16,
  252.         );
  253.         return (@$lookup[$id@$lookup[$idfalse);
  254.     }
  255.  
  256.  
  257.     public static function FLVvideoCodec($id{
  258.         
  259.         static $lookup array(
  260.             getid3_flv::VIDEO_H263   => 'Sorenson H.263',
  261.             getid3_flv::VIDEO_SCREEN => 'Screen video',
  262.             getid3_flv::VIDEO_VP6    => 'On2 VP6',
  263.         );
  264.         return (@$lookup[$id@$lookup[$idfalse);
  265.     }
  266. }
  267.  
  268.  
  269.  
  270. class AMFStream 
  271. {
  272.     public $bytes;
  273.     public $pos;
  274.  
  275.  
  276.     public function AMFStream($bytes{
  277.         
  278.         $this->bytes = $bytes;
  279.         $this->pos = 0;
  280.     }
  281.  
  282.  
  283.     public function readByte({
  284.         
  285.         return getid3_lib::BigEndian2Int(substr($this->bytes$this->pos++1));
  286.     }
  287.  
  288.  
  289.     public function readInt({
  290.         
  291.         return ($this->readByte(<< 8$this->readByte();
  292.     }
  293.  
  294.  
  295.     public function readLong({
  296.         
  297.         return ($this->readByte(<< 24($this->readByte(<< 16($this->readByte(<< 8$this->readByte();
  298.     }
  299.  
  300.  
  301.     public function readDouble({
  302.         
  303.         return getid3_lib::BigEndian2Float($this->read(8));
  304.     }
  305.  
  306.  
  307.     public function readUTF({
  308.         
  309.         $length $this->readInt();
  310.         return $this->read($length);
  311.     }
  312.  
  313.  
  314.     public function readLongUTF({
  315.         
  316.         $length $this->readLong();
  317.         return $this->read($length);
  318.     }
  319.  
  320.  
  321.     public function read($length{
  322.  
  323.         $val substr($this->bytes$this->pos$length);
  324.         $this->pos += $length;
  325.         return $val;
  326.     }
  327.  
  328.     
  329.     public function peekByte({
  330.         
  331.         $pos $this->pos;
  332.         $val $this->readByte();
  333.         $this->pos = $pos;
  334.         return $val;
  335.     }
  336.  
  337.  
  338.     public function peekInt({
  339.  
  340.         $pos $this->pos;
  341.         $val $this->readInt();
  342.         $this->pos = $pos;
  343.         return $val;
  344.     }
  345.  
  346.  
  347.     public function peekLong({
  348.         
  349.         $pos $this->pos;
  350.         $val $this->readLong();
  351.         $this->pos = $pos;
  352.         return $val;
  353.     }
  354.  
  355.  
  356.     public function peekDouble({  
  357.         
  358.         $pos $this->pos;
  359.         $val $this->readDouble();
  360.         $this->pos = $pos;
  361.         return $val;
  362.     }
  363.  
  364.  
  365.     public function peekUTF({
  366.         
  367.         $pos $this->pos;
  368.         $val $this->readUTF();
  369.         $this->pos = $pos;
  370.         return $val;
  371.     }
  372.  
  373.  
  374.     public function peekLongUTF({
  375.         
  376.         $pos $this->pos;
  377.         $val $this->readLongUTF();
  378.         $this->pos = $pos;
  379.         return $val;
  380.     }
  381. }
  382.  
  383.  
  384.  
  385. class AMFReader 
  386. {
  387.     public $stream;
  388.  
  389.     public function __construct($stream{
  390.         
  391.         $this->stream = $stream;
  392.     }
  393.  
  394.  
  395.     public function readData({
  396.         
  397.         $value null;
  398.  
  399.         $type $this->stream->readByte();
  400.  
  401.         switch($type{
  402.             // Double
  403.             case 0:
  404.                 $value $this->readDouble();
  405.             break;
  406.  
  407.             // Boolean
  408.             case 1:
  409.                 $value $this->readBoolean();
  410.                 break;
  411.  
  412.             // String
  413.             case 2:
  414.                 $value $this->readString();
  415.                 break;
  416.  
  417.             // Object
  418.             case 3:
  419.                 $value $this->readObject();
  420.                 break;
  421.  
  422.             // null
  423.             case 6:
  424.                 return null;
  425.                 break;
  426.  
  427.             // Mixed array
  428.             case 8:
  429.                 $value $this->readMixedArray();
  430.                 break;
  431.  
  432.             // Array
  433.             case 10:
  434.                 $value $this->readArray();
  435.                 break;
  436.  
  437.             // Date
  438.             case 11:
  439.                 $value $this->readDate();
  440.                 break;
  441.  
  442.             // Long string
  443.             case 13:
  444.                 $value $this->readLongString();
  445.                 break;
  446.  
  447.             // XML (handled as string)
  448.             case 15:
  449.                 $value $this->readXML();
  450.                 break;
  451.  
  452.             // Typed object (handled as object)
  453.             case 16:
  454.                 $value $this->readTypedObject();
  455.                 break;
  456.  
  457.             // Long string
  458.             default:
  459.                 $value '(unknown or unsupported data type)';
  460.             break;
  461.         }
  462.  
  463.         return $value;
  464.     }
  465.  
  466.  
  467.     public function readDouble({    
  468.         
  469.         return $this->stream->readDouble();
  470.     }
  471.  
  472.  
  473.     public function readBoolean({
  474.         
  475.         return $this->stream->readByte(== 1;
  476.     }
  477.            
  478.            
  479.     public function readString({
  480.         
  481.         return $this->stream->readUTF();
  482.     }
  483.  
  484.  
  485.     public function readObject({
  486.         
  487.         // Get highest numerical index - ignored
  488.         $highestIndex $this->stream->readLong();
  489.  
  490.         $data array();
  491.  
  492.         while ($key $this->stream->readUTF()) {
  493.             // Mixed array record ends with empty string (0x00 0x00) and 0x09
  494.             if (($key == ''&& ($this->stream->peekByte(== 0x09)) {
  495.                 // Consume byte
  496.                 $this->stream->readByte();
  497.                 break;
  498.             }
  499.  
  500.             $data[$key$this->readData();
  501.         }
  502.  
  503.         return $data;
  504.     }
  505.  
  506.  
  507.     public function readMixedArray({
  508.         
  509.         // Get highest numerical index - ignored
  510.         $highestIndex $this->stream->readLong();
  511.  
  512.         $data array();
  513.  
  514.         while ($key $this->stream->readUTF()) {
  515.             // Mixed array record ends with empty string (0x00 0x00) and 0x09
  516.             if (($key == ''&& ($this->stream->peekByte(== 0x09)) {
  517.                 // Consume byte
  518.                 $this->stream->readByte();
  519.                 break;
  520.             }
  521.  
  522.             if (is_numeric($key)) {
  523.                 $key = (float) $key;
  524.             }
  525.  
  526.             $data[$key$this->readData();
  527.         }
  528.  
  529.         return $data;
  530.     }
  531.  
  532.  
  533.     public function readArray({
  534.         
  535.         $length $this->stream->readLong();
  536.  
  537.         $data array();
  538.  
  539.         for ($i 0$i count($length)$i++{
  540.             $data[$this->readData();
  541.         }
  542.  
  543.         return $data;
  544.     }
  545.  
  546.  
  547.     public function readDate({
  548.         
  549.         $timestamp $this->stream->readDouble();
  550.         $timezone $this->stream->readInt();
  551.         return $timestamp;
  552.     }
  553.  
  554.  
  555.     public function readLongString({
  556.         
  557.         return $this->stream->readLongUTF();
  558.     }
  559.  
  560.  
  561.     public function readXML({
  562.         
  563.         return $this->stream->readLongUTF();
  564.     }
  565.  
  566.  
  567.     public function readTypedObject({  
  568.         
  569.         $className $this->stream->readUTF();
  570.         return $this->readObject();
  571.     }
  572. }
  573.  
  574. ?>

Documentation generated on Thu, 12 Jun 2008 14:06:21 -0500 by phpDocumentor 1.4.1