Ithy Logo

如何使用Python自動處理.srt字幕檔案:統計並管理重複字幕

深入解析與完整範例,支援中英日多語言字幕處理

subtitle editing process

主要重點

  • 自動統計與識別重複字幕:利用Python腳本分析字幕檔案中的重複行。
  • 互動式用戶選擇:提供用戶選擇刪除或保留最常見的字幕。
  • 多語言支援與編碼處理:確保中文、英文及日文字幕的正確處理與編碼兼容。

引言

.srt(SubRip Subtitle)檔案廣泛應用於電影、電視節目及線上影片中,用於顯示對白及其他文字資訊。然而,隨著時間的推移和多次編輯,字幕檔案中可能出現重複的字幕行,這不僅影響觀看體驗,還可能增加檔案大小。為了解決這一問題,使用Python自動化處理.srt檔案成為一個高效的解決方案。本指南將詳細介紹如何編寫一個Python腳本,讀取.srt檔案,統計並管理重複字幕,並輸出經過處理的新檔案。

需求分析與功能概述

功能需求

  • 自動讀取和解析.srt字幕檔案。
  • 統計每行字幕的出現次數。
  • 識別出現次數最多的重複字幕。
  • 與用戶互動,詢問是否刪除或保留該重複字幕。
  • 根據用戶選擇,刪除或保留相應的字幕行。
  • 輸出一個新的經過處理的.srt字幕檔案。
  • 支援多種語言字幕,包括中文、英文和日文。

技術挑戰

  • 編碼兼容性:不同語言的字幕檔案可能使用不同的編碼,如UTF-8、CP950、Shift-JIS等,需確保Python腳本能夠正確讀取和處理這些編碼。
  • 字幕格式解析:確保腳本能正確解析.srt檔案的編號、時間戳及字幕文本。
  • 用戶互動:在自動化過程中提供用戶選擇的機制,以靈活控制字幕的刪除或保留。

完整Python腳本

腳本概述

以下完整的Python腳本實現了上述需求。腳本分為多個函數,分別負責讀取檔案、解析字幕、統計重複字幕、與用戶互動決策,以及寫入新的字幕檔案。該腳本支援中文、英文和日文字幕,並能處理多種編碼格式。

Python腳本程式碼

import re
from collections import defaultdict, Counter

def read_srt_file(file_path):
    """
    讀取.srt檔案,嘗試多種編碼,返回檔案內容。
    """
    try:
        with open(file_path, 'r', encoding='utf-8') as file:
            content = file.read()
        return content
    except UnicodeDecodeError:
        # 嘗試其他常見編碼
        encodings = ['cp950', 'shift-jis', 'gb18030']
        for encoding in encodings:
            try:
                with open(file_path, 'r', encoding=encoding) as file:
                    content = file.read()
                return content
            except UnicodeDecodeError:
                continue
        raise Exception("無法識別檔案編碼。請確認檔案的編碼格式。")

def parse_srt(content):
    """
    解析.srt檔案內容,返回字幕列表。
    """
    blocks = re.split(r'\n\n+', content.strip())
    subtitles = []
    for block in blocks:
        lines = block.strip().split('\n')
        if len(lines) >= 3:
            number = lines[0]
            timestamp = lines[1]
            text = '\n'.join(lines[2:]).strip()
            subtitles.append({
                'number': number,
                'timestamp': timestamp,
                'text': text
            })
    return subtitles

def find_duplicates(subtitles):
    """
    找出重複的字幕文本並統計出現次數。
    返回一個字典,鍵為字幕文本,值為出現的索引列表。
    """
    text_count = defaultdict(list)
    for i, subtitle in enumerate(subtitles):
        text_count[subtitle['text']].append(i)
    # 返回出現超過一次的字幕
    return {text: indices for text, indices in text_count.items() if len(indices) > 1}

def write_new_srt(output_path, subtitles):
    """
    將處理後的字幕列表寫入新的.srt檔案。
    """
    with open(output_path, 'w', encoding='utf-8') as file:
        for i, subtitle in enumerate(subtitles, 1):
            if subtitle:  # 確保字幕未被刪除
                file.write(f"{i}\n")
                file.write(f"{subtitle['timestamp']}\n")
                file.write(f"{subtitle['text']}\n\n")

def process_duplicates(subtitles, duplicates):
    """
    與用戶互動,決定是否刪除重複字幕。
    """
    for text, indices in duplicates.items():
        print(f"\n發現重複字幕: \"{text}\"")
        print(f"出現次數: {len(indices)}")
        while True:
            choice = input("是否要刪除這個重複字幕?輸入 '刪除' 或 '保留': ").strip()
            if choice == '刪除':
                # 刪除所有相同的字幕行
                for index in indices:
                    subtitles[index] = None
                print("已刪除所有相同的字幕行。")
                break
            elif choice == '保留':
                print("保留該字幕。")
                break
            else:
                print("無效的輸入,請重新輸入。")
    # 移除被標記為None的字幕
    subtitles = [s for s in subtitles if s is not None]
    return subtitles

def main():
    """
    主函數,執行整個處理流程。
    """
    input_file = input("請輸入要處理的.srt檔案路徑: ").strip()
    output_file = input("請輸入輸出新的.srt檔案路徑: ").strip()

    # 讀取並解析字幕檔
    try:
        content = read_srt_file(input_file)
    except Exception as e:
        print(f"錯誤: {e}")
        return

    subtitles = parse_srt(content)
    if not subtitles:
        print("字幕檔案解析失敗或檔案格式不正確。")
        return

    # 找出重複的字幕
    duplicates = find_duplicates(subtitles)
    if not duplicates:
        print("沒有發現重複的字幕。")
    else:
        # 處理重複字幕
        subtitles = process_duplicates(subtitles, duplicates)

    # 寫入新的字幕檔案
    write_new_srt(output_file, subtitles)
    print(f"新的字幕檔案已儲存至: {output_file}")

if __name__ == "__main__":
    main()
  

詳細腳本解析

1. 讀取與解析.srt檔案

腳本的第一步是讀取.srt檔案內容。由於不同語言可能使用不同的編碼,read_srt_file函數首先嘗試以UTF-8編碼讀取檔案。如果失敗,則依序嘗試CP950(繁體中文)、Shift-JIS(日文)及GB18030(簡體中文)等常見編碼。如果所有嘗試均失敗,腳本將拋出一個錯誤,提示無法識別檔案編碼。

2. 解析字幕內容

parse_srt函數使用正則表達式將整個檔案內容拆分為多個區塊,每個區塊代表一個字幕。每個區塊通常包含三部分:字幕編號、時間戳及字幕文本。函數將這些部分提取並存儲在一個字典列表中,以便後續處理。

3. 統計與識別重複字幕

為了找出重複的字幕行,find_duplicates函數會遍歷所有字幕文本,並使用defaultdict來統計每條字幕出現的索引。這樣可以輕鬆識別出現次數超過一次的字幕文本。

4. 與用戶互動決策

process_duplicates函數負責與用戶互動,詢問是否刪除每一組重複字幕。若用戶選擇刪除,則將這些字幕行從列表中標記為None,最終在過濾階段移除這些標記。

5. 寫入新的.srt檔案

經過處理後的字幕列表將由write_new_srt函數寫入新的.srt檔案中。每個字幕行的編號將重新排序,確保檔案的格式正確。

處理不同編碼與多語言支援

編碼處理

字幕檔案可能使用多種編碼格式,特別是涉及多語言的情況。為了確保腳本能夠正確讀取各種編碼,腳本在讀取檔案時首先嘗試UTF-8編碼,若失敗則依序嘗試其他常見編碼(如CP950、Shift-JIS、GB18030)。這種方法可以大大提高腳本的兼容性,適應不同語言的字幕檔案。

多語言支援

腳本通過處理不同的編碼,實現了對中文、英文及日文字幕的支援。無論字幕文本中包含哪種語言,腳本都能夠正確解析、統計及處理重複的字幕行,從而提高字幕檔案的質量和一致性。

用戶互動與決策流程

腳本的核心之一是與用戶的互動,提供靈活的選擇來刪除或保留重複的字幕。當腳本識別到重複的字幕行時,會顯示字幕文本及其出現次數,並提示用戶進行選擇。以下是交互流程的詳細步驟:

  1. 腳本識別出一組重複的字幕行。
  2. 顯示該字幕文本及其出現的次數。
  3. 提示用戶輸入選擇:「刪除」以移除所有重複,或「保留」以保留原有字幕。
  4. 根據用戶的選擇,執行相應的操作。
  5. 重複這一過程,直到所有重複字幕行都被處理。

腳本的實際應用與最佳實踐

使用方法

  1. 確保已安裝Python環境,建議使用Python 3.6及以上版本。
  2. 將上述腳本保存為process_srt.py
  3. 打開終端或命令提示符,導航至腳本所在目錄。
  4. 執行腳本:python process_srt.py
  5. 依照提示,輸入要處理的.srt檔案路徑及輸出的檔案路徑。
  6. 針對每一組重複字幕,輸入「刪除」或「保留」以完成決策。
  7. 完成後,檔案會被儲存在指定位置,並包含經過處理的新字幕行。

最佳實踐

  • 備份原始字幕檔案:在進行任何修改前,建議先備份原始.srt檔案,以防止資料遺失或錯誤。
  • 檢查編碼格式:在處理字幕檔案前,確認其編碼格式,避免因編碼問題導致解析失敗。
  • 使用虛擬環境:為了避免依賴衝突,建議在虛擬環境中執行腳本。
  • 驗證輸出檔案:處理完成後,打開新的.srt檔案,檢查字幕行的正確性與完整性。
  • 處理大型檔案時耐心等待:對於包含大量字幕行的檔案,腳本可能需要較長時間處理,請耐心等待。

常見問題與解答

1. 腳本無法識別檔案編碼,該怎麼辦?

如果腳本顯示「無法識別檔案編碼」,請確認您的.srt檔案是否使用了不在腳本嘗試範圍內的編碼。您可以手動指定檔案的編碼,或者使用文本編輯器轉換檔案編碼至UTF-8。

2. 刪除所有重複字幕後,檔案出現空白段落,如何處理?

腳本已經包含刪除None值的過程,確保最終的字幕列表中不包含被刪除的字幕行。然而,如果出現空白段落,建議檢查腳本是否正確排除None值,或手動清理輸出的.srt檔案。

3. 如何處理多語言混合的字幕檔案?

腳本支援多種編碼格式,但如果字幕檔案中同時包含多種語言,建議先確保檔案的編碼一致。此外,腳本在處理時不區分語言,僅基於字幕文本進行統計與處理。

示例與應用場景

示例字幕檔案

假設有一個名為example.srt的字幕檔案,內容如下:

1
00:00:01,000 --> 00:00:04,000
你好,歡迎觀看本影片。

2
00:00:05,000 --> 00:00:07,000
Thank you for watching this video.

3
00:00:08,000 --> 00:00:10,000
ありがとう、動画をご覧いただきありがとうございます。

4
00:00:11,000 --> 00:00:13,000
你好,歡迎觀看本影片。

5
00:00:14,000 --> 00:00:16,000
Thank you for watching this video.

執行腳本後,腳本會識別出「你好,歡迎觀看本影片。」和「Thank you for watching this video.」各出現兩次,並詢問是否刪除這些重複字幕。根據用戶的選擇,最終生成的example_new.srt將只保留一次每個重複的字幕行。

應用場景

  • 影片後製製作:在影片製作完成後,確保字幕檔案的乾淨與一致性,提升觀眾觀看體驗。
  • 字幕校對與編輯:自動化工具能有效減少手動檢查的時間,快速定位並處理重複或錯誤的字幕行。
  • 教育與培訓材料:在製作教學影片時,確保字幕的準確性,有助於學習者更好地理解內容。

參考資料

結論

通過上述Python腳本,您可以高效地管理.srt字幕檔案中的重複字幕行,提升字幕檔案的品質和一致性。腳本不僅支援多種語言和編碼,還提供了靈活的用戶互動選項,使得字幕處理過程更加人性化和精確。無論是在影片製作、教育材料編輯,還是個人愛好中,這個工具都能大大提升您的工作效率和字幕品質。


Last updated January 25, 2025
Search Again