web-dev-qa-db-fra.com

PHP Fonction pour obtenir la durée du MP3

Existe-t-il une fonction PHP qui me donne la durée du MP3? J'ai jeté un œil à la fonction ID 3, mais je n'y vois rien pendant un moment, et mis à part cela, id3 est une sorte de tag, qui ne sera pas présent dans tous les fichiers MP3.

25
ram

Cela devrait fonctionner pour vous. Notez la fonction getduration: http://www.zedwood.com/article/127/php-calculate-duration-of-mp3

29
Richard Askew

Installez getid3, mais si vous avez seulement besoin de durée, vous pouvez supprimer tous les modules sauf ceux-ci:

  • module.audio.mp3.php
  • module.tag.id3v1.php
  • module.tag.apetag.php
  • module.tag.id3v2.php

Accédez à la durée avec un code comme celui-ci:

$getID3 = new getID3;
$ThisFileInfo = $getID3->analyze($pathName);
$len= @$ThisFileInfo['playtime_string']; // playtime in minutes:seconds, formatted string

Obtenez-le à Sourceforge

25
TecBrat

Vous pouvez obtenir la durée d’un mp3 ou de nombreux autres fichiers audio/vidéo en utilisant ffmpeg.

  1. Installez ffmpeg sur votre serveur.
  2. Assurez-vous que php Shell_exec n'est pas restreint dans votre php.

        // Discriminate only the audio/video files you want
        if(preg_match('/[^?#]+\.(?:wma|mp3|wav|mp4)/', strtolower($file))){
            $filepath = /* your file path */;
            // execute ffmpeg form linux Shell and grab duration from output
            $result = Shell_exec("ffmpeg -i ".$filepath.' 2>&1 | grep -o \'Duration: [0-9:.]*\'');
            $duration = str_replace('Duration: ', '', $result); // 00:05:03.25
    
            //get the duration in seconds
            $timeArr = preg_split('/:/', str_replace('s', '', $duration[0]));
            $t = $this->_times[$file] = (($timeArr[3])? $timeArr[3]*1 + $timeArr[2] * 60 + $timeArr[1] * 60 * 60 : $timeArr[2] + $timeArr[1] * 60)*1000;
    
        }
    
7
awavi

J'ai passé tellement de temps, mais sans getID3 ( http://getid3.sourceforge.net/ ) pour obtenir la durée du fichier audio impossible.

1) Première bibliothèque de téléchargement de getID3 en utilisant le lien ci-dessous:

 https://github.com/JamesHeinrich/getID3/archive/master.Zip

2) Essayez ce code ci-dessous:

    <?php
       include("getid3/getid3.php");
       $filename = 'bcd4ecc6bf521da9b9a2d8b9616d1505.wav';
       $getID3 = new getID3;
       $file = $getID3->analyze($filename);
       $playtime_seconds = $file['playtime_seconds'];
       echo gmdate("H:i:s", $playtime_seconds);
    ?>
7
Mohin Mathakia
<?php
class MP3File
{
protected $filename;
public function __construct($filename)
{
    $this->filename = $filename;
}

public static function formatTime($duration) //as hh:mm:ss
{
    //return sprintf("%d:%02d", $duration/60, $duration%60);
    $hours = floor($duration / 3600);
    $minutes = floor( ($duration - ($hours * 3600)) / 60);
    $seconds = $duration - ($hours * 3600) - ($minutes * 60);
    return sprintf("%02d:%02d:%02d", $hours, $minutes, $seconds);
}

//Read first mp3 frame only...  use for CBR constant bit rate MP3s
public function getDurationEstimate()
{
    return $this->getDuration($use_cbr_estimate=true);
}

//Read entire file, frame by frame... ie: Variable Bit Rate (VBR)
public function getDuration($use_cbr_estimate=false)
{
    $fd = fopen($this->filename, "rb");

    $duration=0;
    $block = fread($fd, 100);
    $offset = $this->skipID3v2Tag($block);
    fseek($fd, $offset, SEEK_SET);
    while (!feof($fd))
    {
        $block = fread($fd, 10);
        if (strlen($block)<10) { break; }
        //looking for 1111 1111 111 (frame synchronization bits)
        else if ($block[0]=="\xff" && (ord($block[1])&0xe0) )
        {
            $info = self::parseFrameHeader(substr($block, 0, 4));
            if (empty($info['Framesize'])) { return $duration; } //some corrupt mp3 files
            fseek($fd, $info['Framesize']-10, SEEK_CUR);
            $duration += ( $info['Samples'] / $info['Sampling Rate'] );
        }
        else if (substr($block, 0, 3)=='TAG')
        {
            fseek($fd, 128-10, SEEK_CUR);//skip over id3v1 tag size
        }
        else
        {
            fseek($fd, -9, SEEK_CUR);
        }
        if ($use_cbr_estimate && !empty($info))
        { 
            return $this->estimateDuration($info['Bitrate'],$offset); 
        }
    }
    return round($duration);
}

private function estimateDuration($bitrate,$offset)
{
    $kbps = ($bitrate*1000)/8;
    $datasize = filesize($this->filename) - $offset;
    return round($datasize / $kbps);
}

private function skipID3v2Tag(&$block)
{
    if (substr($block, 0,3)=="ID3")
    {
        $id3v2_major_version = ord($block[3]);
        $id3v2_minor_version = ord($block[4]);
        $id3v2_flags = ord($block[5]);
        $flag_unsynchronisation  = $id3v2_flags & 0x80 ? 1 : 0;
        $flag_extended_header    = $id3v2_flags & 0x40 ? 1 : 0;
        $flag_experimental_ind   = $id3v2_flags & 0x20 ? 1 : 0;
        $flag_footer_present     = $id3v2_flags & 0x10 ? 1 : 0;
        $z0 = ord($block[6]);
        $z1 = ord($block[7]);
        $z2 = ord($block[8]);
        $z3 = ord($block[9]);
        if ( (($z0&0x80)==0) && (($z1&0x80)==0) && (($z2&0x80)==0) && (($z3&0x80)==0) )
        {
            $header_size = 10;
            $tag_size = (($z0&0x7f) * 2097152) + (($z1&0x7f) * 16384) + (($z2&0x7f) * 128) + ($z3&0x7f);
            $footer_size = $flag_footer_present ? 10 : 0;
            return $header_size + $tag_size + $footer_size;//bytes to skip
        }
    }
    return 0;
}

public static function parseFrameHeader($fourbytes)
{
    static $versions = array(
        0x0=>'2.5',0x1=>'x',0x2=>'2',0x3=>'1', // x=>'reserved'
    );
    static $layers = array(
        0x0=>'x',0x1=>'3',0x2=>'2',0x3=>'1', // x=>'reserved'
    );
    static $bitrates = array(
        'V1L1'=>array(0,32,64,96,128,160,192,224,256,288,320,352,384,416,448),
        'V1L2'=>array(0,32,48,56, 64, 80, 96,112,128,160,192,224,256,320,384),
        'V1L3'=>array(0,32,40,48, 56, 64, 80, 96,112,128,160,192,224,256,320),
        'V2L1'=>array(0,32,48,56, 64, 80, 96,112,128,144,160,176,192,224,256),
        'V2L2'=>array(0, 8,16,24, 32, 40, 48, 56, 64, 80, 96,112,128,144,160),
        'V2L3'=>array(0, 8,16,24, 32, 40, 48, 56, 64, 80, 96,112,128,144,160),
    );
    static $sample_rates = array(
        '1'   => array(44100,48000,32000),
        '2'   => array(22050,24000,16000),
        '2.5' => array(11025,12000, 8000),
    );
    static $samples = array(
        1 => array( 1 => 384, 2 =>1152, 3 =>1152, ), //MPEGv1,     Layers 1,2,3
        2 => array( 1 => 384, 2 =>1152, 3 => 576, ), //MPEGv2/2.5, Layers 1,2,3
    );
    //$b0=ord($fourbytes[0]);//will always be 0xff
    $b1=ord($fourbytes[1]);
    $b2=ord($fourbytes[2]);
    $b3=ord($fourbytes[3]);

    $version_bits = ($b1 & 0x18) >> 3;
    $version = $versions[$version_bits];
    $simple_version =  ($version=='2.5' ? 2 : $version);

    $layer_bits = ($b1 & 0x06) >> 1;
    $layer = $layers[$layer_bits];

    $protection_bit = ($b1 & 0x01);
    $bitrate_key = sprintf('V%dL%d', $simple_version , $layer);
    $bitrate_idx = ($b2 & 0xf0) >> 4;
    $bitrate = isset($bitrates[$bitrate_key][$bitrate_idx]) ? $bitrates[$bitrate_key][$bitrate_idx] : 0;

    $sample_rate_idx = ($b2 & 0x0c) >> 2;//0xc => b1100
    $sample_rate = isset($sample_rates[$version][$sample_rate_idx]) ? $sample_rates[$version][$sample_rate_idx] : 0;
    $padding_bit = ($b2 & 0x02) >> 1;
    $private_bit = ($b2 & 0x01);
    $channel_mode_bits = ($b3 & 0xc0) >> 6;
    $mode_extension_bits = ($b3 & 0x30) >> 4;
    $copyright_bit = ($b3 & 0x08) >> 3;
    $original_bit = ($b3 & 0x04) >> 2;
    $emphasis = ($b3 & 0x03);

    $info = array();
    $info['Version'] = $version;//MPEGVersion
    $info['Layer'] = $layer;
    //$info['Protection Bit'] = $protection_bit; //0=> protected by 2 byte CRC, 1=>not protected
    $info['Bitrate'] = $bitrate;
    $info['Sampling Rate'] = $sample_rate;
    $info['Framesize'] = self::framesize($layer, $bitrate, $sample_rate, $padding_bit);
    $info['Samples'] = $samples[$simple_version][$layer];
    return $info;
}

private static function framesize($layer, $bitrate,$sample_rate,$padding_bit)
{
    if ($layer==1)
        return intval(((12 * $bitrate*1000 /$sample_rate) + $padding_bit) * 4);
    else //layer 2, 3
        return intval(((144 * $bitrate*1000)/$sample_rate) + $padding_bit);
}
}
?>
<?php
$mp3file = new MP3File("Chal_Halke.mp3");//http://www.npr.org/rss/podcast.php?id=510282
$duration1 = $mp3file->getDurationEstimate();//(faster) for CBR only
$duration2 = $mp3file->getDuration();//(slower) for VBR (or CBR)
echo "duration: $duration1 seconds"."\n";

?>
3
debasish

Il n'y a pas de fonction php native pour faire cela.

Selon l'environnement de votre serveur, vous pouvez utiliser un outil tel que MP3Info .

$length = Shell_exec('mp3info -p "%S" sample.mp3');   // total time in seconds
3
Ragnar123

La longueur du fichier MP3 n’est stockée nulle part (dans le format MP3 "ordinaire"), car le format MP3 est conçu pour être "divisé" en images et ces images restent lisibles.

http://mpgedit.org/mpgedit/mpeg_format/mpeghdr.htm

Si vous ne disposez d'aucun identifiant sur lequel vous baser, ce que vous devez faire (il existe des outils et des classes PHP qui le font) consiste à lire le fichier MP3 dans son intégralité et à additionner les durées de chaque image.

1
LSerni

Comme précédemment, j’avais fourni une solution à la fois pour les fichiers mp3 et WAV. Maintenant, cette solution est spécifiquement destinée au seul fichier WAV avec plus de précisionévaluation fois que la solution précédente.

function calculateWavDuration( $file ) {

    $fp = fopen($file, 'r');

    if (fread($fp, 4) == "RIFF") {

        fseek($fp, 20);
        $raw_header = fread($fp, 16);
        $header = unpack('vtype/vchannels/Vsamplerate/Vbytespersec/valignment/vbits', $raw_header);
        $pos = ftell($fp);

        while (fread($fp, 4) != "data" && !feof($fp)) {

            $pos++;
            fseek($fp, $pos);

        }

        $raw_header = fread($fp, 4);
        $data = unpack('Vdatasize', $raw_header);
        $sec = $data[datasize] / $header[bytespersec];
        $minutes = intval(($sec / 60) % 60);
        $seconds = intval($sec % 60);

        return str_pad($minutes, 2, "0", STR_PAD_LEFT) . ":" . str_pad($seconds, 2, "0", STR_PAD_LEFT);

    }

}

$file = '1.wav'; //Enter File wav
calculateWavDuration($file);
1

Enfin, j'ai développé une solution avec mes propres calculs. Cette solution fonctionne mieux pour les formats de fichiers mp3 et WAV. Cependant, des variations de précision mineures sont attendues. La solution est dans PHP. Je prends un petit indice de WAV

function calculateFileSize($file){

    $ratio = 16000; //bytespersec

    if (!$file) {

        exit("Verify file name and it's path");

    }

    $file_size = filesize($file);

    if (!$file_size)
        exit("Verify file, something wrong with your file");

    $duration = ($file_size / $ratio);
    $minutes = floor($duration / 60);
    $seconds = $duration - ($minutes * 60);
    $seconds = round($seconds);
    echo "$minutes:$seconds minutes";

}

$file = 'Apple-classic.mp3'; //Enter File Name mp3/wav
calculateFileSize($file);
1
$getID3 = new getID3;
$ThisFileInfo = $getID3->analyze($pathName);

// playtime in minutes:seconds, formatted string
$len = @$ThisFileInfo['playtime_string']; 

//don't get playtime_string, but get playtime_seconds
$len = @$ThisFileInfo['playtime_seconds']*1000; //*1000 as calculate millisecond

J'espère que ceci vous aide.

1
Andi Kur