Home > Backend Development > PHP Tutorial > Example tutorial of obtaining mp3 audio information in php

Example tutorial of obtaining mp3 audio information in php

coldplay.xixi
Release: 2023-04-08 21:58:01
forward
2518 people have browsed it

Example tutorial of obtaining mp3 audio information in php

php Get mp3 audio information

A long time ago I saw a php class on the Internet for getting MP3 audio information . Such as: playback duration, file size, file encoding, etc.

<?php
class mp3file
{
    protected $block;
    protected $blockpos;
    protected $blockmax;
    protected $blocksize;
    protected $fd;
    protected $bitpos;
    protected $mp3data;
    public function __construct($filename)
    {
        $this->powarr  = array(0=>1,1=>2,2=>4,3=>8,4=>16,5=>32,6=>64,7=>128);
        $this->blockmax= 1024;
        
        $this->mp3data = array();
        $this->mp3data[&#39;Filesize&#39;] = filesize($filename);
        $this->fd = fopen($filename,&#39;rb&#39;);
        $this->prefetchblock();
        $this->readmp3frame();
    }
    public function __destruct()
    {
        fclose($this->fd);
    }
    //-------------------
    public function get_metadata()
    {
        return $this->mp3data;
    }
    protected function readmp3frame()
    {
        $iscbrmp3=true;
        if ($this->startswithid3())
            $this->skipid3tag();
        else if ($this->containsvbrxing())
        {
            $this->mp3data[&#39;Encoding&#39;] = &#39;VBR&#39;;
            $iscbrmp3=false;
        }
        else if ($this->startswithpk())
        {
            $this->mp3data[&#39;Encoding&#39;] = &#39;Unknown&#39;;
            $iscbrmp3=false;
        }
    
        if ($iscbrmp3)
        {
            $i = 0;
            $max=5000;
            //look in 5000 bytes... 
            //the largest framesize is 4609bytes(256kbps@8000Hz  mp3)
            for($i=0; $i<$max; $i++)
            {
                //looking for 1111 1111 111 (frame synchronization bits)                
                if ($this->getnextbyte()==0xFF)
                    if ($this->getnextbit() && $this->getnextbit() && $this->getnextbit())
                        break;
            }
            if ($i==$max)
                $iscbrmp3=false;
        }
    
        if ($iscbrmp3)
        {
            $this->mp3data[&#39;Encoding&#39;         ] = &#39;CBR&#39;;
            $this->mp3data[&#39;MPEG version&#39;     ] = $this->getnextbits(2);
            $this->mp3data[&#39;Layer Description&#39;] = $this->getnextbits(2);
            $this->mp3data[&#39;Protection Bit&#39;   ] = $this->getnextbits(1);
            $this->mp3data[&#39;Bitrate Index&#39;    ] = $this->getnextbits(4);
            $this->mp3data[&#39;Sampling Freq Idx&#39;] = $this->getnextbits(2);
            $this->mp3data[&#39;Padding Bit&#39;      ] = $this->getnextbits(1);
            $this->mp3data[&#39;Private Bit&#39;      ] = $this->getnextbits(1);
            $this->mp3data[&#39;Channel Mode&#39;     ] = $this->getnextbits(2);
            $this->mp3data[&#39;Mode Extension&#39;   ] = $this->getnextbits(2);
            $this->mp3data[&#39;Copyright&#39;        ] = $this->getnextbits(1);
            $this->mp3data[&#39;Original Media&#39;   ] = $this->getnextbits(1);
            $this->mp3data[&#39;Emphasis&#39;         ] = $this->getnextbits(1);
            $this->mp3data[&#39;Bitrate&#39;          ] = mp3file::bitratelookup($this->mp3data);
            $this->mp3data[&#39;Sampling Rate&#39;    ] = mp3file::samplelookup($this->mp3data);
            $this->mp3data[&#39;Frame Size&#39;       ] = mp3file::getframesize($this->mp3data);
            $this->mp3data[&#39;Length&#39;           ] = mp3file::getduration($this->mp3data,$this->tell2());
            $this->mp3data[&#39;Length mm:ss&#39;     ] = mp3file::seconds_to_mmss($this->mp3data[&#39;Length&#39;]);
            
            if ($this->mp3data[&#39;Bitrate&#39;      ]==&#39;bad&#39;     ||
                $this->mp3data[&#39;Bitrate&#39;      ]==&#39;free&#39;    ||
                $this->mp3data[&#39;Sampling Rate&#39;]==&#39;unknown&#39; ||
                $this->mp3data[&#39;Frame Size&#39;   ]==&#39;unknown&#39; ||
                $this->mp3data[&#39;Length&#39;     ]==&#39;unknown&#39;)
            $this->mp3data = array(&#39;Filesize&#39;=>$this->mp3data[&#39;Filesize&#39;], &#39;Encoding&#39;=>&#39;Unknown&#39;);
        }
        else
        {
            if(!isset($this->mp3data[&#39;Encoding&#39;]))
                $this->mp3data[&#39;Encoding&#39;] = &#39;Unknown&#39;;
        }
    }
    protected function tell()
    {
        return ftell($this->fd);
    }
    protected function tell2()
    {
        return ftell($this->fd)-$this->blockmax +$this->blockpos-1;
    }
    protected function startswithid3()
    {
        return ($this->block[1]==73 && //I
                $this->block[2]==68 && //D
                $this->block[3]==51);  //3
    }
    protected function startswithpk()
    {
        return ($this->block[1]==80 && //P
                $this->block[2]==75);  //K
    }
    protected function containsvbrxing()
    {
        //echo "<!--".$this->block[37]." ".$this->block[38]."-->";
        //echo "<!--".$this->block[39]." ".$this->block[40]."-->";
        return(
               ($this->block[37]==88  && //X 0x58
                $this->block[38]==105 && //i 0x69
                $this->block[39]==110 && //n 0x6E
                $this->block[40]==103)   //g 0x67
/*               || 
               ($this->block[21]==88  && //X 0x58
                $this->block[22]==105 && //i 0x69
                $this->block[23]==110 && //n 0x6E
                $this->block[24]==103)   //g 0x67*/
              );   
    } 
    protected function debugbytes()
    {
        for($j=0; $j<10; $j++)
        {
            for($i=0; $i<8; $i++)
            {
                if ($i==4) echo " ";
                echo $this->getnextbit();
            }
            echo "<BR>";
        }
    }
    protected function prefetchblock()
    {
        $block = fread($this->fd, $this->blockmax);
        $this->blocksize = strlen($block);
        $this->block = unpack("C*", $block);
        $this->blockpos=0;
    }
    protected function skipid3tag()
    {
        $bits=$this->getnextbits(24);//ID3
        $bits.=$this->getnextbits(24);//v.v flags
        //3 bytes 1 version byte 2 byte flags
        $arr = array();
        $arr[&#39;ID3v2 Major version&#39;] = bindec(substr($bits,24,8));
        $arr[&#39;ID3v2 Minor version&#39;] = bindec(substr($bits,32,8));
        $arr[&#39;ID3v2 flags&#39;        ] = bindec(substr($bits,40,8));
        if (substr($bits,40,1)) $arr[&#39;Unsynchronisation&#39;]=true;
        if (substr($bits,41,1)) $arr[&#39;Extended header&#39;]=true;
        if (substr($bits,42,1)) $arr[&#39;Experimental indicator&#39;]=true;
        if (substr($bits,43,1)) $arr[&#39;Footer present&#39;]=true;
        $size = "";
        for($i=0; $i<4; $i++)
        {
            $this->getnextbit();//skip this bit, should be 0
            $size.= $this->getnextbits(7);
        }
        $arr[&#39;ID3v2 Tags Size&#39;]=bindec($size);//now the size is in bytes;
        if ($arr[&#39;ID3v2 Tags Size&#39;] - $this->blockmax>0)
        {
            fseek($this->fd, $arr[&#39;ID3v2 Tags Size&#39;]+10 );
            $this->prefetchblock();
            if (isset($arr[&#39;Footer present&#39;]) && $arr[&#39;Footer present&#39;])
            {
                for($i=0; $i<10; $i++)
                    $this->getnextbyte();//10 footer bytes
            }
        }
        else
        {
            for($i=0; $i<$arr[&#39;ID3v2 Tags Size&#39;]; $i++)
                $this->getnextbyte();
        }
    }
    protected function getnextbit()
    {
        if ($this->bitpos==8)
            return false;
        $b=0;
        $whichbit = 7-$this->bitpos;
        $mult = $this->powarr[$whichbit]; //$mult = pow(2,7-$this->pos);
        $b = $this->block[$this->blockpos+1] & $mult;
        $b = $b >> $whichbit;
        $this->bitpos++;
        if ($this->bitpos==8)
        {
            $this->blockpos++;
                
            if ($this->blockpos==$this->blockmax) //end of block reached
            {
                $this->prefetchblock();
            }
            else if ($this->blockpos==$this->blocksize) 
            {//end of short block reached (shorter than blockmax)
                return;//eof 
            }
            
            $this->bitpos=0;
        }
        return $b;
    }
    protected function getnextbits($n=1)
    {
        $b="";
        for($i=0; $i<$n; $i++)
            $b.=$this->getnextbit();
        return $b;
    }
    protected function getnextbyte()
    {
        if ($this->blockpos>=$this->blocksize)
            return;
        $this->bitpos=0;
        $b=$this->block[$this->blockpos+1];
        $this->blockpos++;
        return $b;
    }
    //-----------------------------------------------------------------------------
    public static function is_layer1(&$mp3) { return ($mp3[&#39;Layer Description&#39;]==&#39;11&#39;); }
    public static function is_layer2(&$mp3) { return ($mp3[&#39;Layer Description&#39;]==&#39;10&#39;); }
    public static function is_layer3(&$mp3) { return ($mp3[&#39;Layer Description&#39;]==&#39;01&#39;); }
    public static function is_mpeg10(&$mp3)  { return ($mp3[&#39;MPEG version&#39;]==&#39;11&#39;); }
    public static function is_mpeg20(&$mp3)  { return ($mp3[&#39;MPEG version&#39;]==&#39;10&#39;); }
    public static function is_mpeg25(&$mp3)  { return ($mp3[&#39;MPEG version&#39;]==&#39;00&#39;); }
    public static function is_mpeg20or25(&$mp3)  { return ($mp3[&#39;MPEG version&#39;]{1}==&#39;0&#39;); }
    //-----------------------------------------------------------------------------
    public static function bitratelookup(&$mp3)
    {
        //bits               V1,L1  V1,L2  V1,L3  V2,L1  V2,L2&L3
        $array = array();
        $array[&#39;0000&#39;]=array(&#39;free&#39;,&#39;free&#39;,&#39;free&#39;,&#39;free&#39;,&#39;free&#39;);
        $array[&#39;0001&#39;]=array(  &#39;32&#39;,  &#39;32&#39;,  &#39;32&#39;,  &#39;32&#39;,   &#39;8&#39;);
        $array[&#39;0010&#39;]=array(  &#39;64&#39;,  &#39;48&#39;,  &#39;40&#39;,  &#39;48&#39;,  &#39;16&#39;);
        $array[&#39;0011&#39;]=array(  &#39;96&#39;,  &#39;56&#39;,  &#39;48&#39;,  &#39;56&#39;,  &#39;24&#39;);
        $array[&#39;0100&#39;]=array( &#39;128&#39;,  &#39;64&#39;,  &#39;56&#39;,  &#39;64&#39;,  &#39;32&#39;);
        $array[&#39;0101&#39;]=array( &#39;160&#39;,  &#39;80&#39;,  &#39;64&#39;,  &#39;80&#39;,  &#39;40&#39;);
        $array[&#39;0110&#39;]=array( &#39;192&#39;,  &#39;96&#39;,  &#39;80&#39;,  &#39;96&#39;,  &#39;48&#39;);
        $array[&#39;0111&#39;]=array( &#39;224&#39;, &#39;112&#39;,  &#39;96&#39;, &#39;112&#39;,  &#39;56&#39;);
        $array[&#39;1000&#39;]=array( &#39;256&#39;, &#39;128&#39;, &#39;112&#39;, &#39;128&#39;,  &#39;64&#39;);
        $array[&#39;1001&#39;]=array( &#39;288&#39;, &#39;160&#39;, &#39;128&#39;, &#39;144&#39;,  &#39;80&#39;);
        $array[&#39;1010&#39;]=array( &#39;320&#39;, &#39;192&#39;, &#39;160&#39;, &#39;160&#39;,  &#39;96&#39;);
        $array[&#39;1011&#39;]=array( &#39;352&#39;, &#39;224&#39;, &#39;192&#39;, &#39;176&#39;, &#39;112&#39;);
        $array[&#39;1100&#39;]=array( &#39;384&#39;, &#39;256&#39;, &#39;224&#39;, &#39;192&#39;, &#39;128&#39;);
        $array[&#39;1101&#39;]=array( &#39;416&#39;, &#39;320&#39;, &#39;256&#39;, &#39;224&#39;, &#39;144&#39;);
        $array[&#39;1110&#39;]=array( &#39;448&#39;, &#39;384&#39;, &#39;320&#39;, &#39;256&#39;, &#39;160&#39;);
        $array[&#39;1111&#39;]=array( &#39;bad&#39;, &#39;bad&#39;, &#39;bad&#39;, &#39;bad&#39;, &#39;bad&#39;);
        
        $whichcolumn=-1;
        if      (mp3file::is_mpeg10($mp3) && mp3file::is_layer1($mp3) )//V1,L1
            $whichcolumn=0;
        else if (mp3file::is_mpeg10($mp3) && mp3file::is_layer2($mp3) )//V1,L2
            $whichcolumn=1;
        else if (mp3file::is_mpeg10($mp3) && mp3file::is_layer3($mp3) )//V1,L3
            $whichcolumn=2;
        else if (mp3file::is_mpeg20or25($mp3) && mp3file::is_layer1($mp3) )//V2,L1
            $whichcolumn=3;
        else if (mp3file::is_mpeg20or25($mp3) && (mp3file::is_layer2($mp3) || mp3file::is_layer3($mp3)) )
            $whichcolumn=4;//V2,   L2||L3 
        
        if (isset($array[$mp3[&#39;Bitrate Index&#39;]][$whichcolumn]))
            return $array[$mp3[&#39;Bitrate Index&#39;]][$whichcolumn];
        else 
            return "bad";
    }
    //-----------------------------------------------------------------------------
    public static function samplelookup(&$mp3)
    {
        //bits               MPEG1   MPEG2   MPEG2.5
        $array = array();
        $array[&#39;00&#39;] =array(&#39;44100&#39;,&#39;22050&#39;,&#39;11025&#39;);
        $array[&#39;01&#39;] =array(&#39;48000&#39;,&#39;24000&#39;,&#39;12000&#39;);
        $array[&#39;10&#39;] =array(&#39;32000&#39;,&#39;16000&#39;,&#39;8000&#39;);
        $array[&#39;11&#39;] =array(&#39;res&#39;,&#39;res&#39;,&#39;res&#39;);
        
        $whichcolumn=-1;
        if      (mp3file::is_mpeg10($mp3))
            $whichcolumn=0;
        else if (mp3file::is_mpeg20($mp3))
            $whichcolumn=1;
        else if (mp3file::is_mpeg25($mp3))
            $whichcolumn=2;
        
        if (isset($array[$mp3[&#39;Sampling Freq Idx&#39;]][$whichcolumn]))
            return $array[$mp3[&#39;Sampling Freq Idx&#39;]][$whichcolumn];
        else 
            return &#39;unknown&#39;;
    }
    //-----------------------------------------------------------------------------
    public static function getframesize(&$mp3)
    {
        if ($mp3[&#39;Sampling Rate&#39;]>0)
        {
            return  ceil((144 * $mp3[&#39;Bitrate&#39;]*1000)/$mp3[&#39;Sampling Rate&#39;]) + $mp3[&#39;Padding Bit&#39;];
        }
        return &#39;unknown&#39;;
    }
    //-----------------------------------------------------------------------------
    public static function getduration(&$mp3,$startat)
    {
        if ($mp3[&#39;Bitrate&#39;]>0)
        {
            $KBps = ($mp3[&#39;Bitrate&#39;]*1000)/8;
            $datasize = ($mp3[&#39;Filesize&#39;] - ($startat/8));
            $length = $datasize / $KBps;
            return sprintf("%d", $length);
        }
        return "unknown";
    }
    //-----------------------------------------------------------------------------
    public static function seconds_to_mmss($duration)
    {
        return sprintf("%d:%02d", ($duration /60), $duration %60 );
    }
}
Copy after login

Call

<?php
include_once &#39;mp3file.class.php&#39;;
function mp3Time($file) {
   $m = new mp3file($file);
   $a = $m->get_metadata();
   return $a[&#39;Length mm:ss&#39;] ? $a[&#39;Length mm:ss&#39;] : 0;
}
function mp3Info($file) {
   $m = new mp3file($file);
   return $m->get_metadata();
}
$_time = mp3Time(&#39;Beyond-情人.mp3&#39;);
echo "歌曲时间长:{$_time}\n";
$_info = mp3Info(&#39;Beyond-情人.mp3&#39;);
print_r($_info);
Copy after login

Output information

→ php mp3.php
歌曲时间长:5:15
Array
(
    [Filesize] => 7576152
    [Encoding] => CBR
    [MPEG version] => 11
    [Layer Description] => 01
    [Protection Bit] => 1
    [Bitrate Index] => 1011
    [Sampling Freq Idx] => 00
    [Padding Bit] => 0
    [Private Bit] => 0
    [Channel Mode] => 00
    [Mode Extension] => 00
    [Copyright] => 0
    [Original Media] => 1
    [Emphasis] => 0
    [Bitrate] => 192
    [Sampling Rate] => 44100
    [Frame Size] => 627
    [Length] => 315
    [Length mm:ss] => 5:15
)
Copy after login

Recommended tutorial: "php video tutorial"

The above is the detailed content of Example tutorial of obtaining mp3 audio information in php. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:aiti.fun
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template