web-dev-qa-db-ja.com

PHP MP3持続時間を取得する関数

MP3の持続時間を提供するPHP関数があります。ID3の関数を調べましたが、持続時間については何も表示されず、id3は何らかのタグです、これはすべてのMP3には存在しないため、これを使用しても意味がありません。

25
ram

Getduration関数に注意してください: http://www.zedwood.com/article/127/php-calculate-duration-of-mp

30
Richard Askew

Getid3をインストールしますが、期間のみが必要な場合は、これらのモジュールを除くすべてを削除できます。

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

次のようなコードで期間にアクセスします。

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

Sourceforge で入手してください

26
TecBrat

私は非常に多くの時間を過ごしましたが、getID3なしで( http://getid3.sourceforge.net/ )オーディオファイルの持続時間を取得することは不可能です。

1)以下のリンクを使用して、getID3のライブラリを最初にダウンロードします。

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

2)以下のコードを試してください:

    <?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);
    ?>
8
Mohin Mathakia

Ffmpegを使用して、mp3または他の多くのオーディオ/ビデオファイルの長さを取得できます。

  1. サーバーにffmpegをインストールします。
  2. Php Shell_execが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
<?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

これを行うためのネイティブphp関数はありません。

サーバー環境によっては、 MP3Info などのツールを使用できます。

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

MP3はフレームに「分割」されるように設計されており、それらのフレームは再生可能なままであるため、MP3の長さは(「プレーン」MP3形式で)どこにも保存されません。

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

依存するIDタグがない場合は、MP3ファイル全体を読み取り、それぞれの継続時間を合計する必要があります(ツールとPHPこれを行うクラスがあります)フレーム。

1
LSerni

以前のように、mp[〜#〜] wav [〜#〜]の両方のファイルのソリューションを提供しましたが、このソリューションは特に[〜#〜] wav [〜#〜]より多くの精度であるが、以前のソリューションよりも長い評価時間のファイル。

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);

最後に、私は自分の計算でソリューションを開発しました。このソリューションは、mp3および[〜#〜] wav [〜#〜]ファイル形式に最適です。ただし、わずかな精度のばらつきが予想されます。解決策は[〜#〜] php [〜#〜]にあります。 [〜#〜] 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);
$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

これがあなたのお役に立てば幸いです。

1
Andi Kur

FFMpegがインストールされている場合、FFProbeを使用して期間を取得するのは非常に簡単です。

$filepath = 'example.mp3';
$ffprobe = \FFMpeg\FFProbe::create();
$duration = $ffprobe->format($filepath)->get('duration');

echo gmdate('H:i:s', $duration);
0
user1214684