Пример #1
0
    /**
     * Get a files meta data and cuepoints
     * 
     * @param      string       $filename
     * @return     array		$meta
     */
    function getMeta( $file ) {
        // Open file
        $f = fopen( $file,'rb' );
        
        // Read header
        $buffer = fread( $f, 9 );
        $header = @unpack( 'C3signature/Cversion/Cflags/Noffset', $buffer );
        
        // If signature is valid, go on
        if( $header['signature1'] == 70 && $header['signature2'] == 76 && $header['signature3'] == 86 ){
            // Read tags
            fseek( $f, $header['offset'] );
            while( feof( $f ) == false ){
                // Read tag header and check length
                $buffer = fread( $f, 15 );
                if( strlen( $buffer ) < 15) break;
                
                // Interpret header
                $tag 			= @unpack( 'Nprevsize/C1type/C3size/C4timestamp/C3stream', $buffer );
                $tag['size'] 	= ( $tag['size1'] << 16 ) + ( $tag['size2'] << 8 ) + ( $tag['size3'] );
				
				if( !$tag['size'] ) break;
                
				// Read tag body (max 16k)
				$next = ftell( $f ) + $tag['size'];
				$body = fread( $f, min( $tag['size'], 16384 ) );
				
				// Seek
				fseek( $f, $next );
			
				switch( $tag['type'] ){
					case 0x09:						
						// Unpack flags
						$info = @unpack( 'Cflags', $body );
						
						// Get frame type and store it
						$ft = ( $info['flags'] >> 4 ) & 15;
						
						if( !isset( $fw ) && !isset( $fh ) && $ft == 0x01 ){
							switch( $info['flags'] & 15 ){
								case 0x04:
								case 0x05:
								
								//codec_on2_vp6:
								//codec_on2_vp6alpha:
									$fw = ord( $body[5] )*16;
									$fh = ord( $body[6] )*16;
									break;
								//codec_sorenson_h263:
								case 0x02:
									$bin = '';
									for( $i=0; $i<16; $i++ ){
										$sbin = decbin( ord( $body[$i+1] ) );
										$bin .= str_pad( $sbin, 8, '0', STR_PAD_LEFT );
									}
									
									// Size type
									$size = bindec( substr( $bin, 30, 3 ) );
									
									// Get width/height
									switch ($size) {
										case 0:        // Custom, 8 bit
											$fw = bindec( substr( $bin, 33, 8 ) );
											$fh = bindec( substr( $bin, 41, 8 ) );
											break;
										case 1:        // Custom, 16 bit
											$fw = bindec( substr( $bin, 33, 16 ) );
											$fh = bindec( substr( $bin, 49, 16 ) );
											break;
										case 2:
											$fw = 352;
											$fh = 288;
											break;
										case 3:
											$fw = 176;
											$fh = 144;
											break;                                        
										case 4:
											$fw = 128;
											$fh = 96;
											break;
										case 5:
											$fw = 320;
											$fh = 240;
											break;
										case 6:
											$fw = 160;
											$fh = 120;
											break;
									}
									break;
							}
						}
						break;
					case 0x12:
						$parser = new AMF0Parser();
						// Parse data
						$data = $parser->readAllPackets( $body );
						$meta = $data[0] == 'onMetaData' ? $data[1] : array('width'=>'', 'height'=>'', 'duration'=>'');
						break;
				}
            }// while
        } 
        
        // Close file
        fclose( $f );
        
		// Width
		if ( isset( $fw ) && !isset( $meta['width'] ) ) {
			$meta['width'] = $fw;
		}
		
		// Height
		if ( isset( $fh ) && !isset( $meta['height'] ) ) {
			$meta['height'] = $fh;
		}  
		
		if( isset( $meta['duration'] ) ){
			$time = abs( $meta['duration'] );
			
			$minutes = floor( $time / 60);
			$seconds = round( ( ( $time / 60 ) - floor( $time / 60 ) ) * 60 );
	
			if( $seconds >= 60 ){
				$seconds -= 60;
				$minutes++;
			}
			
			$meta['duration'] = $minutes . ':' . str_pad( $seconds, 2, 0, STR_PAD_LEFT );
		}else{
			$meta['duration'] = 0;
		}
	   	return $meta;
    }
Пример #2
0
 /**
  * Rewrite (or strip) meta data and cuepoints from FLV file
  *
  * @author 	Tommy Lacroix <*****@*****.**>
  * @access 	public
  * @param 	string		$in		Input file
  * @param 	string		$out	Output file (must be different!)
  * @param 	string[]	$meta	Meta data (ie. array('width'=>320,'height'=>240,...), optional
  * @param 	array		$cuepoints	Cuepoints (ie. array(array('name'=>'cue1','time'=>'4.4',type=>'event'),...), optional
  */
 public function rewriteMeta($in, $out, $meta = false, $cuepoints = false)
 {
     // No tag found yet
     $tagParsed = 0;
     // Open input file
     $f = fopen($in, 'rb');
     // Read header
     $buf = fread($f, 9);
     $header = unpack('C3signature/Cversion/Cflags/Noffset', $buf);
     // Check signature
     $signature = $header['signature1'] == 70 && $header['signature2'] == 76 && $header['signature3'] == 86;
     // If signature is valid, go on
     if ($signature) {
         // Open output file, and write header
         $o = fopen($out, 'w');
         if (!$o) {
             throw new Exception('Cannot open output file!');
         }
         fwrite($o, $buf, 9);
         // Version
         //$version = $header['version'];
         // Write meta data
         if ($meta !== false) {
             $parser = new AMF0Parser();
             $metadata = $parser->writeString('onMetaData');
             $metadata .= $parser->writeMixedArray($meta);
             $metadataSize = substr(pack('N', strlen($metadata)), 1);
             // Write
             $metadataHead = pack('N', 0) . chr(18) . $metadataSize . pack('N', 0) . chr(0) . chr(0) . chr(0);
             fwrite($o, $metadataHead);
             fwrite($o, $metadata);
         }
         // Read tags
         //$prevTagSize = 0;
         $lastTimeStamp = 0;
         do {
             // Read tag header and check length
             $buf = fread($f, 15);
             if (strlen($buf) < 15) {
                 break;
             }
             // Interpret header
             $tagInfo = unpack('Nprevsize/C1type/C3size/C4timestamp/C3stream', $buf);
             $tagInfo['size'] = ($tagInfo['size1'] << 16) + ($tagInfo['size2'] << 8) + $tagInfo['size3'];
             $tagInfo['stream'] = ($tagInfo['stream1'] << 16) + ($tagInfo['stream2'] << 8) + $tagInfo['stream3'];
             $tagInfo['timestamp'] = ($tagInfo['timestamp1'] << 16) + ($tagInfo['timestamp2'] << 8) + $tagInfo['timestamp3'] + ($tagInfo['timestamp4'] << 24);
             // Need we insert a cuepoint here?
             if ($cuepoints !== false) {
                 foreach ($cuepoints as $index => $cuepoint) {
                     if ($lastTimeStamp < $cuepoint['time'] * 1000 && $tagInfo['timestamp'] >= $cuepoint['time'] * 1000) {
                         // Write cuepoint
                         $parser = new AMF0Parser();
                         $metadata = $parser->writeString('onCuePoint');
                         $metadata .= $parser->writeMixedArray($cuepoint);
                         $metadataSize = substr(pack('N', strlen($metadata)), 1);
                         // Write first
                         $metadataHead = pack('N', $tagInfo['prevsize']) . chr(18) . $metadataSize . pack('N', 0) . chr(0) . chr(0) . chr(0);
                         fwrite($o, $metadataHead);
                         fwrite($o, $metadata);
                         // Update prevsize in $buf
                         // @todo
                         // Unset cuepoint
                         unset($cuepoints[$index]);
                     }
                 }
             }
             // Validate previous offset
             //if ($tagInfo['prevsize'] != $prevTagSize) {
             // Do nothing
             //}
             // Read tag body
             $body = fread($f, $tagInfo['size']);
             // Intepret body
             switch ($tagInfo['type']) {
                 case 0x9:
                     // Video tag
                     // Write to output file
                     fwrite($o, $buf, 15);
                     fwrite($o, $body, $tagInfo['size']);
                     break;
                 case 0x8:
                     // Audio tag
                     // Write to output file
                     fwrite($o, $buf, 15);
                     fwrite($o, $body, $tagInfo['size']);
                     break;
                 case 0x12:
                     // Meta tag
                     // Skip
                     break;
             }
             // Increase parsed tag count
             $tagParsed++;
         } while (feof($f) == false);
     }
     // Close file
     fclose($f);
     fclose($o);
 }