SRT 轉 WebVTT
把 SRT 字幕轉成 WebVTT,讓 HTML <video> 真的顯示得出來。全部在瀏覽器裡完成,並說明檔頭、逗號、MIME 類型與編碼這四個坑。
在你的瀏覽器中執行
負值表示字幕提早出現。會被推到零之前的字幕會停在零,不會被丟掉。
沒有帶過去的東西
解析與輸出都在你的瀏覽器裡完成,檔案不會上傳。
為什麼非轉不可
瀏覽器不讀 SRT。<track> 元素只接受一種字幕格式,就是 WebVTT,其他一律忽略——而且是無聲無息地
忽略,主控台不會有錯誤,畫面上也看不出哪裡不對。影片播得好好的、字幕就是不出來,幾乎都是這件事。
兩種格式想做的事其實一樣,所以「把副檔名改掉」才會讓人覺得應該可行。它不可行,理由有三個:
| SRT | WebVTT | |
|---|---|---|
| 第一行 | 數字 1 | WEBVTT 這個字 |
| 時間戳 | 00:01:02,500 | 00:01:02.500 |
| 字幕編號 | 每一條都有 | 不使用 |
把檔案貼到上面,或用選檔按鈕挑一個,就會得到 .vtt。沒有任何東西被上傳。
那行檔頭不是裝飾
一個 WebVTT 檔如果開頭不是 WEBVTT,它就不是 WebVTT 檔,規格要求瀏覽器當場停止解析。轉好的檔案
還是什麼都不顯示,最常見的原因就是這個。
逗號是另一半。00:00:01,000 在 WebVTT 裡是解析錯誤,而一個壞掉的時間戳只會弄死它自己那一條
字幕,不會弄死整個檔案——所以手動改過的檔案可能只少幾句話、其他都正常,這比整份不顯示難發現
得多。
掛到影片上
<video controls crossorigin="anonymous">
<source src="film.mp4" type="video/mp4" />
<track kind="subtitles" src="film.vtt" srclang="zh-Hant" label="中文" default />
</video>
檔案本身沒問題,還有三件事會讓它失敗:
- 要以
text/vtt提供。 伺服器把.vtt當成application/octet-stream或text/plain送 出去,這條軌就會被拒絕。text/vtt才是註冊過的類型。 file://不行。<track>受同源政策管轄,而直接從硬碟開啟的頁面過不了。隨便一個本機 伺服器就夠了。- 跨網域要兩邊都做。 字幕放在別的網域,需要那個網域回
Access-Control-Allow-Origin,而且<video>要加crossorigin。只做一邊等於沒做。
default 決定字幕預設開啟;沒有它,觀眾得自己去播放器選單裡找,而大多數人不會去找。
編碼——中文字幕踩得最慘的一個坑
WebVTT 檔一定要是 UTF-8。 規格裡沒有編碼宣告,也沒有退路——你沒有辦法在檔案裡寫「我是 Big5」。
SRT 沒有這條規定,所以外面流通的 SRT 是當初存檔那台機器用什麼就是什麼:Big5、GB18030、
Shift-JIS、Windows-1252。從論壇抓來的中文字幕檔非常可能是 Big5,逐位元組轉過去,會得到一個格式
完全合法、內容全是亂碼的 .vtt。
這個頁面以 UTF-8 讀取檔案。如果上面的預覽已經是亂碼,那就是原檔不是 UTF-8,再怎麼轉都不會 好——先用能選編碼的文字編輯器另存成 UTF-8,再回來轉。
這趟轉換改變了什麼
幾乎什麼都沒改,這正是重點。時間精確到毫秒完全一致,文字原樣搬過去,<i>、<b>、<u> 在兩種
格式裡寫法相同,會活下來。
字幕編號會被拿掉,因為 WebVTT 不用。cue 識別碼——時間行上面那個選填的名字——也會拿掉,因為除了 WebVTT 自己的 CSS 之外沒有東西會讀它。
反過來轉一樣不會掉東西,只有 align:start position:10% 這類 cue 設定例外,因為 SRT 根本沒有
「位置」可言。