今天我要跟各位分享一個有趣的小專案 - 使用 Python 和 FFmpeg 製作的簡易影片轉換器。這個應用程式不僅實用,還能讓我們學習到如何結合 Python 的圖形使用者介面(GUI)與強大的影片處理工具。

專案概述


這個影片轉換器具有以下特點:

  1. 簡潔的圖形使用者介面
  2. 可以選擇輸入檔案和指定輸出檔案
  3. 使用 FFmpeg 進行影片轉換
  4. 顯示轉換狀態和錯誤訊息

使用的技術

  • Python:程式的主要語言
  • tkinter:Python 的標準 GUI 函式庫
  • ffmpeg-python:FFmpeg 的 Python 綁定,用於影片處理(安裝:pip install ffmpeg-python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# 導入必要的模組
import ffmpeg # 用於處理影片轉換
import threading # 用於背景執行轉換,避免 GUI 凍結
import tkinter as tk # 用於建立圖形使用者介面 (GUI)
from tkinter import filedialog # 用於檔案選擇

# 定義選擇檔案的函數
def select_file():
# 開啟檔案選擇對話框
filename = filedialog.askopenfilename()
# 清除輸入框的現有內容
input_entry.delete(0, tk.END)
# 將選擇的檔案路徑插入輸入框
input_entry.insert(0, filename)

# 實際執行轉換的函數(在背景執行緒中執行)
def _run_conversion(input_file, output_file):
try:
# 讀取輸入檔案
stream = ffmpeg.input(input_file)
# 設置輸出參數(這裡使用預設參數)
stream = ffmpeg.output(stream, output_file)
# 執行 FFmpeg 指令;capture_stderr=True 讓例外物件帶有實際錯誤內容
ffmpeg.run(stream, capture_stdout=True, capture_stderr=True)
# 回主執行緒更新狀態標籤
root.after(0, lambda: status_label.config(text="轉換成功!"))
except ffmpeg.Error as e:
# e.stderr 是 bytes,需要 decode 才能取得可讀的錯誤訊息
error_msg = e.stderr.decode() if e.stderr else str(e)
root.after(0, lambda: status_label.config(text="轉換失敗。錯誤: " + error_msg))

# 定義影片轉換的函數
def convert_video():
# 取得輸入和輸出檔案路徑
input_file = input_entry.get()
output_file = output_entry.get()
if not input_file or not output_file:
status_label.config(text="請先填寫輸入和輸出檔案路徑。")
return
status_label.config(text="轉換中...")
# 放到背景執行緒執行,避免轉換期間 GUI 凍結無回應
t = threading.Thread(target=_run_conversion, args=(input_file, output_file), daemon=True)
t.start()

# 建立主視窗
root = tk.Tk()
root.title("影片轉換器 (使用 ffmpeg-python)")

# 建立並放置控制項
# 輸入檔案部分
tk.Label(root, text="輸入檔案:").grid(row=0, column=0, sticky="e")
input_entry = tk.Entry(root, width=50)
input_entry.grid(row=0, column=1)
tk.Button(root, text="瀏覽", command=select_file).grid(row=0, column=2)

# 輸出檔案部分
tk.Label(root, text="輸出檔案:").grid(row=1, column=0, sticky="e")
output_entry = tk.Entry(root, width=50)
output_entry.grid(row=1, column=1)

# 轉換按鈕
convert_button = tk.Button(root, text="轉換", command=convert_video)
convert_button.grid(row=2, column=1)

# 狀態標籤
status_label = tk.Label(root, text="")
status_label.grid(row=3, column=1)

# 啟動主循環
root.mainloop()

程式碼解析

讓我們來看看這個應用程式的主要組成部分:

  1. 導入必要模組:
    我們導入了 ffmpeg、tkinter 以及 filedialog。這些模組分別用於影片處理、建立 GUI 和處理檔案選擇。
  2. 檔案選擇功能:
    select_file() 函數使用 filedialog.askopenfilename() 來開啟檔案選擇對話框,讓使用者可以輕鬆選擇要轉換的影片檔案。
  3. 影片轉換功能:
    convert_video() 是按鈕的回呼函數,負責做空值防呆、立即顯示「轉換中...」並把實際工作交給背景執行緒。真正的轉換邏輯在 _run_conversion() 中:呼叫 ffmpeg.run() 時傳入 capture_stderr=True,確保轉換失敗時能透過 e.stderr.decode() 取得 FFmpeg 的實際錯誤輸出,而不只是一句通用的 "ffmpeg error"。完成後用 root.after(0, ...) 回到主執行緒更新 UI,這是 tkinter 的線程安全做法。
  4. 建立 GUI:
    我們使用 tkinter 建立了一個簡單的視窗,包含輸入檔案和輸出檔案的輸入框、瀏覽按鈕、轉換按鈕和狀態標籤。

如何使用

  1. 啟動應用程式後,你會看到一個簡單的視窗。
  2. 點擊「瀏覽」按鈕選擇要轉換的影片檔案。
  3. 在「輸出檔案」欄位中輸入想要的輸出檔案名稱(記得加上副檔名)。
  4. 點擊「轉換」按鈕開始轉換過程。
  5. 轉換完成後,狀態標籤會顯示成功或失敗的訊息。

注意事項

請確保你的系統上已安裝 FFmpeg。
這個程式使用了 FFmpeg 的預設參數進行轉換。如果你需要更多自訂選項,可以修改 _run_conversion() 函數中的 ffmpeg.output() 部分。
轉換時 GUI 會顯示「轉換中...」而不是凍結,這是因為轉換跑在背景執行緒;如果要加上取消按鈕或進度條,可以在此基礎上擴展。

結語

這個影片轉換器把 FFmpeg 的指令列能力包進 tkinter GUI,輸入路徑、按轉換、等完成。輸出檔案欄位目前需要手動輸入完整路徑(含副檔名),若想加上「另存新檔」對話框,可參考 filedialog.asksaveasfilename() 自行擴充。