Ask me anything
Ithy Logo
Sign in to save

完整的SRT字幕時段保留Python腳本指南

使用Python與Tkinter創建強大且多語言支持的字幕時段編輯工具

Python subtitle editing tool interface

三大重點

  • 多語言支持:本腳本全面支援中文、英文及日文字幕,確保廣泛適用性。
  • 直觀的GUI介面:基於Tkinter構建的使用者友好界面,簡化字幕處理流程。
  • 靈活的時段選擇:允許用戶輸入多個保留時段,自動過濾並重新賦予字幕時間碼。

概述

在處理影片字幕時,經常需要根據特定需求保留或刪除某些時段的字幕內容。本指南將詳細介紹如何使用Python腳本,結合Tkinter GUI,實現自動讀取、過濾並重新生成新的SRT字幕文件。該腳本不僅支援中文、英文和日文字幕,還提供直觀的使用者介面,使其適合不同經驗水平的用戶。

功能介紹

1. 使用者介面 (GUI)

本腳本採用Python的Tkinter模組構建GUI,提供以下功能:

  • 選擇並加載.srt字幕文件。
  • 輸入多個需要保留的時間段,格式為「HH:MM:SS,mmm - HH:MM:SS,mmm」。
  • 顯示處理進度並提示用戶操作結果。

2. 字幕解析與處理

腳本使用pysrt或正則表達式解析SRT文件,具備以下能力:

  • 準確解析字幕的起始和結束時間碼。
  • 根據用戶提供的保留時段過濾不需要的字幕。
  • 重新賦予被保留字幕的時間碼,確保新的SRT文件時間一致且無誤。

3. 多語言支持

本腳本支援處理中文、英文和日文字幕,並確保以下特性:

  • 正確處理不同語言的字符編碼(UTF-8)。
  • 保留原始字幕的語言特性,避免亂碼或字符缺失。

完整腳本詳解

以下是完整的Python腳本,結合了多個來源的最佳實踐,並進行了優化和擴展:

Python腳本:字幕時段保留工具

import tkinter as tk
    from tkinter import filedialog, messagebox, simpledialog
    import pysrt
    from datetime import datetime

    class SubtitleEditor:
        def __init__(self, root):
            self.root = root
            self.root.title("字幕時段編輯器")
            self.root.geometry("700x500")
            
            # 檔案選擇區
            self.file_frame = tk.Frame(root)
            self.file_frame.pack(pady=10)
            
            self.file_path = tk.StringVar()
            tk.Label(self.file_frame, text="字幕檔案:", font=("Arial", 12)).pack(side=tk.LEFT, padx=5)
            tk.Entry(self.file_frame, textvariable=self.file_path, width=50).pack(side=tk.LEFT, padx=5)
            tk.Button(self.file_frame, text="選擇檔案", command=self.select_file).pack(side=tk.LEFT, padx=5)
            
            # 時間區間輸入區
            self.time_frame = tk.Frame(root)
            self.time_frame.pack(pady=10)
            
            tk.Label(self.time_frame, text="輸入保留的時間區間 (每行一個,格式: HH:MM:SS,mmm - HH:MM:SS,mmm)", font=("Arial", 12)).pack()
            self.time_ranges = tk.Text(self.time_frame, height=10, width=80)
            self.time_ranges.pack(padx=10, pady=5)
            
            # 操作按鈕區
            self.button_frame = tk.Frame(root)
            self.button_frame.pack(pady=10)
            
            tk.Button(self.button_frame, text="處理字幕", command=self.process_subtitle, width=20, bg="#388278", fg="white").pack(side=tk.LEFT, padx=20)
            tk.Button(self.button_frame, text="退出", command=root.quit, width=20, bg="#cc9900", fg="white").pack(side=tk.LEFT, padx=20)

        def select_file(self):
            filename = filedialog.askopenfilename(filetypes=[("SRT files", "*.srt")])
            if filename:
                self.file_path.set(filename)

        def time_to_milliseconds(self, time_str):
            try:
                time_obj = datetime.strptime(time_str.strip(), "%H:%M:%S,%f")
                return (time_obj.hour * 3600 + time_obj.minute * 60 + time_obj.second) * 1000 + int(time_obj.microsecond / 1000)
            except ValueError:
                messagebox.showerror("格式錯誤", f"時間格式錯誤: {time_str}")
                return None

        def milliseconds_to_time(self, ms):
            hours = ms // 3600000
            minutes = (ms % 3600000) // 60000
            seconds = (ms % 60000) // 1000
            milliseconds = ms % 1000
            return f"{hours:02d}:{minutes:02d}:{seconds:02d},{milliseconds:03d}"

        def process_subtitle(self):
            if not self.file_path.get():
                messagebox.showerror("錯誤", "請選擇一個.srt字幕文件。")
                return

            # 讀取時間區間
            time_ranges_text = self.time_ranges.get("1.0", tk.END).strip()
            if not time_ranges_text:
                messagebox.showerror("錯誤", "請輸入至少一個保留的時間區間。")
                return

            keep_periods = []
            lines = time_ranges_text.split('\n')
            for line in lines:
                if line.strip():
                    try:
                        start, end = map(str.strip, line.split('-'))
                        start_ms = self.time_to_milliseconds(start)
                        end_ms = self.time_to_milliseconds(end)
                        if start_ms is not None and end_ms is not None:
                            if start_ms < end_ms:
                                keep_periods.append((start_ms, end_ms))
                            else:
                                messagebox.showerror("時間錯誤", f"開始時間需小於結束時間: {line}")
                                return
                    except ValueError:
                        messagebox.showerror("格式錯誤", f"無法解析時間區間: {line}")
                        return

            try:
                # 讀取字幕文件
                subs = pysrt.open(self.file_path.get(), encoding='utf-8')
                new_subs = pysrt.SubRipFile()
                offset = 0

                for period in keep_periods:
                    period_start, period_end = period
                    for sub in subs:
                        sub_start_ms = (sub.start.hours * 3600 + sub.start.minutes * 60 + sub.start.seconds) * 1000 + sub.start.milliseconds
                        sub_end_ms = (sub.end.hours * 3600 + sub.end.minutes * 60 + sub.end.seconds) * 1000 + sub.end.milliseconds

                        # 判斷字幕是否在保留時段內
                        if sub_end_ms > period_start and sub_start_ms < period_end:
                            # 計算新的起始和結束時間
                            new_start_ms = max(sub_start_ms, period_start) - period_start + offset
                            new_end_ms = min(sub_end_ms, period_end) - period_start + offset
                            new_sub = pysrt.SubRipItem(index=len(new_subs)+1,
                                                       start=pysrt.SubRipTime(milliseconds=new_start_ms),
                                                       end=pysrt.SubRipTime(milliseconds=new_end_ms),
                                                       text=sub.text)
                            new_subs.append(new_sub)
                    offset += (period_end - period_start)

                # 保存新字幕文件
                output_path = filedialog.asksaveasfilename(defaultextension=".srt", filetypes=[("SRT files", "*.srt")])
                if output_path:
                    new_subs.save(output_path, encoding='utf-8')
                    messagebox.showinfo("成功", f"字幕已成功處理並保存至:\n{output_path}")
            except Exception as e:
                messagebox.showerror("處理錯誤", f"在處理字幕時發生錯誤: {str(e)}")

    if __name__ == "__main__":
        root = tk.Tk()
        app = SubtitleEditor(root)
        root.mainloop()
    

腳本說明

  1. GUI介面創建:使用Tkinter建立視窗,包含檔案選擇、時間區間輸入及操作按鈕。
  2. 字幕文件選擇:用戶可通過「選擇檔案」按鈕瀏覽並選擇目標.srt文件。
  3. 時間區間輸入:在文本框中輸入多個保留時段,每行一個,格式為「HH:MM:SS,mmm - HH:MM:SS,mmm」。
  4. 字幕處理邏輯:
    • 解析並轉換用戶輸入的時間區間為毫秒數,便於計算。
    • 遍歷原始字幕,判斷每條字幕是否位於任何保留時段內。
    • 如果字幕在保留時段內,則重新計算其時間碼並添加到新的字幕文件中。
  5. 保存新字幕文件:經過處理的字幕將保存為新的.srt文件,用戶可選擇保存路徑與檔名。

程式碼解析

模組導入

- tkinter:用於建立GUI介面。 - filedialog與messagebox:提供文件選擇與彈窗提示功能。 - pysrt:用於解析和操作.srt文件。 - datetime:處理時間格式轉換。

類別設計

SubtitleEditor類別封裝了所有GUI元件和字幕處理功能,使程式結構清晰,易於維護和擴展。

時間轉換方法

- time_to_milliseconds:將「HH:MM:SS,mmm」格式的時間轉換為毫秒數。 - milliseconds_to_time:將毫秒數轉換回「HH:MM:SS,mmm」格式的時間碼。

字幕處理方法

process_subtitle方法負責整個字幕處理流程,包括讀取文件、解析時間區間、過濾並重新賦予時間碼,最終保存新的字幕文件。

使用步驟

  1. 運行腳本後,主視窗將顯示。
  2. 點擊「選擇檔案」按鈕,選擇需要處理的.srt字幕文件。
  3. 在時間區間輸入框中,輸入所有需要保留的時間段,每行一個,格式為「HH:MM:SS,mmm - HH:MM:SS,mmm」。例如:
    00:02:15,000 - 00:02:40,000
    00:04:20,000 - 00:04:35,000
  4. 點擊「處理字幕」按鈕,腳本將自動過濾並重新賦予字幕時間碼。
  5. 選擇保存新字幕文件的位置與名稱,完成後將彈出成功提示。

使用示例

假設原始字幕文件包含以下內容:


1
00:00:59,002 --> 00:01:01,202
AA

2
00:02:15,045 --> 00:02:17,045
BB

3
00:02:44,908 --> 00:02:47,744
CC

4
00:04:21,371 --> 00:04:24,671
DD
    

並選擇保留時段:


00:02:15,000 - 00:02:40,000
00:04:20,000 - 00:04:35,000
    

處理後的新字幕文件將為:


1
00:00:00,045 --> 00:00:02,045
BB

2
00:00:26,371 --> 00:00:29,671
DD
    

常見問題與解答

問:如何確保時間區間的格式正確?

答:請按照「HH:MM:SS,mmm - HH:MM:SS,mmm」的格式輸入時間區間,例如「00:02:15,000 - 00:02:40,000」。確保每個時間區間在單獨一行,且開始時間小於結束時間。

問:腳本不支援某些語言的字幕,該怎麼辦?

答:本腳本已支援中文、英文及日文字幕。如果遇到其他語言或特殊字符出現亂碼,請確保原始字幕文件使用UTF-8編碼,並在腳本中指定相應編碼格式。

問:處理後的字幕時間碼不準確,應如何調整?

答:請檢查輸入的保留時間區間是否重疊或有錯誤,並確保時間格式正確。若問題依舊存在,您可以調整腳本中的時間轉換方法,或檢查字幕文件的時間碼是否有誤。


參考資料

結論

本指南提供了一個全面且高效的Python腳本,結合Tkinter GUI,滿足用戶對字幕時段保留的需求。通過詳細的步驟說明和完整的程式碼解析,即使是初學者也能輕鬆上手,快速完成字幕的過濾與重新賦予時間碼。無論您是希望提升影片的專業性,還是需要便捷的字幕處理工具,這個腳本都能為您提供有力的支持。


Last updated January 19, 2025

AI-assisted research. Sources, methodology and corrections · Source-checked guides and tools · Explore published answers

Ask Ithy AI