Rasher's Toolbox

Back

mpeg.php

Description

This class will read the header of mp3 files and the function return_info() will return an associative array containing the following elements:

mpeg_ver - MPEG version
layer - MPEG Version Layer
bitrate - File Bitrate
frequency - File frequency
mode - Sound mode (Stereo/mono etc)
copyright - 1 = File is copyrighted, 0 = File is not copyrighted
original - 1 = Original media, 0 = Copy of original media
emphasis - None/50/15 ms/CCIT J.17
length - Length in human readable format
lengths - Length in seconds

The class is largely unchanged from one found on http://leknor.com/code/php/class.id3.php.txt. If you need a more capable MPEG parser, <a href="http://getid3.sf.net">getID3</a> might be worth a look.

Example

<?php
  $mpeg 
= new mpeg('plateau.mp3');
  
$mpeg->getinfo();
  
$info $mpeg->return_info();
  echo 
"plateau.mp3 is in" $info['mode']
?>

This will output:

test.mp3 is in Stereo

Source

Published under the terms of the LGPL

<?php
class mpeg {
    function 
mpeg($file false) {
        
$this->filename $file;
        
$this->error false;
        
$this->error_texts[] = array();
        
$this->print_errors true;
    }

    function 
adderror($text) {
        
$this->error true;
        
$this->error_texts[] = $text;
        if (
$this->print_errors) {
            echo 
$text."\n";
        }
    }

    function 
getinfo($file false) {
        if (!
$file) {
            
$file $this->filename;
        }
        if (!
$file) {
            
$this->adderror('file not set');
        }

        if (! (
$f fopen($file'rb')) ) {
            
$this->adderror('Unable to open ' $file);
            return 
false;
        }

        
$this->filesize filesize($file);

        do {
            while (
fread($f,1) != Chr(255)) { // Find the first frame
            //if ($this->debug) echo "Find...\n";
                
if (feof($f)) {
                    
$this->adderror('No mpeg frame found');
                    return 
false;
                }
            }
            
fseek($fftell($f) - 1); // back up one byte

            
$frameoffset ftell($f);

            
$r fread($f4);
            
// Binary to Hex to a binary sting. ugly but best I can think of.
            
$bits unpack('H*bits'$r);
            
$bits =  base_convert($bits['bits'],16,2);
        } while (!
$bits[8] and !$bits[9] and !$bits[10]); // 1st 8 bits true from the while

        
$this->frameoffset $frameoffset;

        
fclose($f);

        if (
$bits[11] == 0) {
            
$this->mpeg_ver "2.5";
            
$bitrates = array(
                
'1' => array(03248566480961121281441601761922242560),
                
'2' => array(0,  81624324048,  56,  64,  80,  961121281441600),
                
'3' => array(0,  81624324048,  56,  64,  80,  961121281441600),
                     );
        } else if (
$bits[12] == 0) {
            
$this->mpeg_ver "2";
            
$bitrates = array(
                
'1' => array(03248566480961121281441601761922242560),
                
'2' => array(0,  81624324048,  56,  64,  80,  961121281441600),
                
'3' => array(0,  81624324048,  56,  64,  80,  961121281441600),
                     );
        } else {
            
$this->mpeg_ver "1";
            
$bitrates = array(
                
'1' => array(03264961281601922242562883203523844164480),
                
'2' => array(0324856,  64,  80,  961121281601922242563203840),
                
'3' => array(0324048,  56,  64,  80,  961121281601922242563200),
                     );
        }

        
$layer = array(
            array(
0,3),
            array(
2,1),
                  );
        
$this->layer $layer[$bits[13]][$bits[14]];

        if (
$bits[15] == 0) {
            
// It's backwards, if the bit is not set then it is protected.
            
$this->crc true;
        }

        
$bitrate 0;
        if (
$bits[16] == 1$bitrate += 8;
        if (
$bits[17] == 1$bitrate += 4;
        if (
$bits[18] == 1$bitrate += 2;
        if (
$bits[19] == 1$bitrate += 1;
        
$this->bitrate $bitrates[$this->layer][$bitrate];

        
$frequency = array(
            
'1' => array(
                
'0' => array(4410048000),
                
'1' => array(320000),
                    ),
            
'2' => array(
                
'0' => array(2205024000),
                
'1' => array(160000),
                    ),
            
'2.5' => array(
                
'0' => array(1102512000),
                
'1' => array(80000),
                      ),
              );
        
$this->frequency $frequency[$this->mpeg_ver][$bits[20]][$bits[21]];

        
$this->padding $bits[22];
        
$this->private $bits[23];

        
$mode = array(
            array(
'Stereo''Joint Stereo'),
            array(
'Dual Channel''Mono'),
                 );
        
$this->mode $mode[$bits[24]][$bits[25]];

        
// XXX: I dunno what the mode extension is for bits 26,27

        
$this->copyright $bits[28];
        
$this->original $bits[29];

        
$emphasis = array(
            array(
'none''50/15ms'),
            array(
'''CCITT j.17'),
                 );
        
$this->emphasis $emphasis[$bits[30]][$bits[31]];

        if (
$this->bitrate == 0) {
            
$s = -1;
        } else {
            
$s = ((8*filesize($file))/1000) / $this->bitrate;
        }
        
$this->length sprintf('%02d:%02d',floor($s/60),floor($s-(floor($s/60)*60)));
        
$this->lengths = (int)$s;
    }
    function 
return_info($file false) {
        if (
$file !== false) { getinfo($file); }

        if (!isset(
$this->filename)) { echo "oh"; return false; }
        else {
            if (!isset(
$this->bitrate)) { echo "do"; return false; }
            else {
                return array(
                    
'mpeg_ver'    => $this->mpeg_ver,
                    
'layer'       => $this->layer,
                    
'bitrate'     => $this->bitrate,
                    
'frequency'   => $this->frequency,
                    
'mode'        => $this->mode,
                    
'copyright'   => $this->copyright,
                    
'original'    => $this->original,
                    
'emphasis'    => $this->emphasis,
                    
'length'      => $this->length,
                    
'lengths'     => $this->lengths);
            }
        }
    }
}
?>

Last updated: Sat Jun 14 20:02:45 CEST 2008

Valid XHTML 1.0! Valid HTML 3.2!