透過 FFmpeg 導入字幕

在現今的數位媒體社會中,字幕的重要性與日俱增,尤其反映在非母語使用者的需求上。並且隨著語音轉文字等技術的突破性進展與廣泛應用,字幕的製作過程已經變得更加便捷和高效,使得更多的內容創作者能夠輕鬆地為其作品添加字幕,大幅避免口音造成的誤解。接下來,讓我們一起深入探討如何運用 FFmpeg 這個強大的工具來進行字幕的套用。

素材取用

影片:雲端下載 <影片來源 – Bad Apple by あにら | ニコニコ >
字幕組合包:雲端下載 (新增 英文、日英 兩種字幕)

實作過程

認識字幕檔

在開始導入字幕之前,讓我們先簡單認識一下常見的幾種檔案類型。

SRT (Sub-Rip)

其屬於最基本且容易理解的字幕格式,每個片段都由三個基本元素所構成:索引號碼時間區間文字內容。這種格式因其簡單直觀的特性,已經成為目前影片字幕領域中最廣泛使用且最受歡迎的格式之一,然而其文字特效只能從撥放器統一調整。

1
00:00:29,082 --> 00:00:32,449
流れてく 時の中ででも

2
00:00:32,449 --> 00:00:36,006
気だるさが ほらグルグル廻って
SAA (SubStation Alpha)

但這時問題來了,SRT 本身不具帶文字的樣式設定,所以每個人開啟的樣態要嘛最預設的黑框白字,要嘛自己習慣的字體,不一定適配影片的內容。於是乎這個格式把樣式也寫入,確保每個人看到的都是統一樣式。但是並不普及與廣泛支援。

我們透過 FFmpeg 轉檔後成功得到下列內容,可以發現其主要分有三個區塊:腳本資訊文字樣式字幕主體,並多數採用逗號分隔的方式。而文字的部分事實上還能進階,加上一些特效控制文字顯現與消失的方式。

[Script Info]
; Script generated by FFmpeg/Lavc61.19.100
ScriptType: v4.00+
PlayResX: 384
PlayResY: 288
ScaledBorderAndShadow: yes
YCbCr Matrix: None

[V4+ Styles]
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
Style: Default,Arial,16,&Hffffff,&Hffffff,&H0,&H0,0,0,0,0,100,100,0,0,1,1,0,2,10,10,10,1

[Events]
Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
Dialogue: 0,0:00:29.08,0:00:32.45,Default,,0,0,0,,流れてく 時の中ででも
Dialogue: 0,0:00:32.45,0:00:36.01,Default,,0,0,0,,気だるさが ほらグルグル廻って
ASS (Advanced SubStation Alpha)

進行了多項功能性的擴展和改進。這些擴展包括了更靈活的文字排版控制,以及針對音樂影片特別優化的卡拉OK模式功能。

硬字幕 Hard Subs

所謂的硬字幕,是通過影片重新編碼的過程,將字幕文字永久性地覆蓋在原始畫面上。由於字幕已經成為視頻畫面的一部分,一旦製作完成後就無法更改或移除,觀眾也無法根據個人喜好來調整樣式,可以說是較為死板的字幕呈現方式。

至於為何會有如此的需求?並非每個使用者都具備導入外部字幕檔的技術知識,也不是每個播放軟體都支援字幕檔的匯入功能。甚至有些人偷懶,而選擇避開手動開啟字幕的麻煩。而我們在之前比較 Input 與 Output Seeking 時,其實就已經用過這樣的技巧。

雖然在市場上的應用頻率相對較低,但為了完整示範不同字幕格式的使用方法,這裡特別需要提醒一下。當處理 .ass 格式的字幕檔案時,在指令中需要使用 ass= 參數來進行呼叫,這與一般字幕檔使用的 subtitles= 參數有所不同。

hardcoded_srt.bat
ffmpeg -i ./test.mp4 -vf subtitles=test.srt ./test_hardcoded_srt.mp4

毫無疑問地說,字幕已經成功地燒錄到影片當中。但在實際觀看的過程中,特別是像我們這種黑白影片的情況下,經常會遇到一個視覺效果的問題,就是字幕顏色的衝突。關於這個部分,我們則能在燒入的過程中強制設計輸出樣式。

hardcoded_srt_stylized.bat
ffmpeg -i ./test.mp4 -vf "subtitles=test.srt:force_style='Fontname=Arial,Fontsize=24,PrimaryColour=&H00FF21&,BackColour=&H000000&,Bold=1,Italic=1,Alignment=2,BorderStyle=3,Outline=2,Shadow=1,MarginV=30'" ./test_hardcoded_srt_stylized.mp4
ffmpeg-subs-default
ffmpeg-subs-stylized

軟字幕 Soft Subs

相對於硬字幕,軟字幕提供了更高的靈活性和客製化選項。使用者不僅可以自由選擇是否要顯示字幕,還能根據個人喜好和需求來調整字幕的大小、顏色、字型等樣式特徵。這種字幕格式的優勢在於它完全獨立於視頻畫面之外,可以透過不同的播放工具進行各種調整和修改,為觀眾提供更加個人化的觀看體驗。

單軌

這類字幕實際上是以獨立的數據形式保存在影片的軌道資訊中,由於字幕數據被獨立儲存,系統能夠輕易地實現字幕的顯示與隱藏,同時也讓使用者能夠在不同的字幕軌道之間自由切換,為觀看體驗提供更大的彈性。

softcoded_srt.bat
ffmpeg -i ./test.mp4 -i ./test.srt -c copy -c:s mov_text -metadata:s:s:0 language=jpn test_softcoded_srt.mp4

如果你同樣用上 VSCode 來管理 .bat 檔案,此時順道撥放輸出的影片可能就會考慮,「為啥沒有字幕?」就像我們剛剛介紹的,一些簡易撥放器並不支援。例圖則是 Pot Player 的畫面截圖,各位可能看不是很清楚,但在字幕的選擇會有 Default 的預設字幕被系統選擇。

ffmpeg-subs-track_selecting

接著讓我們來探討影片資訊的部分,將會出現一個新的軌道,那就是日語字幕的軌道。這個額外的字幕軌道也為觀眾提供了更佳的觀看體驗,並且也能自訂義調整與開關。

Stream #0:0[0x1](und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p(tv, bt709, progressive), 480x360 [SAR 1:1 DAR 4:3], 134 kb/s, 30 fps, 30 tbr, 15360 tbn (default)
      Metadata:
        handler_name    : ISO Media file produced by Google Inc.
        vendor_id       : [0][0][0][0]
  Stream #0:1[0x2](und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 127 kb/s (default)
      Metadata:
        handler_name    : ISO Media file produced by Google Inc.
        vendor_id       : [0][0][0][0]
  Stream #0:2[0x3](jpn): Subtitle: mov_text (tx3g / 0x67337874), 0 kb/s (default)
      Metadata:
        handler_name    : SubtitleHandler
多軌

但一部熱銷全球的影片,則通常需要給予各式各樣的語言選擇。那我們又該如何達成多個字幕軌道?很明顯 -map 的導入方式再度登場!但這次我們需要 -metadata 先讀取資訊流 (:s) 接著輸出成字幕 (:s) 在第幾軌道 (:數字)。

softcoded_srt_multichannel.bat
ffmpeg -i ./test.mp4 -i ./test.srt -i ./test_eng.srt -map 0 -map 1 -map 2 -c copy -c:s mov_text -metadata:s:s:0 language=jpn -metadata:s:s:1 language=eng test_softcoded_multichannel.mp4

而在與先前的單軌模式做一個比較,可以發現現在多出英文版的字幕軌道。但值得注意的是,系統只會視第一個字幕軌道為預設值,這是為了確保觀眾在播放時能看到作者所選用的字幕內容。這種設計既保持了觀看的便利性,也不影響其他字幕軌道的切換與使用。

  Stream #0:2[0x3](jpn): Subtitle: mov_text (tx3g / 0x67337874), 0 kb/s (default)
      Metadata:
        handler_name    : SubtitleHandler
  Stream #0:3[0x4](eng): Subtitle: mov_text (tx3g / 0x67337874), 0 kb/s
      Metadata:
        handler_name    : SubtitleHandler

後話

添加字幕不僅能夠增加影片的易讀性,更重要的是能夠避免因語言或口音差異所造成的誤解和混淆。在選擇使用 Soft Subs 或 Hard Subs 時,則視個人具體需求和使用場景來決定。有些內容創作者會選擇使用硬字幕來保護其字幕內容的完整性,防止字幕被他人輕易提取或修改。又或者需要提供給多國讀者,則建議使用軟性的多軌方式讓觀眾選用。

參考

[1] How To Burn Subtitles Into Video — FFmpeg Bug Tracker and Wiki
https://trac.ffmpeg.org/wiki/HowToBurnSubtitlesIntoVideo

[2] Subtitles Filter — FFmpeg
https://ffmpeg.org/ffmpeg-filters.html#subtitles-1

[2] Main Options (-metadata) — FFmpeg
https://ffmpeg.org/ffmpeg.html#Main-options

額外讀物

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料