轉碼 Media Source Extensions™ 資源

在使用 Media Source Extensions 時,很可能需要對資源進行條件處理,然後才能進行流式傳輸。本文將介紹相關要求,並展示一個可用於適當編碼資源的工具鏈。

入門

  1. 第一步也是最重要的一步是確保您的檔案包含使用者瀏覽器支援的容器和編解碼器。
  2. 根據編解碼器的不同,您可能需要對檔案進行分段,以符合 ISO BMFF 規範
  3. (可選) 如果您決定使用 HTTP 上的動態自適應流 (DASH) 進行自適應位元率流式傳輸,則需要將資源轉碼為多種解析度。大多數 DASH 客戶端都期望有一個對應的 Media Presentation Description (MPD) 清單檔案,該檔案通常在生成多種解析度的資原始檔時生成。

下面我們將介紹所有這些步驟,但首先讓我們看看一個可以輕鬆完成此操作的工具鏈。

示例媒體

如果您想按照此處列出的步驟進行操作,但沒有媒體可以進行實驗,可以下載 《大朋兔》預告片。大朋兔由 Blender Foundation 擁有版權,並根據 知識共享署名 3.0 許可授權。在本教程中,您將看到檔名 trailer_1080p.mov,這就是下載的檔案。

所需工具

在使用 MSE 時,以下工具是必備的

  1. ffmpeg — 一個命令列工具,用於將媒體轉碼為所需格式。您可以在 下載 FFmpeg 頁面 下載適用於您系統的版本。從存檔檔案中提取可執行檔案,並將其位置新增到您的 PATH 語句中。macOS 使用者也可以使用 homebrew 安裝 ffmpeg。
  2. Bento4 — 一套用於獲取資源元資料和建立 DASH 內容的命令列工具。要安裝,您需要根據您的作業系統和偏好,從提供的專案檔案/原始檔自行構建/編譯應用程式。有關更多詳細資訊,請參閱 構建說明,或下載 預編譯檔案。將 bin 目錄的內容放在與 ffmpeg 相同的位置。
  3. python2 — Bento4 使用它。

在進入下一步之前,請確保成功安裝了這些工具。

示例媒體應放置在 Bento4 的 utils 目錄中,並在該目錄中進行操作。

注意: 由於許可原因,預編譯的 ffmpeg 不包含 libfdk_aac。Bento4 預設使用它,因此您可能需要編譯 ffmpeg。如果您不需要它,請在 mp4-dash-encode.py 命令後面加上 --audio-codec=aac

容器和編解碼器支援

MSE 規範第 1.1 節:目標中所述,MSE 的設計不要求支援任何特定的媒體格式或編解碼器。雖然理論上如此,但瀏覽器對特定容器/編解碼器組合的支援各不相同。

要檢查瀏覽器是否支援特定容器,可以將 MIME 型別字串傳遞給 MediaSource.isTypeSupported() 方法。

js
MediaSource.isTypeSupported("audio/mp3"); // false
MediaSource.isTypeSupported("video/mp4"); // true
MediaSource.isTypeSupported('video/mp4; codecs="avc1.4D4028, mp4a.40.2"'); // true

該字串是容器的 MIME 型別,後面可以選擇跟著編解碼器列表。雖然 MIME 型別相對容易弄清楚,但我們可以使用 mp4info 工具來獲取編解碼器字串。

目前,具有 H.264 影片和 AAC 音訊編解碼器的 MP4 容器在所有現代瀏覽器中都得到支援,而其他容器則不支援。

要將我們的示例媒體從 QuickTime MOV 容器轉換為 MP4 容器,我們可以使用 ffmpeg。因為 MOV 容器中的音訊編解碼器已經是 AAC,影片編解碼器是 h.264,所以我們可以指示 ffmpeg 不進行轉碼。相反,它只會複製音訊和影片軌道,而不會執行任何轉碼,這比轉碼要快得多。

bash
ffmpeg -i trailer_1080p.mov -c:v copy -c:a copy bunny.mp4

檢查分段

為了正確地流式傳輸 MP4,我們需要資源是 ISO BMF 格式的 MP4。沒有適當的分段,任何給定的 MP4 檔案都不能保證與 MSE 一起正常工作。這意味著容器內的元資料是分散的,而不是聚集在一起的。

要檢查 MP4 檔案是否是正確的 MP4 流,您可以再次使用 mp4info 工具來列出 MP4 的原子。

注意: 分段後的版本比原始版本稍大,因為在檔案中分佈了額外的元資料。這通常只會增加 1% 或更少的空間。

分段

如果您有一個不是 MP4 的資源,ffmpeg 可以透過 -movflags frag_keyframe+empty_moov 命令列標誌在轉碼過程中生成一個正確分段的 MP4。

bash
ffmpeg -i trailer_1080p.mov -c:v copy -c:a copy -movflags frag_keyframe+empty_moov bunny_fragmented.mp4

如果您已經有一個 MP4,但未正確分段,您可以再次使用 ffmpeg。

bash
ffmpeg -i non_fragmented.mp4 -movflags frag_keyframe+empty_moov fragmented.mp4

在兩種情況下,Chrome 可能需要設定額外的 movie 標誌。

bash
-movflags frag_keyframe+empty_moov+default_base_moof

擁有一個正確分段的 MP4 檔案是入門所需的一切。如果您想採用自適應位元率流式傳輸,則必須建立多種解析度的編碼。雖然 MSE 足夠靈活,可以允許您進行實現,但強烈建議使用現有的 DASH 客戶端,因為 DASH 是一個規範完善的應用程式協議。

為 DASH 建立內容

假設您可以透過 $PATH 訪問 ffmpeg 和 Bento4 的實用程式,您可以執行 Bento4 的 mp4-dash-encode.py Python 指令碼來生成您內容的多種解析度的編碼。然後,您可以使用 Bento4 的 mp4-dash.py Python 指令碼來生成客戶端所需的相應 MPD 檔案。

執行以下命令

bash
python mp4-dash-encode.py -b 5 -v bunny_fragmented.mp4
python mp4-dash.py video_0*

這應該會輸出以下檔案

output
├── audio
│   └── und
├── stream.mpd
└── video
    ├── 1
    ├── 2
    ├── 3
    ├── 4
    └── 5

注意: mp4-dash-encode.py 不會顯示 ffmpeg 的錯誤訊息。您可以透過指定 -d 選項來檢視它。

注意: 如果顯示錯誤訊息 "Invalid duration specification for force_key_frames: 'expr:eq(mod(n'",請修改 mp4-dash-encode.py 並從 "-force_key_frames 'expr:eq(mod(n,%d),0)'" 中刪除兩個 "'"

總結

在影片正確編碼並生成自適應位元率媒體後,您現在就可以使用 DASH 和 MSE 在 Web 上開始自適應位元率流式傳輸了。