跳至主要內容
SubtitleMatrix

產生 HTML track 元素

匯出HTML track 元素
或者貼上字幕文字

選項

字幕(subtitles)面向聽得到聲音、只需要文字的觀眾 —— 翻譯,或同語言的文字稿。聽障字幕(captions)面向聽不到聲音的觀眾,所以它還會帶上聲音傳達給其他人的資訊:音樂、關門聲、電話鈴響。同一份檔案可以承擔任一用途,所以這一頁直接問你而不是猜測;而且這個值之後無法在元素內部修改。描述、章節與中繼資料不提供:它們都無法用字幕檔案的內容填充。

一個簡短的語言標籤,例如 en、en-GB 或 pt-BR,標明字幕裡文字的語言,而不是影片的語言。宣告為字幕(subtitles)的軌道必須給出語言,所以清空這個欄位會退回 en,而不是刪掉這個屬性 —— 又因為所有屬性都會列印在輸出裡,你可以在貼上之前就看到退回結果。

自由文字:English、English (SDH)、Français。當頁面提供多條軌道時,觀眾就是從這個選單裡選,所以按你受眾認得的寫法來寫。清空這個欄位會整個去掉該屬性,而不是寫一個空值,從而把命名交還給播放器;空標籤會在選單裡留下一行沒有名字的項目。

開啟後,影片一開始播放字幕就出現。一個媒體元素只能有一條預設軌道,所以如果頁面已經有一條,就保持關閉:第二條自稱預設的軌道會讓播放器選錯,而不做預設只意味著觀眾需要自己打開。

時間以哪個影格率計算。在格式頁面上,這是 MicroDVD 需要的值,因為它把時間存成影格編號。在影格率頁面上,它是檔案當初對應的速率 —— 字幕是照這個版本製作的 —— 而頁面的第二個欄位填你要搭配的影片速率。常見的有 23.976、24、25、29.97、30、50、59.94 和 60。填錯會讓整條時間軸位移;在影格率頁面上,位移是按比例發生,而不是固定的量。

這一頁把你手上的字幕放進一個可以直接貼進網頁的 HTML 元素。產物只有一行 `<track>`,WebVTT 內嵌在它的 `src` 屬性裡,所以字幕文字跟著標記一起走——不必再上傳第二個檔案、不必把路徑調對,播放器也不可能去找一個根本不存在的東西。

內嵌就是這一頁存在的全部理由,而原因是瀏覽器對本機檔案的處理方式。軌道是用抓取的方式取得,而不是直接畫出來的;當網頁本身是從磁碟打開的時候,瀏覽器會拒絕那次抓取,於是存到桌面上的一份網頁裡的 `<track src="film.vtt">` 什麼都不會顯示:畫面上沒有錯誤、字幕選單空無一物,主控台多一行大多數人從不打開的訊息。`data:` URI 從來不需要抓取——文字就坐在屬性裡——所以在那種情況下照樣能用。代價是體積,WebVTT 裡每一個空格與換行都會變成三個字元;而這筆代價在這裡值得付,因為這個元素的用途,就是自己一個人也能運作。

屬性的值來自面板上的欄位,因為它們沒有一個能從你的檔案裡讀出來。`kind` 最要緊:subtitles 是給聽不懂音軌的觀眾看的翻譯,captions 則是更完整的版本,連音樂與音效也一併交代給聽不到聲音的觀眾。一份塞滿 `[door slams]` 與音符的檔案,兩種都可能,只有你知道它是為哪一群觀眾做的——所以這一頁選擇發問,而不是猜。另外三個欄位,分別是文字使用的語言、播放器字幕選單上顯示的名稱,以及這條軌道是否該自動開啟。

其中兩個欄位在清空時行為不同,這個差別值得知道。清掉選單名稱,會把整個屬性拿掉,因為標籤是選填的,省略它就等於把選擇權交還給播放器。清掉語言欄位則不會:一條宣告自己是 subtitles 的軌道必須說出語言,所以空白的欄位會回退成 `en`,而不是產出一個缺了必填東西的元素。兩者都不是偷偷替換——輸出的每一行屬性都印出來,你看得到自己的欄位產生了什麼。

元素裡的字幕文字,由轉換頁面所用的同一個 WebVTT 寫出器負責,因此一份本來就是 WebVTT 的檔案,會保留它在字幕條之外攜帶的一切:`WEBVTT` 那一行的文字、註解與樣式區塊,以及決定一行字落在畫面哪個位置的字幕條設定。你的檔案沒有被改變任何東西,也沒有任何東西被上傳;文字、時間與樣式,都以進來時的狀態離開。

範例

一份 SRT 檔案,使用預設欄位

輸入

1
00:00:01,000 --> 00:00:03,000
The room is dark.

2
00:00:04,000 --> 00:00:06,000
Nobody came.

輸出

<track kind="subtitles" src="data:text/vtt;charset=utf-8,WEBVTT%0A%0A1%0A00%3A00%3A01.000%20--%3E%2000%3A00%3A03.000%0AThe%20room%20is%20dark.%0A%0A2%0A00%3A00%3A04.000%20--%3E%2000%3A00%3A06.000%0ANobody%20came.%0A" srclang="en" label="English" default>

輸出只有一行,整份檔案都在裡面:%0A 是換行、%20 是空格,所以 WebVTT 搭著 src 屬性一起走,而不是待在網頁旁邊的另一個檔案裡。四個屬性就是四個欄位——文字使用的語言、觀眾在播放器字幕選單裡挑的那一列,以及 default,它讓這條軌道自動開啟。SRT 的字幕條編號被保留為字幕條識別碼。

WebVTT 進來,原樣是同一份 WebVTT

輸入

WEBVTT - exported from the editing room

NOTE The first pass was done by hand.

STYLE
::cue { color: #f2f2f2; }

intro
00:00:01.000 --> 00:00:03.000 align:start position:10%
The room is dark.

2
00:00:04.000 --> 00:00:06.000
Nobody came.

輸出

<track kind="subtitles" src="data:text/vtt;charset=utf-8,WEBVTT%20-%20exported%20from%20the%20editing%20room%0A%0ANOTE%20The%20first%20pass%20was%20done%20by%20hand.%0A%0ASTYLE%0A%3A%3Acue%20%7B%20color%3A%20%23f2f2f2%3B%20%7D%0A%0Aintro%0A00%3A00%3A01.000%20--%3E%2000%3A00%3A03.000%20align%3Astart%20position%3A10%25%0AThe%20room%20is%20dark.%0A%0A2%0A00%3A00%3A04.000%20--%3E%2000%3A00%3A06.000%0ANobody%20came.%0A" srclang="en-GB" label="English (UK)" default>

WebVTT 檔案在字幕條之外攜帶的一切都活了下來:WEBVTT 那一行上的備註、NOTE 區塊、決定播放器裡字幕長相的 STYLE 區塊、字幕條的名稱行,以及每條字幕的 align:start position:10% 設定(裡面的 %25 是百分比符號,因為裸的百分比符號不允許出現在 URI 裡)。以 WebVTT 進來的檔案,就以同一份 WebVTT 出去。兩個欄位寫著 en-GB 與 English (UK),因為這份拷貝是做給英國觀眾的——檔案本身什麼都沒說。

給聽不到聲音的觀眾看的字幕

輸入

1
00:00:01,000 --> 00:00:03,000
[door slams]
The room is dark.

2
00:00:04,000 --> 00:00:06,000
♪ Nobody came ♪

輸出

<track kind="captions" src="data:text/vtt;charset=utf-8,WEBVTT%0A%0A1%0A00%3A00%3A01.000%20--%3E%2000%3A00%3A03.000%0A%5Bdoor%20slams%5D%0AThe%20room%20is%20dark.%0A%0A2%0A00%3A00%3A04.000%20--%3E%2000%3A00%3A06.000%0A%E2%99%AA%20Nobody%20came%20%E2%99%AA%0A" srclang="en" label="Tom &amp; &quot;the boss&quot;" default>

這份檔案塞滿音效與音樂,那正是 kind="captions"——給聽不到聲音的觀眾看的字幕——存在的目的,而這件事只有欄位能說出來。另外,選單名稱被輸入成 Tom & "the boss",出來時變成 Tom &amp; &quot;the boss":一個沒有跳脫的引號會當場把屬性關掉,名稱剩下的部分就會變成元素上一堆亂七八糟的屬性。

三個欄位被清空或關掉

輸入

1
00:00:01,000 --> 00:00:03,000
A cold night,
and no heating.

2
00:00:04,000 --> 00:00:06,000
Every night this week?

輸出

<track kind="subtitles" src="data:text/vtt;charset=utf-8,WEBVTT%0A%0A1%0A00%3A00%3A01.000%20--%3E%2000%3A00%3A03.000%0AA%20cold%20night%2C%0Aand%20no%20heating.%0A%0A2%0A00%3A00%3A04.000%20--%3E%2000%3A00%3A06.000%0AEvery%20night%20this%20week%3F%0A" srclang="en">

改了三個欄位,得到三種不同結果,因為 HTML 對它們的要求各不相同。選單名稱整個從元素上消失了——它是選填的,省略就等於把決定權交給播放器。語言欄位空著,仍然產出 srclang="en":宣告自己是 subtitles 的軌道必須說出語言,所以不存在「空白的語言」,而回退的結果就印在輸出裡。default 開關關掉了,那個屬性也跟著消失,這條軌道因此不會自動開啟——當一個網頁裡放了不只一條軌道時,這是安全的方向。

常見問題

我還需要在網頁旁邊放一份 .vtt 檔案嗎?

不需要,而這正是這一頁的重點。WebVTT 被寫進 src 屬性裡成為 data: URI,所以這個元素自己帶著字幕。你可以把它貼進網頁、把檔案寄給別人,或搬到另一個資料夾,字幕照樣會出現。唯一要注意的是整份東西就是一個屬性:如果只複製了那一長行的一部分,URI 就斷了,軌道會是空的。

如果我直接從自己的電腦打開 HTML 檔案,這還能運作嗎?

可以,而這個情境正是這一頁要把字幕內嵌的原因。網頁從磁碟打開時,瀏覽器會拒絕抓取另一個軌道檔案,所以指向 film.vtt 的軌道什麼都不會顯示——沒有看得見的錯誤,只有一個空空的字幕選單。data: URI 根本不需要抓取,文字已經在屬性裡,所以它在你的桌面上伺服器上一樣能用。

為什麼輸出比我的字幕檔案長這麼多?

因為 URI 裡每一個不是字母或數字的字元都會變成三個——空格是 %20,換行是 %0A。一百 KB 的檔案會變成好幾百 KB。Base64 會短一些,大約只比原始大三分之一而不是變成兩倍,但結果會是一整片讀不懂的字元;現在這樣,你可以盯著 src 屬性認出自己的對白,對於一份即將貼進網頁、之後還要手動維護的檔案來說,多出來的體積值得。

我把欄位清空之後,為什麼 label 屬性就不見了?

因為選單名稱在 HTML 裡是選填的,省略它並不表示「沒有名稱」——它表示由播放器決定字幕選單要顯示什麼,通常就是語言。所以清空欄位會移除整個屬性,而不是寫一個空字串進去,因為 label="" 會在選單上留下一列空白。隨時都可以把名稱加回來;它就是一段純文字,頁面上沒有別的東西依賴它。

這裡的 subtitles 與 captions 差在哪裡?

差在給誰看。subtitles 假設觀眾聽得到音軌,需要的是把台詞翻譯出來或寫成文字;captions 假設觀眾聽不到音軌,所以還要交代聽覺觀眾透過聲音得到的資訊——音樂、開門、電話鈴響。一份檔案可以服務其中任一目的,同一段文字兩邊都有,所以這一頁沒辦法判斷你要的是哪一種。而且元素一旦產出,之後也無法從裡面改,請挑你觀眾真正需要的那一個。

其他種類的 track 為什麼沒有放進來?

有三種沒有:descriptions,用旁白描述畫面給看不到的觀眾;chapters,那是導覽而不是字幕,本站另有專門一頁;以及 metadata,它不顯示給任何人。這三種都裝不下一份字幕檔案的內容,放進來只會讓你做出一個什麼都不顯示的元素。提供的兩種,才是字幕檔案真的能派上用場的兩種。

我的字幕在進來的過程中會被改變嗎?

文字、時間與樣式都不變,而 WebVTT 檔案會保留自己的註解、樣式與區域區塊,以及每條字幕的設定。改變的是形狀:內容會用播放器讀的 WebVTT 語法重寫,所以 SRT 檔案裡 00:00:01,000 的逗號會變成句點。有一個位元組是刻意丟掉的——開頭那個表示檔案是 UTF-8 的標記,因為 data URI 自己就聲明了編碼,留著它反而會變成最前面三個莫名其妙的字元。

相關工具