首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 解析 MP3 ID3 標籤與 MPEG 資訊:MP3 類別完整實作

     編輯:PHP 相關知識

音訊中繼資料提取:ID3v1/v2.2/v2.3/v2.4 + MPEG 框架解析

MP3 檔案包含 MPEG 音訊框架 (標頭、側資料、主資料) 與選用的 ID3 標籤 (v1 在檔尾 128 bytes,v2 在檔頭)。本類別提供統一介面提取標題、藝術家、專輯、年份、流派、封面圖片、比特率、取樣率、長度等資訊。

類別架構與核心方法

<?php
class MP3 {
    private $filePath;
    private $fileHandle;
    private $fileSize;
    private $info = [];      // MPEG 框架資訊
    private $id3v1 = [];     // ID3v1 標籤
    private $id3v2 = [];     // ID3v2 標籤 (支援 2.2/2.3/2.4)
    private $id3v2Offset = 0;

    public function __construct($filePath) {
        $this->filePath = $filePath;
        $this->fileSize = filesize($filePath);
        $this->fileHandle = fopen($filePath, 'rb');
        if (!$this->fileHandle) throw new Exception("無法開啟檔案: $filePath");
    }

    public function __destruct() {
        if ($this->fileHandle) fclose($this->fileHandle);
    }

    // 公開介面
    public function getInfo() {
        if (empty($this->info)) $this->parseMpeg();
        return $this->info;
    }

    public function getID3() {
        if (empty($this->id3v1) && empty($this->id3v2)) $this->parseID3();
        return array_merge($this->id3v1, $this->id3v2); // v2 優先覆蓋 v1
    }

    // 內部解析方法...
    private function parseMpeg() { /* 掃描框架同步字 0xFFE/0xFFF,解析標頭 */ }
    private function parseID3() {
        $this->parseID3v2(); // 檔頭
        $this->parseID3v1(); // 檔尾
    }
    private function parseID3v1() { /* 讀取最後 128 bytes,標記 "TAG" */ }
    private function parseID3v2() {
        // 檢查 "ID3" 標識,解析版本、旗標、大小 (synchsafe int)
        // 迴圈讀取框架: TIT2 (標題), TPE1 (藝術家), TALB (專輯), TYER (年份), TCON (流派), APIC (封面), 等
        // 支援 UTF-16 (BOM), UTF-8, ISO-8859-1 編碼
    }
    private function readSynchsafeInt($bytes) { /* 7位元編碼整數 */ }
    private function readFrame($maxOffset) { /* 解析單一 ID3v2 框架 */ }
}

// 使用範例
$mp3 = new MP3('song.mp3');
$info = $mp3->getInfo();
$id3 = $mp3->getID3();

echo "標題: {$id3['title']}\n";
echo "藝術家: {$id3['artist']}\n";
echo "專輯: {$id3['album']}\n";
echo "比特率: {$info['bitrate']} kbps\n";
echo "取樣率: {$info['sample_rate']} Hz\n";
echo "長度: {$info['playtime_string']}\n";
if (!empty($id3['cover'])) {
    file_put_contents('cover.jpg', $id3['cover']);
    echo "封面已擷取: cover.jpg\n";
}
?>

關鍵解析細節

項目規格來源解析重點
MPEG 框架同步ISO/IEC 11172-3尋找 0xFFF (11 bits) 或 0xFFE,解析版本、層、比特率索引、取樣率索引、填充、模式
比特率計算MPEG-1 Layer III 表查表獲取 kbps,VBR 需掃描多框架平均或讀取 Xing/Info 標頭
ID3v1非官方標準檔尾 128 bytes: "TAG" + 30字標題 + 30字藝術家 + 30字專輯 + 4字年份 + 30字備註 + 1字流派
ID3v2 大小id3.orgSynchsafe integer: 4 bytes, 每 byte 最高位為 0, 實際 28 bits
ID3v2 框架ID3v2.3.0 / 2.4.0Frame ID (4 chars) + Size (4 bytes) + Flags (2 bytes) + Data
文字編碼ID3v2.3/2.4第一 byte: 0=ISO-8859-1, 1=UTF-16 (BOM), 2=UTF-16BE, 3=UTF-8
封面圖片 (APIC)ID3v2MIME 類型 + 圖片類型 + 描述 + 圖片二進位資料

VBR (可變比特率) 處理

  • 檢測 Xing 標頭 (框架側資料後) 或 LAME 標頭,讀取總框架數、總位元組數、TOC (尋找表)。
  • 平均比特率 = 總位元組數 * 8 / (總框架數 * 每框架樣本數 / 取樣率)。
  • 無 Xing 標頭時需完整掃描所有框架累加大小 (慢),或估算。

現代替代方案

方案優點缺點
getID3() 庫功能最完整、支援超多格式、活躍維護體積大 (~2MB)、純 PHP 效能一般
ffprobe (FFmpeg)極快、準確、支援所有編碼器、可提取波形圖需安裝 FFmpeg、執行外部程序、安全性考量
PHP-FFMpeg物件導向封裝 ffprobe/ffmpeg依賴外部二進制檔
Node.js music-metadata快速、原生非同步、TypeScript 支援需 Node 環境

效能與安全建議

  1. 僅讀取必要範圍:ID3v2 在檔頭,讀取前 128KB 通常足夠;MPEG 掃描前幾個框架即可估算。
  2. 大檔案避免完整讀入記憶體:使用 fseek/fread 逐塊處理。
  3. 上傳驗證:解析前驗證 MIME (audio/mpeg)、副檔名、檔案大小限制。
  4. 暫存檔清理:處理完成立即 unlink 上傳暫存檔。

MP3 中繼資料解析涉及複雜的二進位格式與多版本相容,生產環境強烈建議使用成熟庫 (getID3) 或外部工具 (ffprobe),自行實作僅適合教學或極簡需求。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved