ByteScope

3GP 檔案格式

3GPP 多媒體容器,為手機而設計。

MIME 類型
video/3gpp
副檔名
.3gp
分類
影片

Magic number(檔案簽章)

0x0000000466747970ftypISO-BMFF 'ftyp' box
0x00000008336770343gp4brand '3gp4' (or '3gp5')

關於 3GP 格式

3GP 是 3rd Generation Partnership Project 為手機定義的多媒體容器,規範在 3GPP TS 26.244,本質上是 ISO base media file format 的一個受限設定檔。結構上它就是 MP4:同樣的 box、同樣的大端序大小、開頭同樣是 FileTypeBox。規格加上去的東西是限制 — 一份很短的允許編碼清單,視訊主要是 H.263、MPEG-4 Part 2,後期還有 H.264,音訊則是 AMR-NB、AMR-WB 或 AAC — 這些選擇的前提是:一支只有幾 MB 記憶體、硬體幾乎等於沒有的手機,也錄得起來、播得出來。檔案很小,解析度以現在的標準來說小得可憐,而這個格式主要活在舊的相機膠捲和功能手機錄下來的語音裡。

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

位移長度欄位意義
04ftyp box sizeFileTypeBox 的長度,大端序,含這四個位元組。00 00 00 20 是 32,放得下一個主要品牌識別、一個次版本號和三個相容品牌識別。這個值是找到後面那個 box 的唯一可靠方式。
44Box type 'ftyp'66 74 79 70,規定必須是檔案裡的第一個 box。每個 ISO base media 的衍生格式都把它放在這裡,所以它的存在只能把檔案縮小到那個家族,再多就沒有了。
84Major brand33 67 70 後面接一個 ASCII 數字:'3gp4'、'3gp5'、'3gp6' 以及更後面的版本,各自對應 TS 26.244 的一個版次。那個數字是這個檔案最接近「裡面該預期哪些編碼」的一句宣告。
124Minor version一個大端序 32 位元值,帶著寫入端瞄準的規格版次。ffmpeg 產出的 3gp6 檔案這裡是 00 00 01 00。跟這個家族裡每個次版本號一樣,它是資訊性的,因為它的值而拒收檔案就是 bug。
16variableCompatible brands每個品牌識別四個位元組,一路填到 box 結束,通常是主要品牌識別重複一次之後接 isom、iso2 和 avc1。這裡列著 isom,等於檔案在說「一般的 MP4 讀取端應付得來」— 而這件事成立的頻率,遠高於那個獨立副檔名讓人以為的程度。
328Second box headerftyp 之後那個 box 的大小與類型 — 'moov'、'mdat' 或一個 'free' 佔位 box。ftyp 是 32 個位元組時這個位移才成立,否則它會跟著相容品牌識別清單的長度移動。

怎麼跟長得像的格式分開

容易搞混的怎麼分
MP4位移 8 的品牌識別就是全部的判別法:是 3gp4、3gp5 或 3gp6,而不是 isom 或 mp42。每個 3GP 檔案都是合法的 MP4,在 MP4 讀取端裡都播得動,反過來則不成立 — 一個裝著 H.265、VP9 或 AC-3 的 MP4 違反了 3GPP 的編碼限制,即使它的 box 剖析起來毫無怨言。
3G23GPP2 為 CDMA 網路定義了一個幾乎相同的容器,區別只在位移 8 的品牌識別 '3g2a' 或 '3g2b',以及 .3g2 這個副檔名。它主要多加的是 QCELP 和 EVRC 語音編碼的支援,而那個生態系之外沒有東西解得開;檔案其他部分的排版完全一樣。
AMR3GP 常常被跟它通常裝著的那種原始語音格式搞混。裸的 AMR 檔案根本不是容器:它開頭是一行 ASCII 標頭 23 21 41 4D 52 0A,也就是 '#!AMR' 加一個換行,後面直接是原始語音影格。在 3GP 裡,同樣的音訊是一條正經的軌,樣本項目是 'samr',而檔案裡任何地方都不會有那行標頭。
M4A位移 8 的品牌識別是 'M4A ',box 樹則相同。純音訊的 3GP 檔案是存在的、而且很常見 — 老手機的一段語音備忘錄就是 — 所以副檔名不會告訴你裡面有沒有影片。每條軌裡的 'hdlr' handler 類型才會:'vide' 是畫面、'soun' 是聲音。

常見的壞法

  • 錄到一半被沒電的電池切斷。手機是把樣本寫進 mdat、錄影停止時才附加 moov 索引的,所以拍到一半關機的手機,留下的檔案音訊和視訊全都在、卻沒有辦法播。要救就得從同一支手機、同樣設定錄的另一段影片,把樣本表結構移植過來。
  • 編碼已經解不開了。很多 3GP 檔案裝的是 H.263 視訊和 AMR-NB 語音,而現代播放器悄悄把這兩者都拿掉了。檔案完好無缺、box 走得乾乾淨淨,播放卻照樣失敗 — 看起來像損壞,其實是編碼可用性的問題,解法是轉檔而不是修復。
  • 從手機傳出來的過程中被截斷。因為標頭住在前三十二個位元組裡,它永遠活得下來,所以一個內容掉了大半的檔案,檔案類型偵測還是很開心地報 3GP。把 box 的大小走一遍才會露餡:最後一個 box 承諾的位元組數比實際存在的多。
  • 品牌識別在重新封裝時掉了。用一個會重寫 FileTypeBox 的工具複製串流,位移 8 那幾個位元組就變成 isom。媒體本身什麼都沒變、播起來也跟之前一模一樣,但任何看 3GP 品牌識別做事的東西,現在看到的是另一種格式。
  • 標頭前面有垃圾。一個下載到一半、前面還存著 HTML 錯誤頁的檔案,會把 'ftyp' 擠離位移 4。moov box 裡的 chunk 位移全部是從檔案開頭量的,所以那幾個開頭的位元組必須真的刪掉,不能只是跳過去。

這個格式現在還在用嗎

3GP 有一個很具體的任務 — 大約 2002 到 2010 年間手機上的影音訊息與相機錄影 — 而當手機好到可以直接用 H.264 錄進 MP4 時,那個任務就不存在了。現在沒有任何新東西是用這個格式產出的。它還會出現的地方是檔案庫:舊的 MMS 附件、功能手機的相機膠捲、語音備忘錄,還有那些便宜到在手機早就換代之後仍然沿用舊編碼晶片的監視器或行車記錄器。碰到這些,正確的動作是轉檔一次,轉成 H.264 加 AAC 的 MP4,因為問題不在容器 — 問題在 H.263 和 AMR-NB,而且每年都有更少的播放器還內建它們的解碼器。3GP 真正保留下來的優勢只有一個:小。一段 AMR-NB 語音錄音每秒只有幾 KB,遠遠低於任何通用編碼做得到的數字。

在這個站上打開 3GP 檔

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

相關格式

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

格式開頭位元組副檔名
MP466 74 79 70.mp4
M4A66 74 79 70.m4a

常見問題

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

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