繁體中文

視訊與字幕·字幕工具包

瀏覽器如何解析 SRT 檔案:區塊、索引、時間碼和文字

· 工作原理

字幕 srt 檔案格式

兩個 SRT 提示區塊由空白行分隔,每個提示區塊都有一個索引行、一個時間碼行和文字行
原始 ToolAcre 向量圖

SRT 看起來微不足道,直到您遇到真正的檔案。這篇文章將介紹解析器如何分割區塊、讀取索引和時間碼、處理多行文字以及從實際檔案包含的格式錯誤的區塊中復原。

檔案“看起來不錯”,但缺少一半線索——看似寬鬆的格式如何隱藏嚴格的期望

SRT 沒有規格主體,沒有 MIME 註冊,也沒有播放器隨附的驗證器。相反,存在的是大多數軟體都同意的形狀:一個數字、一個時間碼行、一行或多行文字,然後是一個空白行。由於形狀是常規的而不是指定的,因此兩個檔案在文字編輯器中看起來都是正確的,但只有其中一個加載,失敗通常是無聲的。無法讀取提示的玩家往往會跳過它而不是報告它,因此帶有損壞區塊的檔案會出現間隙而不是錯誤。

因此,解析器有兩個相反方向的工作。它必須接受真實檔案包含的變化,因為檔案是由轉錄服務、手動編輯和格式轉換器產生的,每個服務都做出不同的假設。它還必須拒絕會在錯誤時間發出提示的讀數,因為默默地錯誤的時間戳比報告的故障更糟。

分成區塊-作為分隔符號的空白行以及雜散空白和 CRLF 的麻煩

分割發生在空行上,而不是索引號碼。解析器首先規範行結尾,用單一換行符號取代 CRLF 對和單獨的 CR,因為在 Windows 上編寫並在 Unix 上編輯的檔案可以包含這兩者。然後它會分割成兩個或多個換行符,修剪每個結果區塊並丟棄空的區塊。這種順序很重要:在標準化之前進行分割會在時間碼行的末尾留下雜散的回車符,然後時間碼將無法匹配。

位元組順序標記在這之前被剝離。檔案開頭的 UTF-8 BOM 是三個字節,天真的解析器將其視為第一個索引號的一部分,這足以使第一個提示在後面的每個提示解析時不可讀。空白分隔行上的尾隨空格由修剪處理,因此空白行包含空格的檔案仍可正確分割。

索引行-為什麼數字經常是錯誤的、重複的或缺少的,以及為什麼解析器不應該信任它們

索引號被讀取然後被忽略。真實檔案編號提示從零開始,合併後重新編號,手動編輯後複製數字,或在轉換器寫入檔案時完全省略該行。信任這些數字意味著繼承每一個錯誤,因此解析器會分配自己的序號,計算迄今為止已成功建構的線索。

這個選擇也解釋了為什麼解析器從不要求索引行存在。它透過在區塊中搜尋包含箭頭的第一行來定位時間碼行,而不是假設時間碼是第二行。沒有索引行的區塊會正常解析,而時間碼之前有兩個雜散行的區塊仍然會解析,因為位置不是標識時間碼的內容。

時間碼行 — HH:MM:SS,mmm --> HH:MM:SS,mmm,可容忍的變化和破壞玩家的變化

時間碼行與單一正規表示式進行匹配,並其中的容差是經過深思熟慮的。時間是可選的,因為 WebVTT 允許兩個欄位的讀數並轉換器會發出它。無論檔案聲稱採用哪種格式,都接受逗號或句號作為毫秒分隔符,因為混合分隔符很常見,拒絕它們會導致更多好的檔案失敗而不是壞的檔案。小數位填滿在右側,因此以一位數結尾的提示會被讀取為數百毫秒而不是單位。

兩次閱讀均被拒絕。超過五十九分或秒的欄位將被拒絕而不是攜帶,因為九十秒不是時鐘讀數,通常表示檔案已損壞或轉換錯誤;默默地將其標準化會移動提示。開頭或結尾無法解析的行會產生一個記錄的問題,命名有問題的文字和預期的形狀,並該區塊將被跳過而不是猜測。

文字行-多行提示、格式化標籤以及區塊真正結束的位置

時間碼行之後的所有內容都是提示文字,與換行符重新連接在一起。沒有行數限制,也不會嘗試重排,因此三行提示將保留為三行。這就是空行是承載的原因:它是唯一告訴解析器文字已經結束的東西,這就是為什麼自己的文字包含空行的提示將被讀取為兩個區塊,而後半部將被報告為沒有時間碼。

提示設定與結束時間戳記之間由兩個或多個空格分隔。 WebVTT 允許定位指令(例如對齊和行放置)遵循同一行的結束時間,因此解析器在解析時間戳記之前將它們分開,並將它們保留在提示旁邊。單一空格不是分隔符,它可以防止雜亂的時間碼行遺失其結束時間。

工作範例:解析具有兩個故意錯誤的五個提示檔案 - 強大的解析器恢復什麼以及它標記什麼

取一個五塊檔案,其中塊三的時間碼行已損壞,無法讀取 00:01:75,000 --> 00:01:78,000,而塊四碼在複製和貼上過程中四碼。解析器正常讀取區塊一和區塊二,並將它們編號為一和二。第三塊與時間碼的形狀匹配,但帶有 75 秒欄位,因此它被拒絕並記錄為錯誤的時間戳,命名它無法讀取的行。

塊四根本不包含箭頭,因此它被記錄為沒有時間戳,引用該塊的前四十個字符,以便可以在原始檔案中找到該行。區塊五解析並成為提示三,而不是提示五,因為編號會計算成功的提示。結果是三個可用的提示和兩個具體的、已定位的投訴,而不是第一個故障出現異常並沒有關於第二個故障的資訊。

這不包括 - ASS/SSA 樣式、定位代碼和非字幕文字轉儲到 SRT

這描述了 SRT 以及共享其提示形狀的 WebVTT 部分。它不包括 ASS 和 SSA,它們帶有腳本頭、樣式定義和每個事件的樣式引用,並不能透過在空白行上拆分來讀取。這些格式使用的卡拉 OK 計時、繪圖命令和內聯覆蓋標籤超出了提示和時間碼解析器模型的範圍。

它也不修復文字。貼上到沒有時間碼的檔案中的腳本會產生沒有時間戳的塊列表,該列表可以準確報告,但如果沒有不存在的計時信息,則無法將其轉換為字幕。編碼錯誤是一個單獨的問題:使用錯誤的字元集解碼的檔案會解析為完全有效的提示,但其文字是錯誤的,並任何結構檢查都無法檢測到這一點。

重點:寬鬆解析,嚴格編寫 — 字幕工具包如何讀取混亂的 SRT 並寫回乾淨的內容

工作規則是寬解析、嚴書寫。在進入過程中,接受可選的時間、分隔符號、缺少索引行、混合行結尾和前導位元組順序標記,並將每個錯誤記錄為已定位問題,而不是拋出第一個錯誤,因此可以一次修復檔案。在退出時,發出一種規範形狀。

這就是字幕工具包在轉換時所做的事情。提示從 1 開始重新編號並保持連續,時間戳以 SRT 的逗號和 WebVTT 的句號重新發出,返回的檔案是玩家期望的形狀,無論輸入多麼不規則。將玩家拒絕的檔案貼到轉換器中,並首先閱讀報告的問題;他們命名提示並引用台詞,這通常足以找到原作中的錯誤。