ByteScope

MP3 檔案格式

MPEG-1/2 Audio Layer III,最普及的有損音訊格式。

MIME 類型
audio/mpeg
副檔名
.mp3
分類
音訊

Magic number(檔案簽章)

0x00000000494433ID3'ID3' metadata tag

沒有標籤的 MP3 會直接以 MPEG 音框同步開頭:FF 後面接著高 3 位元皆為 1 的位元組。

關於 MP3 格式

MP3 是讓隨身數位音樂走入主流的格式,它用一套聽覺的知覺模型丟掉多數人聽不出來的部分,把音訊縮到原始大小的十分之一左右。它在任何實質意義上都不是容器:一個 MP3 檔案就是一串各自獨立的音框,每一框大約 26 毫秒,每一框都有自己四個位元組的標頭,寫明位元率、取樣率和聲道模式。檔案層級沒有長度、沒有索引、也沒有目錄,這就是為什麼 MP3 可以用文字編輯器在任何地方剪一刀之後照樣播得動。實務上幾乎每個檔案前面都掛著一個 ID3v2 標籤,裝著曲名、演出者和封面圖,而位移 0 那段認得出來的 ASCII,就是那個標籤提供的。

檔頭結構,一個位元組一個位元組看

位移長度欄位意義
03ID3v2 identifier49 44 33,ASCII 的 ID3 三個字母。這是硬掛在音訊前面的中介資料標籤,不是 MP3 格式本身的一部分,而一個完全合法的 MP3 可以根本沒有它 — 那種檔案一開頭就是音框標頭。
32ID3v2 version主版本號接修訂號:03 00 是 ID3v2.3,04 00 是 ID3v2.4,這兩個是實際在用的版本。修訂號那個位元組固定是 00,而且兩個位元組都不可以是 FF。
51ID3v2 flags位元 7 表示標籤做過去同步處理,位元 6 表示後面跟著一個延伸標頭,位元 5 標記它是實驗性的,位元 4 只在 2.4 版有意義,表示標籤結尾有一個十位元組的頁尾。多數檔案這些全部是 0。
64ID3v2 tag size一個 syncsafe 整數:四個位元組,每個的最高位元都被強制為零,各貢獻七個可用位元,總共 28 位元。這個值不含那十個位元組的標頭。忘了用 syncsafe 編碼的寫入端會產出一個過大的值,於是解碼器跳進音訊中間,開頭那零點幾秒就沒了。
10variableID3v2 frames標籤本體,長度就是位移 6 宣告的那麼多位元組。每個 frame 是一個四字元識別碼、一個大小和一組旗標:TIT2 是曲名、TPE1 是演出者、TALB 是專輯、TSSE 是編碼器、APIC 是封面圖。專輯封面經常讓這一段比它後面一分鐘的音訊還要大得多。
454First MPEG audio frame header音訊真正開始的地方 — 十個位元組的 ID3 標頭加上位移 6 所寫的長度。位移欄寫 45,是標籤剛好 35 個位元組時的結果,標籤一變它就跟著移動。音框標頭如果讀到 FF FB 40 C0:十一個同步位元全設,接著 MPEG 版本 1、Layer III、沒有 CRC;然後位元率索引 4 與取樣率索引 0,代表 44100 Hz 下的 56 kbps;最後聲道模式 3,單聲道。
664Xing or Info tag一個偽音框,帶著總音框數和一份 seek 表,坐在第一個音框裡標頭與 side information 之後 — MPEG-1 單聲道是 17 個位元組、MPEG-1 立體聲是 32,MPEG-2 則是 9 和 17 — 在這裡就落在音框內第 21 個位元組。變動位元率的檔案讀到 Xing,固定位元率讀到 Info,而它不存在,正是某些播放器報出離譜長度的原因。
-128128ID3v1 tag最早的中介資料格式,是檔案最尾端固定 128 個位元組的區塊,開頭是 ASCII 的 TAG 三個字母,54 41 47。曲名、演出者、專輯各三十個位元組,年份四個,註解三十個,曲風編號一個。為了相容至今仍會被寫出來,而不認得它的解碼器會把它播成一小段雜訊。

怎麼跟長得像的格式分開

容易搞混的怎麼分
ADTS AAC這是所有「只檢查音框同步」的做法的陷阱。裸的 .aac 檔案開頭是 FF F1 或 FF F9,跟 MP3 音框一樣通得過十一位元的同步測試。分開它們的是那兩個 layer 位元,也就是第二個位元組的位元 2 與位元 1:MP3 的 Layer III 是 01,而 ADTS 讓它們維持 00,那是 MPEG-1 音訊保留、從不使用的值。要避開它,就得檢查完整的音框標頭,而不是只看同步。
MP2/MP1音框結構完全相同,同步一樣是 FF Ex,差別只在同樣那兩個 layer 位元 — Layer II 是 10,Layer I 是 11。MP2 至今仍在廣播領域使用,所以檔案真的會出現,而一個看到 MPEG 音訊同步就假設是 Layer III 的播放器,不會拒收,只會解出雜訊。
FLAC在 hex 編輯器裡不可能混淆,因為 FLAC 開頭是看得懂的 ASCII fLaC,但實務上天天在混淆,因為兩個副檔名描述的是同一張專輯。這裡有一個方向確實存在位元組層級的危害:某些馬虎的標籤軟體會把 ID3v2 標籤寫到 FLAC 檔案前面,而 FLAC 規格並不允許這件事,於是對任何看到 49 44 33 就停手的偵測器來說,結果看起來就是一個 MP3。
WAV一個 RIFF WAV 檔案裝的可以是 MP3 資料而不是 PCM,由它 'fmt ' chunk 裡的格式標籤 0x0055 宣告。這種檔案開頭是 52 49 46 46,在每一項結構測試下都是 WAV,而裡面的位元組是不折不扣的 MP3 音框。把它改名成 .mp3 並不會把 RIFF 標頭拿掉,於是多數解碼器會在最前面那四十來個位元組上絆倒。

常見的壞法

  • 標籤和第一個音框之間有垃圾。下載到一半、ID3 大小寫錯,或多出來的一塊封面圖,都會讓本該是音框標頭的地方變成別的東西。解碼器的做法是往前掃描下一個 FF Ex 樣式來重新同步,所以音訊還是播得出來 — 只是前面多一聲喀,而且長度是從錯誤的起點算出來的。
  • 變動位元率的檔案沒有 Xing 標頭。少了那個偽音框裡的總音框數,播放器只能拿它看到的第一個音框的位元率去推長度,而那在 VBR 檔案上就是錯的。症狀是一首標著三分鐘的曲子播了五分鐘,而且每次 seek 都跳到錯的位置。
  • 截斷。因為這個格式裡任何地方都沒有檔案層級的長度,被截斷的 MP3 跟一首本來就比較短的曲子分不出來:它會乾淨地播到切口然後停下,完全不報錯。唯一的線索是 Xing 標頭裡的音框數(如果有的話),以及最後一個音框在它宣告的長度之前就結束了。
  • ID3v1 標籤被當成音訊解。檔案尾端那個 128 位元組的區塊以 TAG 開頭、而且不是音框,所以一路走音框走到檔尾、又不檢查它的解碼器,就會吐出一小段雜訊。用比較舊的軟體抓的曲子,結尾那聲經典的喀,就是它。
  • ID3v2 的大小欄位不是 syncsafe。有些寫入端在位移 6 放的是普通的大端序整數,而因為那樣每個位元組都可以超過 127,讀出來的值就比真正的標籤大。解碼器跳過頭、落進音訊裡,開頭那零點幾秒就不見了 — 這是標籤軟體的 bug,音訊本身完全沒事。

這個格式現在還在用嗎

MP3 在技術上已經過時,在實務上卻躲不掉。同樣位元率下 AAC 比它好,而串流服務和每支手機錄音實際用的都是 AAC;64 kbps 以下 Opus 比兩者都好,語音和即時音訊跑的是它。這些都沒有把 MP3 擠掉,因為它最後一批專利在 2017 年到期,如今它享有一件繼任者都沒有的事:過去二十五年做出來的每一台裝置都播得動它,不用授權、不用協商、也不用 fallback。這讓它成為 podcast、有聲書、任何用下載而非串流取得的東西,以及車用音響和那些永遠不會收到韌體更新的便宜硬體播放器的預設。凡是你打算再編輯或重新編碼的東西,它都是錯的選擇,因為每過一次編碼器就再掉一些;而要典藏,正確答案是留無損格式,需要時再從那裡生 MP3。

在這個站上打開 MP3 檔

這些全部在你的瀏覽器裡跑,檔案不會離開你的電腦。

相關格式

容易和 MP3 搞混的格式,可以比對它們的開頭位元組。

格式開頭位元組副檔名
FLAC66 4C 61 43.flac
M4A66 74 79 70.m4a
Ogg4F 67 67 53.ogg
WAV52 49 46 46.wav

常見問題

檔案的 magic number 是什麼?

檔案開頭的前幾個位元組,不管檔名寫什麼,它標明的是真正的格式。PNG 一定以 89 50 4E 47 開頭,ZIP 則是 50 4B 03 04。作業系統、瀏覽器和 file 指令讀的都是這幾個位元組,而不是相信副檔名 — 這就是為什麼把檔案改名並不會改變它實際上是什麼。

我要怎麼自己檢查 magic number?

在 macOS 或 Linux 上,xxd -l 16 檔名 會印出前 16 個位元組;在 Windows 上,PowerShell 的 Format-Hex -Path 檔名 -Count 16。或者把檔案丟進本站的檔案類型辨識工具,它會在本機讀取位元組並告訴你是什麼格式,不會上傳任何東西。

為什麼兩種格式的 magic number 會一樣?

因為其中一種是建立在另一種之上。docx、xlsx、pptx、apk、jar 與 epub 骨子裡都是 ZIP 壓縮檔,所以全都以 ZIP 的簽章開頭;要分辨它們得看裡面的項目。Java class 檔和 macOS 的通用二進位檔都以 CA FE BA BE 開頭,靠緊接其後的欄位區分。

有完全沒有 magic number 的檔案嗎?

有。XML、HTML、JSON、SVG、CSV 這類以文字為基礎的格式沒有固定的位元組簽章,所以改用結構來辨識:開頭的 <?xml 宣告、<svg 元素,或是 { 後面接著帶引號的鍵。這種偵測是合理推測而非確定,因此本參考頁會把這些格式標示為結構偵測。

magic number 相符就代表檔案安全嗎?

不代表。它告訴你的是格式,不是內容是否無害 — 一個貨真價實的 PDF 或 docx 仍然可能夾帶惡意內容。辨識真實類型是有用的第一道檢查,尤其在副檔名和位元組不一致的時候,但它不是惡意軟體掃描。

手上有檔案可能是 MP3?用檔案類型辨識工具查出來 — 它在本機讀取 magic number,不上傳任何東西。或者瀏覽所有格式。