在處理視頻字幕時,經常需要根據特定需求保留或刪除某些時間段的字幕內容。本文將詳細介紹如何使用Python編寫一個腳本,實現讀取.srt字幕檔案,讓用戶選擇保留的時間段,並生成新的.srt檔案。此腳本支持中文、英文及日文字幕,適用於各種多語言環境。
在開始之前,請確保已安裝Python 3.6以上版本。接下來,安裝處理字幕的pysrt庫:
pip install pysrt
如需處理檔案編碼,還需要安裝Chardet庫:
pip install chardet
以下是完整的Python腳本,實現讀取.srt檔案,讓用戶選擇保留的時間段,並生成新的.srt檔案:
import pysrt
from datetime import datetime, timedelta
import os
import chardet
def detect_encoding(file_path):
"""檢測檔案編碼"""
with open(file_path, 'rb') as f:
result = chardet.detect(f.read())
return result['encoding']
def parse_time_input(time_str):
"""
將用戶輸入的時間字串轉換為timedelta物件
支持格式:HH:MM:SS,mmm 或 HH:MM:SS
"""
try:
if ',' in time_str:
time_part, ms_part = time_str.split(',')
dt = datetime.strptime(time_part, "%H:%M:%S")
return timedelta(hours=dt.hour, minutes=dt.minute, seconds=dt.second, milliseconds=int(ms_part))
else:
dt = datetime.strptime(time_str, "%H:%M:%S")
return timedelta(hours=dt.hour, minutes=dt.minute, seconds=dt.second)
except ValueError:
return None
def get_time_ranges():
"""獲取使用者想要保留的時間範圍"""
ranges = []
print("\n請輸入要保留的時間範圍 (格式: HH:MM:SS,mmm - HH:MM:SS,mmm)")
print("例如:00:02:15,000 - 00:02:40,000")
print("輸入 'done' 完成輸入\n")
while True:
time_range = input("請輸入時間範圍或 'done': ").strip()
if time_range.lower() == 'done':
break
if '-' not in time_range:
print("格式錯誤,請使用 '開始時間 - 結束時間' 格式。")
continue
start_str, end_str = map(str.strip, time_range.split('-', 1))
start_td = parse_time_input(start_str)
end_td = parse_time_input(end_str)
if start_td is None or end_td is None:
print("時間格式錯誤,請重新輸入。")
continue
if start_td >= end_td:
print("開始時間必須早於結束時間。")
continue
ranges.append((start_td, end_td))
return ranges
def is_subtitle_in_ranges(sub, ranges):
"""檢查字幕是否在保留範圍內"""
sub_start = timedelta(hours=sub.start.hours, minutes=sub.start.minutes, seconds=sub.start.seconds, milliseconds=sub.start.milliseconds)
sub_end = timedelta(hours=sub.end.hours, minutes=sub.end.minutes, seconds=sub.end.seconds, milliseconds=sub.end.milliseconds)
for start, end in ranges:
# 若字幕的任何部分在範圍內,則保留
if sub_start < end and sub_end > start:
return True
return False
def process_subtitle_file():
"""主函數:處理字幕檔案"""
input_file = input("請輸入.srt檔案路徑: ").strip()
if not os.path.isfile(input_file):
print("檔案不存在,請確認路徑後重試。")
return
encoding = detect_encoding(input_file)
try:
subs = pysrt.open(input_file, encoding=encoding)
except Exception as e:
print(f"無法讀取字幕檔案:{e}")
return
print("\n檔案中共包含 {0} 條字幕。".format(len(subs)))
ranges = get_time_ranges()
if not ranges:
print("未輸入任何保留的時間範圍,無需處理。")
return
filtered_subs = pysrt.SubRipFile()
for sub in subs:
if is_subtitle_in_ranges(sub, ranges):
filtered_subs.append(sub)
if not filtered_subs:
print("未找到符合保留範圍的字幕。")
return
# 重新編排字幕編號
for idx, sub in enumerate(filtered_subs, start=1):
sub.index = idx
output_file = os.path.splitext(input_file)[0] + "_filtered.srt"
try:
filtered_subs.save(output_file, encoding='utf-8')
print(f"成功生成新的字幕檔案:{output_file}")
except Exception as e:
print(f"無法保存字幕檔案:{e}")
if __name__ == "__main__":
process_subtitle_file()
這個腳本的主要功能包括:
使用chardet庫來自動檢測輸入檔案的編碼方式,確保pysrt能夠正確讀取字幕內容。
def detect_encoding(file_path):
"""檢測檔案編碼"""
with open(file_path, 'rb') as f:
result = chardet.detect(f.read())
return result['encoding']
將用戶輸入的時間字串轉換為timedelta物件,以便後續進行時間比較。
def parse_time_input(time_str):
"""
將用戶輸入的時間字串轉換為timedelta物件
支持格式:HH:MM:SS,mmm 或 HH:MM:SS
"""
try:
if ',' in time_str:
time_part, ms_part = time_str.split(',')
dt = datetime.strptime(time_part, "%H:%M:%S")
return timedelta(hours=dt.hour, minutes=dt.minute, seconds=dt.second, milliseconds=int(ms_part))
else:
dt = datetime.strptime(time_str, "%H:%M:%S")
return timedelta(hours=dt.hour, minutes=dt.minute, seconds=dt.second)
except ValueError:
return None
通過互動式輸入,讓用戶可以輸入多個想要保留的時間範圍,並存儲在列表中。
def get_time_ranges():
"""獲取使用者想要保留的時間範圍"""
ranges = []
print("\n請輸入要保留的時間範圍 (格式: HH:MM:SS,mmm - HH:MM:SS,mmm)")
print("例如:00:02:15,000 - 00:02:40,000")
print("輸入 'done' 完成輸入\n")
while True:
time_range = input("請輸入時間範圍或 'done': ").strip()
if time_range.lower() == 'done':
break
if '-' not in time_range:
print("格式錯誤,請使用 '開始時間 - 結束時間' 格式。")
continue
start_str, end_str = map(str.strip, time_range.split('-', 1))
start_td = parse_time_input(start_str)
end_td = parse_time_input(end_str)
if start_td is None or end_td is None:
print("時間格式錯誤,請重新輸入。")
continue
if start_td >= end_td:
print("開始時間必須早於結束時間。")
continue
ranges.append((start_td, end_td))
return ranges
對於每一條字幕,檢查其開始或結束時間是否在任何一個保留的時間範圍內。
def is_subtitle_in_ranges(sub, ranges):
"""檢查字幕是否在保留範圍內"""
sub_start = timedelta(hours=sub.start.hours, minutes=sub.start.minutes, seconds=sub.start.seconds, milliseconds=sub.start.milliseconds)
sub_end = timedelta(hours=sub.end.hours, minutes=sub.end.minutes, seconds=sub.end.seconds, milliseconds=sub.end.milliseconds)
for start, end in ranges:
# 若字幕的任何部分在範圍內,則保留
if sub_start < end and sub_end > start:
return True
return False
根據用戶輸入的時間範圍,篩選出符合條件的字幕,並保存為新的.srt檔案。
def process_subtitle_file():
"""主函數:處理字幕檔案"""
input_file = input("請輸入.srt檔案路徑: ").strip()
if not os.path.isfile(input_file):
print("檔案不存在,請確認路徑後重試。")
return
encoding = detect_encoding(input_file)
try:
subs = pysrt.open(input_file, encoding=encoding)
except Exception as e:
print(f"無法讀取字幕檔案:{e}")
return
print("\n檔案中共包含 {0} 條字幕。".format(len(subs)))
ranges = get_time_ranges()
if not ranges:
print("未輸入任何保留的時間範圍,無需處理。")
return
filtered_subs = pysrt.SubRipFile()
for sub in subs:
if is_subtitle_in_ranges(sub, ranges):
filtered_subs.append(sub)
if not filtered_subs:
print("未找到符合保留範圍的字幕。")
return
# 重新編排字幕編號
for idx, sub in enumerate(filtered_subs, start=1):
sub.index = idx
output_file = os.path.splitext(input_file)[0] + "_filtered.srt"
try:
filtered_subs.save(output_file, encoding='utf-8')
print(f"成功生成新的字幕檔案:{output_file}")
except Exception as e:
print(f"無法保存字幕檔案:{e}")
在命令行或終端中導航到腳本所在目錄,並運行:
python your_script_name.py
當提示輸入.srt檔案路徑時,輸入字幕檔案的完整路徑,例如:
請輸入.srt檔案路徑: /path/to/your/subtitle.srt
根據提示,輸入要保留的時間段,可以輸入多個範圍。例如:
請輸入時間範圍或 'done': 00:02:15,000 - 00:02:40,000
請輸入時間範圍或 'done': 00:05:00,000 - 00:05:30,000
請輸入時間範圍或 'done': done
輸入完成後,腳本將自動過濾並保留指定時間段內的字幕。
腳本將生成一個新的.srt檔案,檔名為原檔名加上「_filtered」。例如:「subtitle_filtered.srt」。
在測試腳本前,準備一個包含多條字幕的.srt檔案,並確保檔案編碼為UTF-8、CP950等以支持中文、英文或日文字幕。
輸入格式需嚴格遵守,以下為範例:
開始時間:00:01:00,000
結束時間:00:02:00,000
這將保留從1分鐘到2分鐘之間的字幕內容。
若需處理多個.srt檔案,可將腳本稍作修改,批量處理指定目錄下的所有字幕檔。
import glob
def batch_process(directory, ranges):
"""批量處理指定目錄下的所有.srt檔案"""
srt_files = glob.glob(os.path.join(directory, "*.srt"))
for file in srt_files:
try:
subs = pysrt.open(file, encoding=detect_encoding(file))
filtered_subs = pysrt.SubRipFile()
for sub in subs:
if is_subtitle_in_ranges(sub, ranges):
filtered_subs.append(sub)
if not filtered_subs:
print(f"{file} 無符合範圍的字幕,跳過。")
continue
for idx, sub in enumerate(filtered_subs, start=1):
sub.index = idx
output_file = os.path.splitext(file)[0] + "_filtered.srt"
filtered_subs.save(output_file, encoding='utf-8')
print(f"已生成:{output_file}")
except Exception as e:
print(f"處理 {file} 時出錯:{e}")
為了提升用戶體驗,可以使用Tkinter等庫為腳本添加圖形用戶界面(GUI)。這樣,用戶無需在命令行中操作,只需通過點擊和輸入即可完成字幕的過濾。
import tkinter as tk
from tkinter import filedialog, messagebox
def select_file():
file_path = filedialog.askopenfilename(filetypes=[("SRT files", "*.srt")])
entry_file.delete(0, tk.END)
entry_file.insert(0, file_path)
def start_processing():
file_path = entry_file.get()
if not file_path:
messagebox.showerror("錯誤", "請選擇.srt檔案。")
return
# 此處調用process_subtitle_file的相關函數並傳遞參數
# 需要進一步實現GUI的時間範圍輸入
messagebox.showinfo("完成", "字幕過濾完成。")
root = tk.Tk()
root.title("字幕過濾器")
tk.Label(root, text="選擇.srt檔案:").grid(row=0, column=0, padx=10, pady=10)
entry_file = tk.Entry(root, width=50)
entry_file.grid(row=0, column=1, padx=10, pady=10)
tk.Button(root, text="瀏覽", command=select_file).grid(row=0, column=2, padx=10, pady=10)
tk.Button(root, text="開始過濾", command=start_processing).grid(row=1, column=1, pady=20)
root.mainloop()
A1:請確保.srt檔案存在且路徑正確。此外,確保檔案編碼為UTF-8或CP950,如有其他編碼,請相應調整。
A2:請嚴格按照「HH:MM:SS,mmm - HH:MM:SS,mmm」格式輸入。例如:「00:02:15,000 - 00:02:40,000」。確保使用逗號分隔秒和毫秒部分。
A3:這表示沒有任何一條字幕位於您指定的保留範圍內。請檢查您的時間範圍是否正確,並確保範圍內確實有字幕。
通過本文提供的詳細Python腳本,您可以輕鬆地過濾.srt字幕檔案中的特定時間段,保留所需的字幕內容。腳本不僅支持多種語言,還具有良好的擴展性,適用於各種不同的使用場景。無論是個人視頻編輯還是專業字幕處理,此腳本都能提供極大的便利。
確保字幕的時間格式嚴格遵循.srt標準格式,即「HH:MM:SS,mmm」。任何偏離此格式的時間都可能導致解析失敗。
這可能是由於檔案編碼問題或字幕檔案本身存在問題。使用chardet庫檢測並指定正確的編碼,或檢查字幕檔案是否完整和正確。
請檢查以下幾點:
利用自然語言處理(NLP)技術,根據字幕內容自動識別並選擇需要保留的時間範圍。例如,保留特定主題或關鍵詞相關的字幕。
拓展腳本功能,支持其他字幕格式如.ass、vtt等,提升其通用性和適用範圍。
通過添加圖形用戶界面(GUI),使操作更加直觀,特別適合不熟悉命令行的用戶。
掌握如何使用Python處理字幕檔案,特別是過濾指定時間段的字幕,是視頻編輯和多媒體內容製作中的一項重要技能。希望本文提供的腳本和詳細解析能夠幫助您高效地完成這一任務,提升工作效率。