ByteScope

MP4 檔案格式

MPEG-4 Part 14,網路影音的標準 ISO-BMFF 容器。

MIME 類型
video/mp4
副檔名
.mp4
分類
影片

Magic number(檔案簽章)

0x0000000466747970ftypISO-BMFF 'ftyp' box
0x0000000869736F6Disoma major brand, e.g. 'isom'/'mp42'

關於 MP4 格式

MP4 是串流與下載影片最主流的封裝容器,通常裝的是 H.264、H.265 或 AV1 視訊搭配 AAC 音訊。它不是一串影格,而是一棵 box 樹,每個 box 都是一個大端序 32 位元大小加上四字元類型,而 ISO/IEC 14496-12 規定 FileTypeBox 必須排在第一個。這就是為什麼認得出來的 ASCII 'ftyp' 坐在位移 4 而不是位移 0:前面那四個位元組是它所引導的那個 box 的大小。播放器解碼需要的一切 — 軌列表、編碼參數、樣本表、時間戳 — 都住在 'moov' box 裡,壓縮後的樣本本身則住在一個或多個 'mdat' box 裡。格式本身沒有規定這兩者誰先誰後,而這個沒被限制的排序決定,正是大家用 MP4 時多數實務麻煩的源頭。

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

位移長度欄位意義
04ftyp box size整個 FileTypeBox 的位元組數,大端序,含這四個位元組本身。00 00 00 20 是 32 個位元組,足夠放一個主要品牌識別、一個次版本號和四個相容品牌識別。大小是 1 代表類型後面跟著 64 位元的 largesize;大小是 0 代表這個 box 一路延伸到檔案結尾。這兩個逃生口從來不會用在 ftyp 上。
44Box type 'ftyp'66 74 79 70。這才是每個 ISO base media 檔案真正的 magic number,而它刻意不在位移 0,因為這個格式裡每個 box 都把自己的長度擺在名字前面。
84Major brand四字元代碼,指名這個檔案宣稱遵循的規格:isom、iso2、iso5、iso6、mp41、mp42、avc1,分段串流則是 dash。MP4 跟 MOV、M4V、M4A、3GP、AVIF、HEIC 的分野就在這段位元組,因為它們前面那個 ftyp box 長得一模一樣。
124Minor version一個大端序 32 位元數字,純資訊用 — 規格明文說讀取端不得因為它而拒收檔案。ffmpeg 在 isom 品牌識別旁邊寫 00 00 02 00,而網路上極大比例的檔案帶著這個值,沒有什麼更好的理由。
16variableCompatible brands一串四字元的品牌識別,每個四個位元組,把 box 剩下的空間填滿。看不懂主要品牌識別的播放器,只要認得這裡任何一筆就可以繼續處理 — 一個 dash 分段或 avc1 檔案,能在只認得 isom 的解碼器裡打開,靠的就是這個。
328Second box headerftyp 之後那個 box 的大小與類型 — 'moov'、'mdat'、'free' 或 'wide'。ftyp box 是 32 個位元組時它就落在位移 32,這很常見但不是規則:請去讀位移 0 的大小,不要假設位置。

怎麼跟長得像的格式分開

容易搞混的怎麼分
QuickTime Movie前八個位元組一個不差,唯一分得開它們的是位移 8 的主要品牌識別:'qt ' 後面帶兩個空格、也就是 71 74 20 20,代表 QuickTime。還有第二種情況是純比對品牌識別會完全漏掉的 — 大約 2004 年以前寫出來的 QuickTime 檔案根本沒有 ftyp box,位移 4 直接就是 'moov'、'mdat'、'free'、'skip'、'wide' 或 'pnot'。
M4V同樣的 box、同樣的排版,位移 8 的品牌識別是 'M4V '(4D 34 56 20,注意尾隨的空格)。沒有保護的 M4V 各方面都就是 MP4,改個副檔名就行;播不了的那些是有 FairPlay 保護的,而那件事要在檔案更深處的加密樣本項目裡才看得到,不在標頭這裡。
3GP位移 8 的品牌識別是 3gp4、3gp5 或 3gp6 — 33 67 70 後面接一個數字。3GP 是同一個容器針對手機收斂出來的受限設定檔,所以它裡面每個 box 都是合法的 MP4,反過來卻不成立:一個裝著 H.265 或 AC-3 的 MP4 不是合法的 3GP 檔案,即使剖析器可以很順地走完它。
AVIF它一樣有 ftyp box,品牌識別是 'avif' 或 'avis',一樣塞滿了名字相同的 box — 但它是靜態影像,圖放在 'meta' box 裡而不是放在帶時間軸的軌上。HEIC 也是同一回事,品牌識別是 'heic'、'heix' 或 'mif1'。任何只憑 'ftyp' 下判斷的工具,都會很開心地把一張照片叫成影片。
WebM完全無關:WebM 和 Matroska 是 EBML 檔案,位移 0 就是 1A 45 DF A3。會混淆是副檔名害的、不是位元組害的,因為兩邊都裝得下 AV1 和 Opus、也都能在瀏覽器裡播,所以檔案就被人在兩種副檔名之間亂改,然後打不開。

常見的壞法

  • moov box 不見了。電池沒電當場中斷的錄影、或匯出到一半被砍掉的檔案,留下的是 mdat 裡每一格影像都在、索引卻從來沒寫出來的檔案 — 因為多數封裝器是在記憶體裡建 moov,最後才附加到檔尾。這種檔案很大,在 hex dump 裡明顯全是影片資料,卻完全播不出來;要救就得拿同一台裝置錄的另一個完好檔案,把樣本表重建出來。
  • moov box 在檔尾,而檔案是用串流方式送的。這裡其實什麼都沒壞,但透過 HTTP 抓檔的播放器必須下載到最後才能開始播,在慢速連線上看起來就跟壞檔一模一樣。把這個 box 搬到前面正是 faststart 旗標做的事,而它只是改寫位移,不會重新編碼任何東西。
  • 下載被截斷。因為 box 會先宣告自己的長度,剖析器走到最後一個完整的 box 之後,會碰到一個承諾的位元組數超過剩餘量的大小欄位。寫得好的讀取端會停下來、把手上有的播完;其他的則直接把檔案報成損壞,即使大部分內容都解得好好的。
  • box 大小在說謊。小於 8 的大小不可能存在,因為光是大小和類型欄位就佔 8 個位元組,但一個壞掉的位元組就能生出這種值 — 而天真的剖析器把大小加到游標上之後,會在同一個位移上永遠迴圈下去。當一個檔案不是讓工具報錯而是讓它卡死時,值得手動查一下這個。
  • 前面被塞了位元組。一頁被存成 .mp4 名字的 HTML 錯誤訊息,或是真正資料前面多出來的 BOM,都會把 'ftyp' 擠離位移 4。moov box 裡每一個 chunk 位移都是從檔案開頭量的,所以就算把垃圾認出來了,也必須真的把它刪掉、而不只是跳過去,檔案才播得動。

這個格式現在還在用嗎

網路上的影片,實際上就是 MP4。HLS 和 DASH 以分段形式送的是它,每支手機錄的是它,全世界每個瀏覽器和每顆硬體解碼器播的都是裝在它裡面的 H.264,每套剪輯軟體匯入的也是它。它的專利處境正是 WebM 存在的理由,而在開放網路上跑免權利金的 AV1 與 VP9 這件事上,WebM 確實搶到了實質的份額;Matroska 則拿下典藏用途,因為它處理多條字幕與音軌時麻煩少得多。讓 MP4 仍然是第一選擇的還是硬體:MP4 裡的一條 H.264 軌,在過去十五年做出來的幾乎每一支手機、每一台電視和每一台筆電上,都是由專用電路解的 — 對任何靠電池跑的裝置來說,這比壓縮率贏一點更值錢。它也是 Safari 和 iOS 唯一當成一等公民對待的容器,這一點對任何要把影片送給一般大眾的人來說,就已經把爭論結束掉了。

在這個站上打開 MP4 檔

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

相關格式

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

格式開頭位元組副檔名
QuickTime Movie66 74 79 70.mov
M4V66 74 79 70.m4v
M4A66 74 79 70.m4a
WebM1A 45 DF A3.webm
AVIF66 74 79 70.avif

常見問題

檔案的 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 仍然可能夾帶惡意內容。辨識真實類型是有用的第一道檢查,尤其在副檔名和位元組不一致的時候,但它不是惡意軟體掃描。

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