
在處理教學影片、訪談、Podcast 或逐字稿影片時,常見的需求是:只保留「有字幕的內容」,自動剪掉中間的停頓、空白或無聲段落。如果手動在剪輯軟體中一段段對齊字幕,不但耗時,也容易出錯。
這篇文章會帶你使用圖形化的設定介面,讓你不必記憶複雜的指令,即可透過滑鼠點擊完成剪掉影片空白段落。
介紹 ffmpeg 在聲音處理的幾個指令,還有對聲音進行音量正規化會踩到什麼坑,都不用去背指令,等需要用再問 AI 就可以了。
了解有意義聲音與聲響的差異。
使用情境
這支腳本特別適合以下場景:
- 教學影片只保留講話段落
- 訪談或會議影片去除空白等待時間
- Podcast 錄影自動裁切發言片段
- AI 轉錄後,直接用字幕反推影片剪輯
你只需要:
- 一個影片檔(mp4 / mkv / mov…)
環境與套件需求
在開始之前,請確認以下環境已準備好:
- Python 3.8+
- 系統已安裝
ffmpeg,openai-whisper - Python 套件:
pip install ffmpeg-python pysrt openai-whisper
其中:
- ffmpeg-python:FFmpeg 的 Python 封裝,用來描述影片處理流程
- pysrt:專門解析
.srt字幕檔的工具 - whisper:聲音轉
.srt字幕檔的工具
腳本整體流程說明
video_cutter.py 程式的邏輯可以拆成 6 個步驟:
- 讀取並檢查影片與字幕檔是否存在
- 解析 SRT,取得每一段字幕的開始與結束時間
- 對影片與音訊分別做
trim - 重設時間軸(PTS),避免剪接錯位
- 將所有片段依序 concat
- 輸出成一支新的影片檔
來源檔案轉換為單聲道 MP3 (16kHz), 是透過 ffmpeg 指令
ffmpeg -i input.mp3 -ar 16000 -ac 1 -ab 16k output.mp3
生成字幕, 是透過 whisper 指令
whisper audio.mp3 --language=zh --device=cpu --model=turbo
安裝的教學, 參考: https://max-everyday.com/2025/12/whisper-python/
指令的使用方式
python video_cutter.py input.mp4
video_cutter.py 實作的細節
不知道也沒差,建議直接略過這個區塊
1️⃣ 合併過短字幕
- 設定最小片段長度(例如 0.4 秒)
- 若某段太短,嘗試與前一段合併
- 合併條件:時間間隔不超過指定閾值(例如 0.3 秒)
2️⃣ 前後 padding
- 對每段字幕加上前後緩衝(例如 ±0.15 秒)
- 自動 clamp 在 0 與影片總長度之間
- padding 在「合併後」才套用,避免重疊錯亂
3️⃣ 靜音偵測(輔助條件)
- 使用 ffmpeg 的
silencedetect - 先跑一次分析音訊,取得靜音區段
- 若字幕區間完全落在靜音內 → 捨棄
- 若只部分靜音 → 保留(字幕仍有意義)
使用「靜音偵測」就不需要輸入 srt 字幕檔了嗎?
這是一個非常關鍵、而且問得很精準的問題。結論先給你,再把背後的設計邏輯一次說清楚。
結論一句話:
只用「靜音偵測」可以剪影片,但「不能等價取代 SRT(Whisper)」;兩者的角色本質不同。
先把兩者在「影片自動切割」中的定位講清楚。
Whisper 產生的 SRT,本質上是在回答一個問題:
「這段時間,人類在說『有意義的話』嗎?」
而靜音偵測(silencedetect),回答的是另一個問題:
「這段時間,聲音能量是否低於某個門檻?」
這兩件事不是同一件事,也不互為子集。
一、只用靜音偵測,不用 SRT,會發生什麼事?
你可以完全不用 SRT,只靠靜音來切,例如:
- 偵測所有非靜音區間
- 每段非靜音就是一個剪輯段
這在「技術上」完全可行,而且程式還更簡單。
但實際效果會有幾個不可避免的問題:
- 會保留大量「沒有語意價值」的聲音
例如:- 呼吸聲
- 笑一下
- 背景音樂
- 咳嗽
- 嘆氣、嗯、啊
- 無法判斷「語句邊界」
一句話中間短暫停頓 0.2 秒,
靜音偵測可能直接把它切成兩段。 - 對內容型影片不友善
像是:- 教學影片
- 訪談
- Podcast
- YouTube talking head
不是「有聲音就留」。
因此:
只靠靜音偵測,剪出來的是「聲音片段」,不是「語意片段」。
二、那是否代表一定需要 SRT(Whisper)?
這要看你的「剪輯目標」。
可以這樣判斷:
如果你的目標是這種 → 可以不需要 SRT
- 去掉完全沒聲音的空白
- 快速裁掉長時間靜默
- 監控錄音品質
- Podcast 粗剪(人工後製)
如果你的目標是這種 → SRT 幾乎是必要的
- 依照「一句話」切段
- 產生短影音(Reels / Shorts)
- 自動章節
- 後續做摘要、關鍵句擷取、翻譯
你目前描述的用途是:
SRT 主要是透過 whisper 來產生,目的是利用 SRT 字幕自動切割影片
這個用途,本質上就是 語意導向切割,
所以 SRT 不是多餘的,而是核心訊號來源。
三、正確的工程思路:不是「二選一」,而是「主從關係」
在成熟的系統裡,設計通常是這樣:
Whisper / SRT:主判斷(語意)
靜音偵測:輔助過濾(聲學)
實務上最穩定的策略是:
- 用 SRT 決定「候選剪輯區間」
- 用靜音偵測做「品質檢查」
- 字幕區間內如果 90% 都是靜音 → 丟棄
- 字幕前後有長靜音 → 裁掉
- 最後再補 padding,讓語音自然進出
也就是你目前優化方向中,最合理的一條路。
四、什麼情況下「可以完全不要 SRT」?
只有在以下情境,我會建議你拿掉 SRT:
- 你已經不在乎「說了什麼」
- 你只想保留「有聲音的地方」
- 或你後面還會人工看一遍再修
例如:
- 監控錄影
- 課堂錄音粗剪
- 音檔清理工具
一旦你的目標是「自動產出可直接發布的內容」,
SRT(Whisper)就不是 optional,而是語意層的 ground truth。
ffmpeg 增加影片的音量
要讓音量達到最大但不破音,最保險的做法是先進行音量標準化。這通常需要跑兩次指令,或者用一個比較聰明的過濾器。
使用簡單的標準化
這個指令會自動搜尋音軌中的最高點,並將其提升到 0dB,也就是不失真的最大極限。這對於聲音太小的檔案非常有用。
ffmpeg -i input.mp4 -af "loudnorm=I=-16:TP=-1.5:LRA=11" -c:v copy output.mp4
兩步驟自動偵測
如果你想更精確地提升,可以先執行 volumedetect 找出最大增益。這個指令不會輸出新檔案,只是幫你計算數據。
ffmpeg -i input.mp4 -af volumedetect -f null /dev/null
在 Windows 中,我們把空輸出指向 NUL。
ffmpeg -i input.mp4 -af volumedetect -f null NUL
執行後在輸出的文字裡找 max_volume。如果顯示為 -6.0dB,代表你還有 6dB 的增加空間。接著再手動輸入增加的數值。
ffmpeg -i input.mp4 -af "volume=6dB" -c:v copy output.mp4
分析偵測結果
你的 max_volume 是 -1.2 dB。這代表這段影片中最大聲的地方,距離數位音訊的極限(0 dB)只剩下 1.2 dB 的空間。如果你的目標是單純增加音量且不想讓聲音破掉,你最多只能增加 1.2 dB。
執行調整指令
如果你確定要調到極限(也就是讓最大聲的地方剛好達到 0 dB),請在 Windows CMD 執行以下指令:
ffmpeg -i input.mp4 -af "volume=1.2dB" -c:v copy output.mp4
關於音量的建議
雖然最大值接近極限,但你的 mean_volume(平均音量)只有 -25.0 dB。這表示這段影片大部分時間聲音其實很小,只有少數幾個地方突然很大聲。
如果你覺得聽起來還是太小聲,單純調高 volume 可能會導致大聲的地方破音。這種情況建議改用前面提到的 loudnorm 指令,它會壓縮大聲的部分並提升小聲的部分,讓整體的聽感變大。
ffmpeg -i input.mp4 -af "loudnorm" -c:v copy output_norm.mp4
為什麼直接使用 loudnorm 過濾器處理過的檔案, 再使用偵測可增加的音量空間, max_volumn 反而下降?
這是一個很專業的觀察。直接使用 loudnorm 後 max_volume 反而下降,主要是因為這個過濾器的工作邏輯與單純調整增益(Gain)完全不同。
動態範圍壓縮的影響
loudnorm 是一種智慧型的音量標準化工具。它不只是把聲音推大,還會同時檢查聲音的動態範圍。為了讓整體聽感達到目標的響度(預設通常是 -16 LUFS),它會壓縮聲音的高峰。當它偵測到原始音軌中某些瞬間的峰值太高時,為了符合整體的響度標準,它會主動把這些高峰壓低,導致你看到的 max_volume 數值從 -1.2 dB 往下降。
防止數位失真的保護機制
loudnorm 內建了一個參數叫作 TP(True Peak),預設值通常是 -2.0 dB。這是一個安全閥,目的是確保處理後的聲音在任何播放設備上都不會產生數位破音。因為你原本的 max_volume 是 -1.2 dB,已經比這個安全標準還要大聲,所以 loudnorm 會強制把它壓回到 -2.0 dB 左右或更低,這就是為什麼偵測結果數值會變小的原因。
響度與峰值的差異
在音訊處理中,大聲不代表峰值高。max_volume 只代表影片中最響的那一個瞬間,而 loudnorm 關注的是整段影片聽起來的平均感覺。雖然峰值下降了,但因為它把原本微弱的聲音補償上來了,實際聽起來的感覺反而會比原本更清晰、更大聲。
你的測試結果驗證
這證明了 loudnorm 正在正確執行它的任務:它放棄了極少數的最高點空間,換取了整段音軌更一致、更飽滿的聽感。如果你希望處理後的 max_volume 更接近 0 dB,可以在指令中手動加上 TP 參數:
ffmpeg -i input.mp4 -af "loudnorm=TP=-0.1" -c:v copy output.mp4
這樣雖然峰值會上升,但通常不建議這麼做,因為留一點預留空間(Headroom)對音質比較好。
產生 Echo 回音音效
ffmpeg 使用 aecho 濾鏡來製作回音。你需要設定輸入增益、輸出增益、延遲時間以及衰減比例。
ffmpeg -i input.mp4 -af "aecho=0.8:0.8:1000:0.5" -c:v copy output.mp4
這行指令的參數意義如下:
- 0.8:原始聲音的音量。
- 0.8:回音的音量。
- 1000:延遲時間(毫秒),1000 代表 1 秒。
- 0.5:每次回音衰減的比例。
調整 EQ 均衡器
如果你想調整高低音,最直覺的是使用 equalizer 濾鏡。你可以針對特定的頻率進行增益或衰減。
例如,如果你想提升 1000Hz 附近的聲音(讓人聲更清晰),增加 6 分貝:
ffmpeg -i input.mp4 -af "equalizer=f=1000:width_type=h:w=200:g=6" -c:v copy output.mp4
- f=1000:中心頻率。
- width_type=h:頻寬單位。
- w=200:影響的頻率範圍寬度。
- g=6:增益分貝數。
快速調整高低音 (Bass/Treble)
如果你不想設定複雜的 EQ,可以直接用 bass 或 treble 濾鏡。這對高中生理解音訊調整最簡單。
提升重低音:
ffmpeg -i input.mp4 -af "bass=g=10" -c:v copy output.mp4
提升高音:
ffmpeg -i input.mp4 -af "treble=g=8" -c:v copy output.mp4
多重濾鏡組合
你可以把音量調整、EQ 和回音全部串在一起使用,中間用逗號隔開即可。
ffmpeg -i input.mp4 -af "volume=1.2,bass=g=5,aecho=0.8:0.5:500:0.3" -c:v copy output.mp4
完整的人聲優化指令
這串指令包含了高通濾波、人聲強化和動態門檻去噪。
ffmpeg -i input.mp4 -af "highpass=f=80, lowpass=f=8000, afftdn=nr=10, equalizer=f=3000:width_type=h:w=200:g=3, loudnorm" -c:v copy output.mp4
濾鏡參數詳細解說
1. 高通與低通濾波 (highpass/lowpass)
highpass=f=80 會切斷 80Hz 以下的聲音。人聲通常不會低於這個頻率,但冷氣運轉或電流聲的低頻雜訊會被擋掉。lowpass=f=8000 則是過濾掉極高頻的刺耳雜音。
2. 智慧去噪 (afftdn)
afftdn 是 ffmpeg 內建強大的降噪工具。nr=10 代表降噪強度。如果你的背景嘶嘶聲很明顯,可以適度調高這個數值(建議在 10 到 20 之間),但調太高會讓人聲聽起來像在水底下說話。
3. 人聲頻段強化 (equalizer)
equalizer=f=3000:g=3 針對 3000Hz 左右進行微幅增益。這個頻段通常是人聲清晰度的關鍵,稍微拉高能讓講話聲更突出、更有磁性。
4. 終端響度標準化 (loudnorm)
最後放上 loudnorm 是為了確保優化後的聲音音量穩定,不會因為去噪過程讓音量忽大忽小。
進階去噪:使用動態閘門 (agate)
如果你的錄音環境有明顯的間歇性背景噪音(例如翻書聲或細微鍵盤聲),可以加入 agate 濾鏡。它會在沒人講話時自動把音量關到極小。
ffmpeg -i input.mp4 -af "agate=threshold=-30dB:ratio=2, highpass=f=80, afftdn, loudnorm" -c:v copy output.mp4
加入一點點空間感(Room Ambience)可以讓人聲聽起來更自然,不會像是在完全真空的密室裡講話。我們可以利用 aecho 來模擬微弱的牆面反射,讓 Podcast 更有專業錄音室的質感。
錄音室空間感指令
這組設定會加入極短的回音,聽覺上不會感覺到有明顯的「回聲」,而是覺得聲音變厚實了。
ffmpeg -i input.mp4 -af "highpass=f=80, afftdn=nr=12, aecho=0.8:0.3:40:0.2, loudnorm" -c:v copy output.mp4
參數調整重點
1. 空間感設定 (aecho)
aecho=0.8:0.3:40:0.2 這裡的核心在於 40 毫秒。這是一個非常短的時間,人耳聽不出延遲,只會覺得聲音多了一層包覆感。如果數字調到 500 以上,就會變成像在山洞說話的效果。
2. 去噪強度 (afftdn)
我把 nr 微調到了 12。這在去除 Podcast 背景底噪(如電腦風扇聲)非常有效。如果雜音還是很大,你可以嘗試把這個數值加到 15。
3. 低頻切除 (highpass)
這一步絕對不能省。Podcast 聽眾很多是用耳機收聽,切掉 80Hz 以下的雜訊,能大幅減少聽覺疲勞,讓人聲聽起來很乾淨。
檢查處理後的波形
處理完後,建議你再次使用 volumedetect 檢查。
ffmpeg -i output.mp4 -af volumedetect -f null NUL
你會發現 mean_volume(平均音量)應該會提升到 -16dB 附近,這正是目前國際 Podcast 平台的標準響度,聽眾在切換不同節目時,不需要一直手動調整手機音量。
套用 loudnorm, 開場的第一句話變的很小聲.
這通常是因為 loudnorm 預設是「單次掃描」(One-pass)模式。在這種模式下,ffmpeg 還沒分析完整段音訊,只能邊走邊猜。當開場的第一句話突然出現時,濾鏡為了保險起見會壓低音量,導致聽起來悶悶的。
解決開場音量過小的問題
要解決這個問題,最專業的做法是提供「預測數據」。你可以手動調整以下細部參數,或是改用兩次掃描模式。
1. 調整目標響度與峰值
你可以透過調整 I(目標響度)和 TP(真峰值)來讓整體聲音更響亮。
ffmpeg -i input.mp4 -af "loudnorm=I=-14:TP=-1.0:LRA=11" -c:v copy output.mp4
- I=-14:目標響度。數值越小(如 -12)聲音越大。Podcast 建議在 -16 到 -14 之間。
- TP=-1.0:允許的最高峰值。從預設的 -2.0 改成 -1.0 可以釋放更多音量空間。
2. 關閉線性限制 (measured)
如果你發現第一句話被壓得太厲害,可以嘗試強制設定 measured 參數。但更簡單的方法是調整 LRA(響度範圍)。
LRA=15:增加動態範圍。這會讓大聲與小聲的落差變大,有時候能減緩開場被強行壓低的感覺。
徹底解決方法:兩次掃描 (Two-pass)
這是大部份專業人士的做法。第一次先讓 ffmpeg 記住整段影片的音量特徵,第二次再根據這些數據進行精確調整。這樣濾鏡就不會在開場時「反應過度」。
在 Windows 上手動做兩次掃描比較麻煩,但有一個作弊的方法,就是調大內建的緩衝區。
增加預測緩衝
雖然 ffmpeg 的 loudnorm 主要靠演算法,但你可以嘗試在人聲處理鏈中,先放一個 compand(壓縮器)來預處理,或是直接改用 speechnorm。
如果你堅持用 loudnorm 且不想跑兩次指令,可以試試看這個組合,這對開場壓抑會有改善:
ffmpeg -i input.mp4 -af "loudnorm=I=-16:TP=-1.5:LRA=11:measured_I=-25.0:measured_TP=-1.2:measured_LRA=7.0:measured_thresh=-35.0" -c:v copy output.mp4
註:上面的
measured數值是我根據你之前提供的偵測數據填入的。手動餵入這些偵測到的數據,能讓loudnorm在開場時就知道該怎麼處理。
另一個選擇:speechnorm
如果 loudnorm 讓 Podcast 開場聽起來還是很不自然,我強烈建議換成 speechnorm。它是專門為語音設計的,能非常平滑地調整每一句話的音量。
ffmpeg -i input.mp4 -af "speechnorm=e=4:p=0.9" -c:v copy output.mp4
你想試試看用 speechnorm 處理的效果嗎?它通常比 loudnorm 更適合解決「第一句話變小聲」的問題。
延伸優化方向
- 合併過短字幕(避免 0.1 秒碎片)
- 自動補前後緩衝(padding)
- 加入靜音偵測作為輔助條件
- 封裝成 CLI 工具或 Web API
總結
透過字幕作為「真實內容的時間索引」,可以讓影片剪輯變得高度自動化、可重現、可批次處理。這支腳本雖然精簡,但已涵蓋 FFmpeg 在實務上最容易踩雷的幾個重點(PTS、音畫同步、concat)。
只要你有字幕,就能讓影片自己「剪好給你」。