Source Rally PHP Community Scripts .. Sign up .. Login
A class with some stuff implented to mess around with MP3-files.
Please note:
- This script has at least one bug - it won't be able to tell the length of all MP3s.
- It is very slow an takes up a lot of memory.
- It will only work with PHP5+ (small modifications will make it work in PHP4 as well)

LGPL License
Access: Public      Tags: PHP, MP3, IDV2
Add to favourites       Subscribe comments       Copy code       Bookmark
<?php
/*
//Merge two files
$path = 'path.mp3';
$path1 = 'path1.mp3';
$mp3 = new mp3($path);

$newpath = 'path.mp3';
$mp3->striptags();

$mp3_1 = new mp3($path1);
$mp3->mergeBehind($mp3_1);
$mp3->striptags();
$mp3->setIdv3_2('01','Track Title','Artist','Album','Year','Genre','Comments','Composer','OrigArtist',
'Copyright','url','encodedBy');
$mp3->save($newpath);


//Extract 30 seconds starting after 10 seconds.
$path = 'path.mp3';
$mp3 = new mp3($path);
$mp3_1 = $mp3->extract(10,30);
$mp3_1->save('newpath.mp3');

//Extract the exact length of time
$path = 'path.mp3';
$mp3 = new mp3($path);
$mp3->setFileInfoExact();
echo $mp3->time;
//note that this is the exact length!
*/
class mp3
{
    var 
$str;
    var 
$time;
    var 
$frames;
    
    function 
mp3($path="")
    {
        if(
$path!="")
        {
            
$this->str file_get_contents($path);
        }
    }
    
    function 
setStr($str)
    {
        
$this->str $str;
    }
    
    function 
setFileInfoExact()
    {
        
$maxStrLen strlen($this->str);
        
$currentStrPos strpos($this->str,chr(255));
        
$framesCount=0;
        
$time 0;
        while(
$currentStrPos $maxStrLen)
        {
            
$str substr($this->str,$currentStrPos,4);
            
$strlen strlen($str);
            
$parts = array();
            for(
$i=0;$i $strlen;$i++)
            {
                
$parts[] = $this->decbinFill(ord($str[$i]),8);
            }
            if(
$parts[0] != "11111111")
            {
                if((
$maxStrLen-128) > $currentStrPos)
                {
                    return 
false;
                }
                else
                {
                    
$this->time $time;
                    
$this->frames $framesCount;
                    return 
true;
                }
            }
            
$a $this->doFrameStuff($parts);
            
$currentStrPos += $a[0];
            
$time += $a[1];
            
$framesCount++;
        }
        
$this->time $time;
        
$this->frames $framesCount;
        return 
true;
    }
    
    function 
extract($start,$length)
    {
        
$maxStrLen strlen($this->str);
        
$currentStrPos strpos($this->str,chr(255));
        
$framesCount=0;
        
$time 0;
        
$startCount = -1;
        
$endCount = -1;
        while(
$currentStrPos $maxStrLen)
        {
            if(
$startCount==-1&&$time>=$start)
            {
                
$startCount $currentStrPos;
            }
            if(
$endCount==-1&&$time>=($start+$length))
            {
                
$endCount $currentStrPos-$startCount;
            }
            
$doFrame true;
            
$str substr($this->str,$currentStrPos,4);
            
$strlen strlen($str);
            
$parts = array();
            for(
$i=0;$i $strlen;$i++)
            {
                
$parts[] = $this->decbinFill(ord($str[$i]),8);
            }
            if(
$parts[0] != "11111111")
            {
                if((
$maxStrLen-128) > $currentStrPos)
                {
                    
$doFrame false;
                }
                else
                {
                    
$doFrame false;
                }
            }
            if(
$doFrame)
            {
                
$a $this->doFrameStuff($parts);
                
$currentStrPos += $a[0];
                
$time += $a[1];
                
$framesCount++;
            }
        }
        
$mp3 = new mp3();
        if(
$endCount == -1)
        {
            
$endCount $maxStrLen-$startCount;
        }
        if(
$startCount!=-1&&$endCount!=-1)
        {
            
$mp3->setStr(substr($this->str,$startCount,$endCount));
        }
        return 
$mp3;
    }
    
    function 
decbinFill($dec,$length=0)
    {
        
$str decbin($dec);
        
$nulls $length-strlen($str);
        if(
$nulls>0)
        {
            for(
$i=0;$i<$nulls;$i++)
            {
                
$str '0'.$str;
            }
        }
        return 
$str;
    }
    
    function 
doFrameStuff($parts)
    {
        
//Get Audio Version
        
$errors = array();
        switch(
substr($parts[1],3,2))
        {
            case 
'01':
            
$errors[]='Reserved audio version';
            break;
            case 
'00':
            
$audio 2.5;
            break;
            case 
'10':
            
$audio 2;
            break;
            case 
'11':
            
$audio 1;
            break;
        }
        
//Get Layer
        
switch(substr($parts[1],5,2))
        {
            case 
'01':
            
$layer 3;
            break;
            case 
'00':
            
$errors[]='Reserved layer';
            break;
            case 
'10':
            
$layer 2;
            break;
            case 
'11':
            
$layer 1;
            break;
        }
        
//Get Bitrate
        
$bitFlag substr($parts[2],0,4);
        
$bitArray = array(
    
'0000'    => array(free,    free,    free,    free,    free),
    
'0001'    => array(32,    32,    32,    32,    8),
    
'0010'    => array(64,    48,    40,    48,    16),
    
'0011'    => array(96,    56,    48,    56,    24),
    
'0100'    => array(128,    64,    56,    64,    32),
    
'0101'    => array(160,    80,    64,    80,    40),
    
'0110'    => array(192,    96,    80,    96,    48),
    
'0111'    => array(224,    112,    96,    112,    56),
    
'1000'    => array(256,    128,    112,    128,    64),
    
'1001'    => array(288,    160,    128,    144,    80),
    
'1010'    => array(320,    192,    160,    160,    96),
    
'1011'    => array(352,    224,    192,    176,    112),
    
'1100'    => array(384,    256,    224,    192,    128),
    
'1101'    => array(416,    320,    256,    224,    144),
    
'1110'    => array(448,    384,    320,    256,    160),
    
'1111'    => array(bad,    bad,    bad,    bad,    bad)
    );
        
$bitPart $bitArray[$bitFlag];
        
$bitArrayNumber;
        if(
$audio==1)
        {
            switch(
$layer)
            {
                case 
1:
                
$bitArrayNumber=0;
                break;
                case 
2:
                
$bitArrayNumber=1;
                break;
                case 
3:
                
$bitArrayNumber=2;
                break;
            }
        }
        else
        {
            switch(
$layer)
            {
                case 
1:
                
$bitArrayNumber=3;
                break;
                case 
2:
                
$bitArrayNumber=4;
                break;
                case 
3:
                
$bitArrayNumber=4;
                break;
            }
        }
        
$bitRate $bitPart[$bitArrayNumber];
        
//Get Frequency
        
$frequencies = array(
        
1=>array('00'=>44100,
        
'01'=>48000,
        
'10'=>32000,
        
'11'=>'reserved'),
        
2=>array(),
        
2.5=>array());
        
$freq $frequencies[$audio][substr($parts[2],4,2)];
        
//IsPadded?
        
$padding substr($parts[2],6,1);
        if(
$layer==3||$layer==2)
        {
            
//FrameLengthInBytes = 144 * BitRate / SampleRate + Padding
            
$frameLength 144 $bitRate 1000 $freq $padding;
        }
        
$frameLength floor($frameLength);
        
$seconds += $frameLength*8/($bitRate*1000);
        return array(
$frameLength,$seconds);
        
//Calculate next when next frame starts.
        //Capture next frame.    
    
}
    
    function 
setIdv3_2($track,$title,$artist,$album,$year,$genre,$comments,$composer,$origArtist,
$copyright,$url,$encodedBy)
    {
        
$urlLength = (int)(strlen($url)+2);
        
$copyrightLength = (int)(strlen($copyright)+1);
        
$origArtistLength = (int)(strlen($origArtist)+1);
        
$composerLength = (int)(strlen($composer)+1);
        
$commentsLength = (int)strlen($comments)+5;
        
$titleLength = (int) strlen($title)+1;
        
$artistLength = (int)strlen($artist)+1;
        
$albumLength = (int) strlen($album)+1;
        
$genreLength = (int) strlen($genre)+1;
        
$encodedByLength = (int)(strlen($encodedBy)+1);
        
$trackLength = (int) strlen($track) + 1;
        
$yearLength = (int) strlen($year)+1;
        
$str .= chr(73);//I
        
$str .= chr(68);//D
        
$str .= chr(51);//3
        
$str .= chr(3);//
        
$str .= chr(0);//
        
$str .= chr(0);//
        
$str .= chr(0);//
        
$str .= chr(0);//
        
$str .= chr(8);//
        
$str .= chr(53);//5
        
$str .= chr(84);//T
        
$str .= chr(82);//R
        
$str .= chr(67);//C
        
$str .= chr(75);//K
        
$str .= chr(0);//
        
$str .= chr(0);//
        
$str .= chr(0);//
        
$str .= chr($trackLength);//
        
$str .= chr(0);//
        
$str .= chr(0);//
        
$str .= chr(0);//
        
$str .= $track;
        
$str .= chr(84);//T
        
$str .= chr(69);//E
        
$str .= chr(78);//N
        
$str .= chr(67);//C
        
$str .= chr(0);//
        
$str .= chr(0);//
        
$str .= chr(0);//
        
$str .= chr($encodedByLength);//
        
$str .= chr(64);//@
        
$str .= chr(0);//
        
$str .= chr(0);//
        
$str .= $encodedBy;
        
$str .= chr(87);//W
        
$str .= chr(88);//X
        
$str .= chr(88);//X
        
$str .= chr(88);//X
        
$str .= chr(0);//
        
$str .= chr(0);//
        
$str .= chr(0);//
        
$str .= chr($urlLength);//
        
$str .= chr(0);//
        
$str .= chr(0);//
        
$str .= chr(0);//
        
$str .= chr(0);//
        
$str .= $url;
        
$str .= chr(84);//T
        
$str .= chr(67);//C
        
$str .= chr(79);//O
        
$str .= chr(80);//P
        
$str .= chr(0);//
        
$str .= chr(0);//
        
$str .= chr(0);//
        
$str .= chr($copyrightLength);//
        
$str .= chr(0);//
        
$str .= chr(0);//
        
$str .= chr(0);//
        
$str .= $copyright;
        
$str .= chr(84);//T
        
$str .= chr(79);//O
        
$str .= chr(80);//P
        
$str .= chr(69);//E
        
$str .= chr(0);//
        
$str .= chr(0);//
        
$str .= chr(0);//
        
$str .= chr($origArtistLength);//
        
$str .= chr(0);//
        
$str .= chr(0);//
        
$str .= chr(0);//
        
$str .= $origArtist;
        
$str .= chr(84);//T
        
$str .= chr(67);//C
        
$str .= chr(79);//O
        
$str .= chr(77);//M
        
$str .= chr(0);//
        
$str .= chr(0);//
        
$str .= chr(0);//
        
$str .= chr($composerLength);//
        
$str .= chr(0);//
        
$str .= chr(0);//
        
$str .= chr(0);//
        
$str .= $composer;
        
$str .= chr(67);//C
        
$str .= chr(79);//O
        
$str .= chr(77);//M
        
$str .= chr(77);//M
        
$str .= chr(0);//
        
$str .= chr(0);//
        
$str .= chr(0);//
        
$str .= chr($commentsLength);//
        
$str .= chr(0);//
        
$str .= chr(0);//
        
$str .= chr(0);//
        
$str .= chr(0);//
        
$str .= chr(9);//
        
$str .= chr(0);//
        
$str .= chr(0);//
        
$str .= $comments;
        
$str .= chr(84);//T

        
$str .= chr(67);//C
        
$str .= chr(79);//O
        
$str .= chr(78);//N
        
$str .= chr(0);//
        
$str .= chr(0);//
        
$str .= chr(0);//
        
$str .= chr($genreLength);//
        
$str .= chr(0);//
        
$str .= chr(0);//
        
$str .= chr(0);//
        
$str .= $genre;
        
$str .= chr(84);//T
        
$str .= chr(89);//Y
        
$str .= chr(69);//E
        
$str .= chr(82);//R
        
$str .= chr(0);//
        
$str .= chr(0);//
        
$str .= chr(0);//
        
$str .= chr($yearLength);//
        
$str .= chr(0);//
        
$str .= chr(0);//
        
$str .= chr(0);//
        
$str .= $year;
        
$str .= chr(84);//T
        
$str .= chr(65);//A
        
$str .= chr(76);//L
        
$str .= chr(66);//B
        
$str .= chr(0);//
        
$str .= chr(0);//
        
$str .= chr(0);//
        
$str .= chr($albumLength);//
        
$str .= chr(0);//
        
$str .= chr(0);//
        
$str .= chr(0);//
        
$str .= $album;
        
$str .= chr(84);//T
        
$str .= chr(80);//P
        
$str .= chr(69);//E
        
$str .= chr(49);//1
        
$str .= chr(0);//
        
$str .= chr(0);//
        
$str .= chr(0);//
        
$str .= chr($artistLength);//
        
$str .= chr(0);//
        
$str .= chr(0);//
        
$str .= chr(0);//
        
$str .= $artist;
        
$str .= chr(84);//T
        
$str .= chr(73);//I
        
$str .= chr(84);//T
        
$str .= chr(50);//2
        
$str .= chr(0);//
        
$str .= chr(0);//
        
$str .= chr(0);//
        
$str .= chr($titleLength);//
        
$str .= chr(0);//
        
$str .= chr(0);//
        
$str .= chr(0);//
        
$str .= $title;
        
$this->str $str.$this->str;
    }
    
    function 
mergeBehind(mp3 $mp3)
    {
        
$this->str .= $mp3->str;
    }
    
    function 
mergeInfront(mp3 $mp3)
    {
        
$this->str $mp3->str.$this->str;
    }
    
    function 
getIdvEnd()
    {
        
$strlen strlen($this->str);
        
$str substr($this->str,($strlen-128));
        
$str1 substr($str,0,3);
        if(
strtolower($str1) == strtolower('TAG'))
        {
            return 
$str;
        }
        else
        {
            return 
false;
        }
    }
    
    function 
getStart()
    {
        
$strlen strlen($this->str);
        for(
$i=0;$i<$strlen;$i++)
        {
            
$v substr($this->str,$i,1);
            
$value ord($v);
            if(
$value == 255)
            {
                return 
$i;
            }
        }
    }
    
    function 
striptags()
    {
        
//Remove start stuff...
        
$newStr '';
        
$s $start $this->getStart();
        if(
$s===false)
        {
            return 
false;
        }
        else
        {
            
$this->str substr($this->str,$start);
        }
        
//Remove end tag stuff
        
$end $this->getIdvEnd();
        if(
$end!==false)
        {
            
$this->str substr($this->str,0,(strlen($this->str)-129));
        }
    }
    
    function 
save($path)
    {
        
$fp fopen($path,'w');
        
fwrite($fp,$this->str);
        
fclose($fp);
    }
}
?>
Add to favourites       Subscribe comments       Copy code       Bookmark
Sign up to add your own comment here!

Comments