ffmpeg常用功能備忘

下載 ffmpeg:https://www.gyan.dev/ffmpeg/builds/

安裝方法:

  • 把解壓後的ffmpeg目錄,貼到C:\Program Files中,複製包含ffmpeg.exe的資料夾路徑,例如:C:\Program Files\ffmpeg\bin。 接著,設定\系統\系統資訊\進階系統設定,進入「系統內容」視窗後,點擊「環境變數」鈕扣。 在系統變數找到「path」,點選「編輯\新建」,把之前複製的bin路徑貼上,最好把它移到最上方,然後點選「確定」來儲存設定。
  • 在cmd中,用ffmpeg -version來確認安裝成功,用where ffmpeg來確定安裝位置。

使用方法:

  • 如已安裝,直接在cmd中運行指令
  • 如未安裝,只是下載解壓:
    • 把圖片、音樂、視頻等要處理的檔案和 ffmpeg.exe 、ffprobe.exe 放在同一個資料夾
    • 在該資料夾按住 Shift + 右鍵 → 選擇「在此處開啟PowerShell視窗」或「命令提示字元」
    • 輸入指令(把檔名改成你的)
  • 基本語法結構:
    • 官方說明:「ffmpeg -h
    • FFmpeg 指令列的基本格式為:ffmpeg [全域參數] {[輸入檔案參數] -i 輸入檔案位址}… {[輸出檔案參數] 輸出檔案位址}…
    • 順序很重要,但很容易記住:全域選項、輸入和輸出。另外,輸入輸出選項會先於輸入輸出規格。
    • 全域參數會影響整個程式執行。例如「-loglevel」會設定日誌等級;想看即時進度可以加「-progress」 或直接看預設輸出;FFmpeg 擁有極強的容錯機制,遇到損毀太嚴重導致 FFmpeg 直接中斷,可在第一個 -i 前面加上 -err_detect ignore_err 強制跳過錯誤繼續輸出;「\」 換行符連接多行
    • 輸入檔案參數跟隨「-i」來指定輸入來源屬性,例如「-ss」來設定輸入檔起始時間;
    • 輸出檔參數決定輸出結果,例如 「-c:v」 複製視訊編碼,「-c:a」複製音訊編碼, 「-b:v」 控制視頻位元速率。加「-c copy 」可以不重新編碼,速度極快、無損。加「-y」 可以直接覆蓋輸出檔。
    • 舉個例子:將一個 MP4 視訊轉換為 AVI 格式,同時降低視頻碼率,命令如下:
      ffmpeg -i 輸入.mp4 -b:v 500k -c:v libx264 輸出.avi
      • 此命令中,「-i 輸入.mp4」 是指定輸入檔,「-b:v 500k」是把視頻位元速率設為 500k,「-c:v libx264」是選用 libx264 編碼器進行視頻編碼,最終輸出為「輸出.avi」。
    • 多行書寫:當命令參數眾多時,為增強可讀性,可寫成多行形式:
      ffmpeg \-y \-c:a libfdk_aac -c:v libx264 \-i 輸入.mp4 \-c:v libvpx-vp9 -c:a libvorbis \輸出.webm
      • ➔這裡,「\」分行符號連接多行,全域參數 「-y」 居首,表示即使輸出存在,也要覆寫。接著是輸入檔參數,最後是輸出檔參數與輸出檔案名,邏輯清晰,便於理解與修改。
    • 換行寫更清晰:
    • ffmpeg -y \
    • -ss 20 -t 60 -i bbb_sunflower_1080p_60fps_normal.mp4 \
    • -i train.jpg \ -ss 4 -i voice_recording.wav \
    • -filter_complex "[0:v]hue=h=80:s=1[main];1:v]crop=w=382:h=304:x=289:y=227[train]; [main][train]overlay=x=200:y=200,vignette=PI/4; [2:a]volume=1.5,aecho=0.8:0.9:100:0.3[speech]; [0:a][speech]amix=duration=shortest,asplit[audio1][audio2]" \
    • -map '' -map '[audio1]' -metadata title="Editor's cut" bbb_edited.mp4 \
    • -map '[audio2]' bbb_edited_audio_only.wav
  • 高頻參數詳解:
    • 「-c」是編碼器「指揮官」,如「-c:v」聚焦視頻編碼,「-c:a」掌管音訊編碼,「-c copy」則開啟「極速通道」,直接複製流而不重新編碼,能在格式轉換時保留原始品質並大幅提速,像無損轉換 MKV 到 MP4 時就常用到。
    • 「-i」是輸入檔 「指引牌」,精準定位輸入源,若處理多個輸入檔,多次使用 「-i」可依次指定。
    • 「-preset」是視頻品質 「調控器」,從「ultrafast」到「veryslow」,速度與品質逆向而行,追求快速出片可選「ultrafast」,看重畫質精細就得耐住性子選 「veryslow」。

範例:(揉雜了不同版本的ffmpeg,請小心試錯)

1. 格式轉換

ffmpeg -i 輸入.mp4 輸出.mkv

ffmpeg -i 輸入.mov -c:v libx264 -c:a aac 輸出.mp4

ffmpeg -i 輸入.mov -c:v libx264 -preset fast -crf 32 -c:a aac 輸出.mp4

ffmpeg -i 輸入.qsv -c:v libx264 -c:a aac -crf 23 輸出.mp4

ffmpeg -i 輸入.wav -b:a 320k 輸出_320k.mp3

ffmpeg -i 輸入.wav -ar 44100 輸出_44100khz.mp3

ffmpeg -i 輸入.wav -ac 2 -ar 44100 -b:a 320k 輸出_hqfull.mp3

➔ 「-c:v libx264」 指定視訊轉碼器為 libx264,它廣泛用於高品質 H.264 視頻編碼;
「-preset」用來控制「編碼速度 vs 壓縮效率」的平衡,有「ultrafast」「superfast」「faster」「fast」「medium」「slow」「slower」「veryslow」;
「-c:a aac」 將音訊編碼器設為 AAC,在音訊壓縮與品質平衡上表現出色;
「-crf 23」 中的 CRF(Constant Rate Factor)值控制畫質(0–51,數字越小畫質越好,一般建議 18–28,預設 23);
-b:a 320k」音訊指定你預期從編解碼器輸出的目標位元率;
-ar 44100」音訊指定取樣率以確保品質或較低的輸出檔案大小;
-ac 1/2/6」音訊-ac 1:用於單聲道,-ac 2:立體聲,-ac 6:用於 5.1,用於指定產出高品質成果。

2. 壓縮影片(減小體積)

常用高品質壓縮

ffmpeg -i 輸入.mp4 -c:v libx264 -crf 23 -preset medium -c:a aac -b:a 128k 輸出.mp4

更小體積(畫質稍降)

ffmpeg -i 輸入.mp4 -c:v libx264 -crf 28 -preset slow 輸出.mp4

(CRF 數值越大體積越小,18~28 是常用範圍)

若原始視頻解析度過高,如 1920×1080,想壓縮至 720p 且儘量保畫質

ffmpeg -i 輸入.mp4 -vf "scale=1280:720" -preset slow -crf 20 輸出.mp4

➔「-vf “scale=1280:720″」 精準調整解析度,「-preset slow」 讓編碼慢工出細活,提升壓縮效率,「-crf 20」 在品質與檔大小間取平衡,CRF 值可按需微調, 數值越大體積越小。

若原檔為舊的 RMVB / FLV 格式,經常會出現聲畫不同步或音訊中斷 (直接可用批次檔)

@echo off
chcp 65001 >nul
setlocal enabledelayedexpansion

echo 正在執行兩階段自動修復轉碼...
echo -----------------------------------

for %%i in (*.rmvb) do (
    echo [步驟 1/2] 正在提取並修復音訊: "%%i"
    ffmpeg -y -err_detect ignore_err -fflags +genpts -i "%%i" -vn -acodec pcm_s16le -ar 44100 "%%~ni_temp.wav"
    
    echo [步驟 2/2] 正在合併影視與修復音訊...
    ffmpeg -y -err_detect ignore_err -fflags +genpts -i "%%i" -i "%%~ni_temp.wav" -map 0:v:0 -map 1:a:0 -c:v libx264 -preset faster -crf 30 -r 30 -af "aresample=async=1000" -c:a aac -b:a 128k "%%~ni.mp4"
    
    echo 清理暫存檔...
    if exist "%%~ni_temp.wav" del "%%~ni_temp.wav"
)

echo -----------------------------------
echo 所有檔案處理完畢!
pause

此批次檔先單獨把音訊解碼匯出成 .wav(WAV 格式最穩定,不會因為 PTS 遺失而中斷解碼)。
再將 .wav 與影片合併輸出 MP4,最後自動刪除暫存的 .wav
-r 30強迫影片輸出為 30 fps 恆定影格率(CFR)。消除 RMVB 可變影格率導致的時間軸漂移。
-af "aresample=async=1000" 關鍵防異步參數。自動根據影片時間軸拉伸/縮短或補齊音訊採樣,確保音訊與影像時間軸嚴密對齊,防止後半段沒聲音。
-c:v libx264 -crf 30 使用 H.264 編碼壓縮影片。CRF 23 能在畫質與檔案大小間取得良好平衡(數值越小畫質越高,通常 18-28 之間,這裡用 30 會犧牲畫質)。
-c:a aac -b:a 128k 將 RealAudio 直接轉碼為標準 AAC 音訊格式,相容性最佳。
-y若目標檔名已存在,自動覆蓋不中斷批次流程。
-err_detect ignore_err 忽略解碼過程中的錯誤,盡可能繼續處理損壞的檔案 -fflags +genpts 若輸入檔缺少 PTS(簡報時間戳),則自動重新生成,防止音訊同步異常。
-discard:v 0 表示「不丟棄任何視訊幀(包含所有非關鍵幀)」,在處理時間戳(PTS/DTS)混亂的檔案時,確保所有視訊幀都被完整保留與計算,避免轉檔後出現影音不同步。(嚴重時可用)
-map 0:v:0只讀取輸入檔的第一個視訊軌。
-map 0:a:0?只讀取輸入檔的第一個音訊軌(加 ? 代表若該檔案完全沒有音軌也不會報錯中斷)。

3. 提高影片品質

高品質 H.264 轉碼並提供高品質 AAC 音訊的完整命令列如下:

ffmpeg -y -i bbb_sunflower_1080p_60fps_normal.mp4 \
-c:v libx264 -preset slow -crf 22 \
-profile:v main -g 250 -pix_fmt yuv420p \
-map 0:0 -map 0:1 \
-acodec aac -ar 44100 -b:a 320k bbb_transcoded_h264_HQ.mov

➔c:v libx264:將編解碼器設為 libx264;-preset slow:預設慢速;-crf 22:是固定速率因子,是設定影像品質的主要選項;-profile:v main -g 250 -pix_fmt yuv420p:這些是進階選項,保證你得到相當向下相容的結果(參考 thisthis, 和 this.);-map 0:0 -map 0:1:你可能不需要這個:這些選項是選擇正確的影片和音訊串流。我們有兩條音訊串流,需要立體聲那條以避免 AAC 串流出現問題;-ar 44100:設定音訊取樣率;-b:a 320k:設定音訊位元率

追求高效壓縮且目標受眾設備較新,可嘗試H.265 / HEVC:

ffmpeg -i 輸入.mp4 -c:v libx265 -crf 28 -preset fast -c:a copy 輸出.mp4

ffmpeg -i 輸入.mp4 -c:v libx265 -preset medium -crf 22 輸出.mp4

ffmpeg -y -i bbb_sunflower_1080p_60fps_normal.mp4 \
-c:v libx265 -preset slow -crf 27 \
-profile:v main -g 250 -pix_fmt yuv420p \
-map 0:0 -map 0:1 \
-acodec aac -ar 44100 -b:a 320k bbb_transcoded_h265_HQ.mov

➔碼率控制同樣關鍵,固定碼率(CBR)雖碼率恒定,但複雜場景畫質波動大;動態碼率(VBR)依畫面複雜度分配碼率,檔品質高但碼率難控;平均碼率(ABR)折衷二者,指定平均碼率同時兼顧畫質。

為適配某視頻平臺要求,將碼率設為 2Mbps:

ffmpeg -i 輸入.mp4 -b:v 2M -bufsize 2M -maxrate 2M -minrate 2M 輸出.mp4

編碼格式也有門道,H.264 廣泛相容,編碼效率不錯;H.265/HEVC 更先進,相同畫質下文件體積可比 H.264 小 30% – 50%,但編碼耗時久且部分設備相容性欠佳。

➔合理搭配解析度、編碼格式與碼率策略,FFmpeg 助力視頻 「瘦身」 不失風采。

4. 裁剪(剪片段)

從第 10 秒剪到第 30

ffmpeg -i 輸入.mp4 -ss 00:00:10 -to 00:00:30 -c copy 輸出.mp4

或指定時長(從第 10 秒開始剪 20 秒)

ffmpeg -i 輸入.mp4 -ss 10 -t 20 -c copy 輸出.mp4

➔「-ss」 指定開始時間,「-to」 設定結束時間,「-t」設定時長,「-c copy」 則是無損複製流,保證剪輯快速且畫質無損。若需要影格等級(Frame-exact)的精確剪輯,建議進行重新編碼:

5. 提取音訊 / 視訊

提取音訊:

ffmpeg -i 影片.mp4 -vn -c:a copy 音訊.m4a

提取原始 AAC 音訊

ffmpeg -i 影片.mp4 -vn -c:a copy 音訊.aac

提取原始 MP3/DTS/AC3 等音訊(依原影片音訊格式而定)

ffmpeg -i 影片.mkv -vn -c:a copy 音訊.m4a

或轉成 MP3 / 無損 FLAC

ffmpeg -i 影片.mp4 -vn -c:a libmp3lame -b:a 192k 音訊.mp3

轉為高音質 MP3 (VBR ~240kbps)

ffmpeg -i 影片.mp4 -vn -c:a libmp3lame -q:a 2 音訊.mp3

轉為無損 FLAC

ffmpeg -i 影片.mp4 -vn -c:a flac 音訊.flac

➔「-vn」 表示忽略視頻流,僅處理音訊,「-c:a libmp3lame」 選用流行的 LAME MP3 編碼器保障音訊品質。

截取多軌頻道中的第一條聲軌:

ffmpeg -i 影片.mp4 -map 0:1 stereo_audio_only.wav

➔參數 -map 0:1 表示,在 output 中,我們希望有 Input #0 的(第一個輸入檔) Stream #1 !

提取同一影片的兩條聲軌串流,解壓成兩個獨立的 WAV 檔案

ffmpeg -y -i 影片.mp4 -map 0:1 stereo_audio_only.wav -map 0:2 ac3_audio_only.wav

提取同一影片的兩條聲軌串流,一條為 WAV 檔案,一條為MP3檔案

ffmpeg -y -i 影片.mp4 stereo_audio_only.wav  stereo_audio_only.mp3

提取同一影片的兩條聲軌串流,,解壓成兩個指定品質的獨立MP3檔案

ffmpeg -y \
 -i 影片.mp4  \
 -map 0:1 -b:a 320k stereo_audio_only_high_quality.mp3 \
 -map 0:1 -b:a 64k  stereo_audio_only_low_quality.mp3

提取MKV影片中四條不同語言音軌,解壓成四個獨立的WAV檔案 (Powershell)

ffmpeg -I 輸入.mkv” \
-map 0:a:0 -vn -acodec pcm_s16le -ar 44100 "track_0.wav" \
-map 0:a:1 -vn -acodec pcm_s16le -ar 44100 "track_1.wav" \
-map 0:a:2 -vn -acodec pcm_s16le -ar 44100 "track_2.wav" \
-map 0:a:3 -vn -acodec pcm_s16le -ar 44100 "track_3.wav"

用原有的音軌名稱命名提取的WAV (Powershell)

$file = "test.mkv"

# 1. 取得所有音軌的索引、語言與名稱標籤
$streams = ffprobe -v error -show_entries stream=index:stream_tags=language,title -select_streams a -of json $file | ConvertFrom-Json

# 2. 逐一提取並以聲軌名稱命名
foreach ($s in $streams.streams) {
    $idx = $s.index
    # 優先使用 title 標籤,若無則使用 language 標籤,皆無則使用 track_索引
    $lang = if ($s.tags.title) { $s.tags.title } elseif ($s.tags.language) { $s.tags.language } else { "track_$idx" }
    
    # 清除檔名不不支援的非法字元
    $safeLang = $lang -replace '[\\/:*?"<>|]', '_'
    
    # 執行 FFmpeg 轉檔
    ffmpeg -y -i $file -map 0:$idx -vn -acodec pcm_s16le -ar 44100 "${file}_${safeLang}.wav"
}

提取視訊:

ffmpeg -i 輸入.mp4 -an 輸出無聲視訊.mp4

➔「-an」 表示忽略音頻流,僅處理視訊

6. 合併多個影片(無重編碼,最快)

先建立一個文字檔 list.txt

file '影片1.mp4'
file '影片2.mp4'
file '影片3.mp4'

然後執行:

ffmpeg -f concat -safe 0 -i list.txt -c copy 合併.mp4

7. 合併影片(只抽取視頻畫面)和MP3音訊

ffmpeg -i 輸入視頻.mkv -i 輸入音訊.mp3 -map 0:v:0 -map 1:a:0 -c:v copy -c:a aac -b:a 192k -shortest 輸出.mp4

ffmpeg -i 輸入視頻.mkv -i 輸入音訊.mp3 -map 0:v:0 -map 1:a:0 -map 0:s? -c:v libx264 -vf “scale=1280:-2” -preset faster -crf 28 -c:a aac -q:a 2 -ac 2 -c:s mov_text -disposition:s:0 default 輸出.mp4

-i 輸入.mkv:第一個輸入檔(原始影片),-i input_audio.mp3:第二個輸入檔(MP3 音訊)。

-map 0:v:0:強制只取第一個輸入檔 (0) 的第一個視訊軌(自動丟棄原始影片的所有音軌與字幕)。

-map 1:a:0:強制只取第二個輸入檔 (1) 的第一個音訊軌(即你的 MP3)。

-map 0:s?映射影片所有字幕軌

-c:v copy畫質零損失秒出! 畫面直接流複製,不重新壓縮編碼(若原始影片視訊格式已是 H.264/HEVC 等 MP4 相容格式,幾秒內即可完成;若影片本身需要重新編碼,可改為 -c:v libx264)。

-vf "scale=1280:-2":使用濾鏡縮放畫面,預設寬1280,高按比例縮放。

-q:a 2 -ac 2自動根據聲音複雜度調整位元率。

-c:a aac -b:a 192k:將 MP3 音訊重新編碼為 AAC 格式,位元率設為 192k。

-c:s mov_text -disposition:s:0 default字幕轉為 MP4 標準的 mov_text 軟字幕格式,並預設開啟

-shortest(推薦加上):當影片與 MP3 長度不一致時,以較短者的長度為準自動截斷,避免影音長度不同步(例如影片 3 分鐘但 MP3 有 5 分鐘時,會自動在 3 分鐘處裁切)。

8. 調整解析度 / 縮放 / 部分裁切 / 畫中畫

強制縮放到 1280×720

ffmpeg -i 輸入.mp4 -vf scale=1280:720 輸出_720p.mp4

ffmpeg -i 輸入.mp4 -vf "scale=1920:1080" -c:a copy 輸出_1080p.mp4

保持比例,寬度改成 1280,高度按比例自動計算

ffmpeg -i 輸入.mp4 -vf scale=1280:-2 輸出.mp4

ffmpeg -i 輸入.mp4 -vf "scale=1280:-1" -c:a copy 輸出_720p.mp4

➔寬度 1280,高度按比例自動計算,並強制為偶數「-2」(奇數「-1」可能報錯)
其他常見寫法:
高度固定 720,寬度自動(保持比例且為偶數) scale=-2:720
寬度最大不超過 1280,高度最大不超過 720(保持比例) scale=’min(1280,iw)’:-2

裁剪出左上角 320×240 區域 (Crop 濾鏡可裁剪畫面):

ffmpeg -i 輸入.mp4 -vf "crop=320:240:0:0" 輸出.mp4

裁切中間 1280×720 的區域

ffmpeg -i 輸入.mp4 -vf "crop=1280:720:0:0" -c:a copy 輸出.mp4

crop=out_w:out_h:x:y(輸出寬:輸出高:起始X座標:起始Y座標)

添加畫中畫效果

ffmpeg -i 背景視頻.mp4 -i 小窗視頻.mp4 -filter_complex "[1:v]scale=iw/2:ih/2[ovrl];[0:v][ovrl]overlay=W-w: H-h" pip_video.mp4

➔以 「背景視頻.mp4」 為背景,「小窗視頻.mp4」 為畫中畫小窗視頻,置於右下角

9. 加速 / 減速

2 倍速

ffmpeg -i 輸入.mp4 -filter:v "setpts=0.5*PTS" -filter:a "atempo=2.0" 輸出.mp4

0.5 倍速(慢放)

ffmpeg -i 輸入.mp4 -filter:v "setpts=2.0*PTS" -filter:a "atempo=0.5" 輸出.mp4

10. 旋轉 / 翻轉

順時針轉 90

ffmpeg -i 輸入.mp4 -vf "transpose=1" 輸出.mp4

順時針轉 180

ffmpeg -i 輸入.mp4 -vf "transpose=1,transpose=1" 輸出.mp4

順時針轉 270 度(等同逆時針轉 90 度)

ffmpeg -i 輸入.mp4 -vf "transpose=2" 輸出.mp4

水平翻轉

ffmpeg -i 輸入.mp4 -vf hflip 輸出.mp4

垂直翻轉(上下顛倒)

ffmpeg -i 輸入.mp4 -vf vflip 輸出.mp4

transpose數值表示的效果說明:

0:逆時針轉 90 度 + 垂直翻轉
1:順時針轉 90 度
2:逆時針轉 90 度
3:順時針轉 90 度 + 垂直翻轉

如果影片格式支援(如 MP4),只想改變播放時的方向而不想重新編碼影片(節省時間且不損失畫質),可以使用 -metadata:s:v rotate 參數:

設定影片播放時順時針旋轉 180

ffmpeg -i 輸入.mp4 -c copy -metadata:s:v rotate="180" 輸出.mp4

11. 加字幕

燒錄硬字幕 (Hard Subtitles / Burn-in)(將字幕直接壓製到影片畫面上(無法關閉)

ffmpeg -i 影片.mp4 -vf "subtitles=字幕.srt" 輸出.mp4

壓製 SRT 字幕

ffmpeg -i 影片.mp4 -vf "subtitles=字幕.srt" -c:v libx264 -crf 22 -c:a copy 內嵌字幕輸出.mp4

壓製特效 ASS 字幕

ffmpeg -i 影片.mp4 -vf "ass=字幕.ass" -c:v libx264 -crf 22 -c:a copy 內嵌字幕輸出.mp4

打包內封軟字幕(Soft Subtitles / Muxing)(將外部字幕檔(SRT/ASS)打包進 MKV 或 MP4 容器內,播放時可自由切換開啟/關閉)

打包封裝進 MKV 容器

ffmpeg -i 影片.mp4 -i 字幕.srt -c copy -c:s srt 輸出.mkv

指定字幕語言標籤 (例如繁體中文/zh-TW)

ffmpeg -i i影片.mp4 -i 字幕.srt -c copy -metadata:s:s:0 language=zho 輸出.mkv

12. 提取影片畫面(截圖 / 製作 GIF)

每秒截一張圖

ffmpeg -i 影片.mp4 -vf fps=1 圖片_%04d.png

製作成 GIF(從第 5 秒開始,時長 3 秒)

ffmpeg -ss 5 -t 3 -i 影片.mp4 -vf "fps=10,scale=480:-1" 輸出.gif

高畫質 GIF 轉換(先生成調色盤以提升畫質)

ffmpeg -ss 00:00:05 -t 5 -i 影片.mp4 -filter_complex "[0:v] fps=15,scale=480:-1:flags=lanczos,split [a][b];[a] palettegen [p];[b][p] paletteuse" 輸出.gif

13. 調整音量 / 音訊處理

音量加大 1.5

ffmpeg -i 輸入.mp4 -af "volume=1.5" 輸出.mp4
ffmpeg -i 輸入.mp3 -af "volume=1.5" 輸出.mp3

音訊標準化(自動調整響度)

ffmpeg -i 輸入.mp4 -af loudnorm 輸出.mp4

混音

ffmpeg -i 輸入音樂1.mp3 -i 輸入音樂2.mp3 -filter_complex amix=inputs=2:duration=first:dropout_transition=3 輸出混音音樂.mp3

➔這裡通過 amix 濾鏡精准控制混音參數,實現完美音訊融合。

14. 圖片序列轉影片

ffmpeg -framerate 30 -i 圖片_%04d.png -c:v libx264 -pix_fmt yuv420p 輸出.mp4

15. 去除音訊(只留畫面)

ffmpeg -i 輸入.mp4 -an -c:v copy 無聲.mp4

16. 靜音視頻加上音樂

ffmpeg -i 輸入無聲視頻.mp4 -i 音樂.mp3 -c:v copy -c:a aac -map 0:v:0 -map 1:a:0 輸出有聲視頻.mp4

17. 合併圖片和音樂為視頻:

ffmpeg -loop 1 -framerate 30 -i 圖片.jpg -i 音樂.mp3 -c:v libx264 -tune stillimage -c:a aac -b:a 192k -pix_fmt yuv420p -shortest -max_interleave_delta 100M -movflags +faststart 輸出.mp4

強制指定時長(更精準),

先查音樂精確時長:

ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 音樂.mp3

假設顯示 64.162083,-t就改成:

ffmpeg -loop 1 -framerate 30 -i 圖片.jpg -i 音樂.mp3 -t 64.162083 -c:v libx264 -tune stillimage -c:a aac -b:a 192k -pix_fmt yuv420p -movflags +faststart 輸出.mp4

18.  快速查看影片資訊

ffprobe -i 影片.mp4

或更詳細

ffprobe -v quiet -print_format json -show_format -show_streams 影片.mp4

19. 流媒體處理與直播推流

在流媒體播放網路上的 RTMP 直播流:

ffplay rtmp://live.example.com/app/streamKey

➔「ffplay」 是 FFmpeg 自帶的簡易播放機,通過指定 RTMP 流位址,就能即時觀看直播內容。

將本地視頻即時推流到自家搭建的基於 RTMP 協定的流媒體伺服器:

ffmpeg -re -i 輸入.mp4 -c:v libx264 -c:a aac -f flv

rtmp://server_ip/live/stream_name

➔「-re」 參數至關重要,它能按視頻原始幀率讀取,避免因過快推送導致播放異常;「-c:v libx264」 與 「-c:a aac」 選用主流編碼格式保障相容性與品質;「-f flv」 指定輸出格式為 FLV,適配多數流媒體伺服器接收,如此一來,便能開啟個人專屬直播頻道。 涉及流媒體協議,常見的 RTMP 常用於直播推流,它低延遲、能即時雙向通信;HLS(HTTP Live Streaming)基於 HTTP,相容性強,可自我調整不同網路狀況,多用於蘋果生態及網頁端視頻播放;SRT(Secure Reliable Transport)專注安全可靠傳輸,在複雜網路下丟包率低,保障流媒體穩定。理解這些協議特性,依需求選擇,能優化流媒體處理效果。

參考來源:全網最全FFmpeg教程,從新手到高手的蛻變指南 – 知乎

深入研究:FFmpeg – 終極指南 |IMG。LY 部落格 — FFmpeg – Ultimate Guide | IMG.LY Blog

以下示例,可把一個資料夾(包含子資料夾)中的所有不同格式影片檔在無人值守下一次過全部壓縮為MP4(預設寬1280,H.264編碼,同時保留所有音軌和不同類型字幕,可任意更改):

Powershell:(在檔案總管中按住Ctrl+Shift右鍵影片目錄,「在這裡開啟powershell視窗」,並執行以下命令)

# ==================================================================================
# PowerShell 批次影片轉碼腳本 (支援多音軌、外掛/內建字幕、舊檔音訊修復)
# ==================================================================================

# 1. 定義要搜尋並處理的影片副檔名清單
$extensions = "*.mp4", "*.avi",  "*.mkv", "*.mov", "*.flv", "*.wmv", "*.mpg"

# 2. 遞迴搜尋目前目錄及所有子資料夾內的影片檔案
Get-ChildItem -Recurse -Include $extensions | ForEach-Object {
    $src = $_.FullName
    
    # 【過濾機制】若發現是轉碼過程中產生的 .tmp.mp4 檔案則直接跳過,避免重複處理
    if ($src -like "*.tmp.mp4") { return }

    # 定義相關檔案路徑
    $srtPath     = [System.IO.Path]::ChangeExtension($src, "srt")      # 對應的外掛 .srt 字幕路徑
    $tempOutput  = [System.IO.Path]::ChangeExtension($src, "tmp.mp4")  # 轉碼時使用的臨時檔路徑
    $finalOutput = [System.IO.Path]::ChangeExtension($src, "mp4")      # 最終輸出的 .mp4 路徑

    Write-Host "`n===================================================" -ForegroundColor Cya
    Write-Host "正在處理: $src" -ForegroundColor Cyan
    Write-Host "===================================================" -ForegroundColor Cyan

    # 【防呆清理】若上次執行中途中斷留下殘留的 .tmp.mp4,先強制刪除
    if (Test-Path $tempOutput) { Remove-Item $tempOutput -Force }

    # 檢查是否存在同名的外掛 .srt 字幕檔
    $hasSrt = Test-Path $srtPath

    # ------------------------------------------------------------------------------
    # 【情況 A】存在同名外掛 .srt 字幕檔
    # ------------------------------------------------------------------------------
    if ($hasSrt) {
        Write-Host "偵測到外掛 SRT 字幕,正在打包(自動相容老舊音訊)..." -ForegroundColor Yellow

        # FFmpeg 參數說明:
        # -y                         : 自動覆蓋輸出檔(無人值守)
        # -i $src                    : 輸入檔 0(原始影片)
        # -i $srtPath                : 輸入檔 1(外掛 SRT 字幕)
        # -map 0:v:0                 : 只映射影片 0 的第一個視訊軌(排除可能的預覽圖/封面)
        # -map 0:a                   : 映射影片 0 的「所有」音軌(保留多國語言聲軌)
        # -map 1:0                   : 映射字幕 1 的第一個字幕軌(外掛 SRT)
        # -c:v libx264               : 視訊採用 H.264 編碼
        # -vf "scale=1024:-2"        : 等比例縮放寬度至 1024px,高度按比例自動計算為 2 的倍數
        # -preset faster             : 編碼速度設為 faster,兼顧速度與壓縮率
        # -crf 28                    : 固定品質係數(28 為畫質與體積的平衡點)
        # -c:a aac                   : 音訊統一重新編碼為 AAC
        # -q:a 2                   : 自動根據聲音複雜度調整位元率,每條音軌大約會落在 128k~192k 之間,音質比固定 -b:a 128k 更好,且完美支援多音軌。
        # -ar 44100                  : 強制音訊採樣率為 44.1 kHz(解決老舊 RMVB/FLV 11k/22k 轉碼報錯)
        # -ac 2                      : 強制音訊輸出為標準雙聲道 Stereo(避免單聲道破音)
        # -c:s mov_text              : 字幕轉為 MP4 標準的 mov_text 軟字幕
        # -disposition:s:0 default   : 將第一個字幕軌標記為「預設開啟」
        ffmpeg -y -i $src -i $srtPath -map 0:v:0 -map 0:a? -map 1:0 -c:v libx264 -vf "scale=1280:-2" -preset faster -crf 28 -c:a aac -q:a 2 -b:a 192k -c:s copy $tempOutput
    
    # ------------------------------------------------------------------------------
    # 【情況 B】無外掛 SRT 檔,嘗試打包影片內部自帶的「所有音軌與內建字幕」
    # ------------------------------------------------------------------------------
    } else {
        Write-Host "未發現外掛字幕,嘗試保留所有音軌(自動相容老舊音訊)與內建字幕..." -ForegroundColor Yellow

        # -map 0:s? : 映射影片內建的「所有」字幕軌(? 代表若無字幕也不會報錯),-map 0:t? 表示打包附件軌,主要指 ASS 字幕內嵌的字型檔
        ffmpeg -y -i $src -map 0:v:0 -map 0:a? -map 0:s? -map 0:t? -c:v libx264 -vf "scale=1280:-2" -preset faster -crf 28 -c:a aac -q:a 2 -b:a 192k -c:s copy $tempOutput
    }

    # ------------------------------------------------------------------------------
    # 【安全性驗證】檢查 FFmpeg 回傳碼 ($LASTEXITCODE -eq 0) 且輸出檔存在且大小 > 0
    # ------------------------------------------------------------------------------
    if ($LASTEXITCODE -eq 0 -and (Test-Path $tempOutput) -and (Get-Item $tempOutput).Length -gt 0) {
        Remove-Item $src -Force                                 # 刪除原始影片
        if ($hasSrt) { Remove-Item $srtPath -Force }             # 若有外掛 SRT 順便刪除
        Rename-Item $tempOutput -NewName (Split-Path $finalOutput -Leaf) # 將臨時檔命名為正式 MP4
        Write-Host "[成功] 已完成轉碼並刪除原檔: $src" -ForegroundColor Green

    # ------------------------------------------------------------------------------
    # 【情況 C】自動降級備案(備用機制)
    # 原因:若 MKV 內含 MP4 無法封裝的「圖像字幕」(如 PGS/VOBSub),上述轉碼會失敗。
    #      此時自動切換為「保留所有音軌,但剔除字幕」重新轉碼。
    # ------------------------------------------------------------------------------
    } else {
        Write-Host "[警告] 內建字幕格式不相容(如 PGS/VOBSub),嘗試保留所有音軌並無視字幕..." -ForegroundColor Yellow
        if (Test-Path $tempOutput) { Remove-Item $tempOutput -Force }

        # -sn : 停用字幕(Skip Subtitles),確保影片與多聲軌能順利輸出
        ffmpeg -y -i $src -map 0:v:0 -map 0:a? -c:v libx264 -vf "scale=1280:-2" -preset faster -crf 28 -c:a aac -q:a 2 -b:a 192k -sn $tempOutput

        # 再次進行安全性驗證
        if ($LASTEXITCODE -eq 0 -and (Test-Path $tempOutput) -and (Get-Item $tempOutput).Length -gt 0) {
            Remove-Item $src -Force
            if ($hasSrt) { Remove-Item $srtPath -Force }
            Rename-Item $tempOutput -NewName (Split-Path $finalOutput -Leaf)
            Write-Host "[成功] 已修復音訊並完成壓縮 (無視不相容字幕): $src" -ForegroundColor Green
        } else {
            # 最終防護:若所有嘗試均失敗,絕不刪除原始檔案
            Write-Host "[失敗] 轉碼過程發生錯誤,完好保留原始檔案: $src" -ForegroundColor Red
            if (Test-Path $tempOutput) { Remove-Item $tempOutput -Force }
        }
    }
}

Write-Host "`n===================================================" -ForegroundColor Cyan
Write-Host "所有影片處理完成!" -ForegroundColor Cyan
Write-Host "===================================================" -ForegroundColor Cyan

➔用修改「-crf」變更畫面質素

聲音編碼改為 -c:a aac -b:a 128k

  • 針對 MP4可用的 -c:a copy(直接複製音訊流),但在處理 RMVB、AVI 時很容易出錯,因為舊格式常見的音訊編碼(如 RealAudio 或特殊 PCM)不一定能直接塞進 MP4 容器中。
  • 改用 -c:a aac 進行重新編碼能保證 100% 成功轉碼並兼容 MP4。

副檔名統一:舊檔無論是 .rmvb.avi,轉碼成功並刪除原檔後,都會重新命名為「同檔名的.mp4」。

字幕:

要將字幕保留為可隨時開啟/關閉(軟字幕),且設定為預設自動播放,需要使用 FFmpeg 的 -disposition 參數。

MP4 容器最相容的文字字幕格式是 mov_text。只要在指令中加入以下設定即可:

  • -map 0:強制讀取輸入檔中的所有軌道(影片、聲音、字幕)。
  • -c:s mov_text:將字幕轉為 MP4 標準軟字幕格式。
  • -disposition:s:0 default:將第一個字幕軌(s:0)設定為預設顯示(Default)
  • 優先尋找是否有同名的外掛 .srt 字幕檔(例如 video1.mkvvideo1.srt),有的話直接封裝進去並設為預設開啟,成功後順便刪除舊 .srt
  • 若沒有外掛字幕,則自動抓取影片原本內嵌的字幕軌,封裝並設為預設開啟。

播放器相容性-disposition:s:0 default 標記會被大多數現代播放器(VLC、PotPlayer、Apple TV、Synology Video Station / Plex 等)讀取並自動顯示字幕。

圖形字幕限制:MP4 容器不支援 MKV 常見的圖像字幕(如 Blu-ray PGS 或 DVD VOBSub)。腳本已寫入防呆機制,若遇到無法轉換的字幕類型,會自動切換為無字幕輸出,保證轉碼順利完成而不中斷。

-map 0:v -map 0:a? -map 0:s? -map 0:t?:明確讀取影像、聲音、字幕、附件(Attachments,主要指 ASS 字幕內嵌的字型檔)。留意MP4 容器格式不支援 ASS 特效字幕,必須輸出MKV才支持。

$LASTEXITCODE -eq 0 + 檔案大小判斷:雙重驗證轉碼成功才刪除原檔,防止誤刪。

.bat 批次檔(支持 UNC 網路路徑)直接複製並儲存為 compress_all.bat,放在影片目錄雙擊執行

@echo off
chcp 65001 >nul
REM 將命令提示字元視窗的編碼切換為 UTF-8 (65001),避免檔名含有中文時出現亂碼

REM 設定變數延遲展開,確保在 for 迴圈內的 if/set 邏輯(如 !SUCCESS!)能即時更新與讀取
SetLocal EnableDelayedExpansion

echo 正在準備批次壓縮影片(完整保留多音軌、外掛/內建字幕,並修正老舊 RMVB/FLV 音訊)...

REM ----------------------------------------------------------------------------------
REM "pushd %~dp0":將此批次檔所在的資料夾設為目前工作目錄。
REM 若資料夾位於NAS或網路磁碟UNC路徑,如 \\NAS\Share,pushd會自動建立臨時磁碟機代號,如 Z:
REM ----------------------------------------------------------------------------------
pushd "%~dp0"

REM ----------------------------------------------------------------------------------
REM 【遞迴搜尋影片檔案】
REM ----------------------------------------------------------------------------------
for /r %%F in (*.mp4 *.avi *.mkv *.mov *.flv *.wmv *.mpg) do (

    REM 過濾機制:檢查檔名是否包含 .tmp.mp4,避免批次檔重複處理到轉碼中的臨時檔
    echo "%%F" | findstr /i "\.tmp\.mp4$" >nul
    if errorlevel 1 (
        echo.
        echo ===================================================
        echo 正在處理: "%%F"
        echo ===================================================

        REM 防呆清理:若上次執行中途中斷留下殘留的 .tmp.mp4,先強制刪除
        if exist "%%~dpnF.tmp.mp4" del /f /q "%%~dpnF.tmp.mp4"

        REM ------------------------------------------------------------------------------
        REM 【情況 A】偵測是否存在與影片「同名」的外掛 .srt 字幕檔
        REM ------------------------------------------------------------------------------
        if exist "%%~dpnF.srt" (
            echo 偵測到外掛 SRT 字幕,正在打包(自動相容老舊音訊)...
            
            REM FFmpeg 參數詳細解析:
            REM -y                         : 自動覆蓋輸出檔,不跳出確認詢問(達到無人值守)
            REM -i "%%F"                    : 輸入檔 0(原始影片)
            REM -i "%%~dpnF.srt"           : 輸入檔 1(外掛 SRT 字幕)
            REM -map 0:v:0                 : 只映射影片 0 的第一個視訊軌(排除可能的預覽圖/封面)
            REM -map 0:a                   : 映射影片 0 的「所有」音軌(保留多國語言聲軌)
            REM -map 1:0                   : 映射字幕 1 的第一個字幕軌(即外掛 SRT)
            REM -c:v libx264               : 視訊使用 H.264 編碼
            REM -vf "scale=1024:-2"        : 等比例縮放寬度至 1024px,高度自動按比例計算(且強制為 2 的倍數)
            REM -preset faster             : 編碼速度設定為 faster,兼顧壓縮速度與檔案大小
            REM -crf 28                    : 固定品質係數(數字越小品質越好,28 為體積與畫質的優良平衡點)
            REM -c:a aac -b:a 128k         : 音訊統一重新編碼為 AAC 格式,位元率 128k
            REM -ar 44100                  : 強制音訊採樣率為 44.1 kHz(解決老舊 RMVB/FLV 的 11k/22k 轉碼報錯問題)
			REM -q:a 2	                 	:會讓 FFmpeg 自動根據聲音複雜度調整位元率,每條音軌大約會落在 128k~192k 之間,音質比固定 128k 更好,且完美支援多音軌。
            REM -ac 2                      : 強制音訊輸出為標準雙聲道 Stereo(避免單聲道或非標準聲道破音)
            REM -c:s mov_text              : 字幕轉為 MP4 標準的 mov_text 軟字幕格式
            REM -disposition:s:0 default   : 將第一個字幕軌標記為「預設開啟」,播放器開啟時會自動顯示
            ffmpeg -y -i "%%F" -i "%%~dpnF.srt" -map 0:v:0 -map 0:a? -map 1:0 -c:v libx264 -vf "scale=1080:-2" -preset faster -crf 28 -c:a aac -q:a 2 -b:a 192k -c:s copy "%%~dpnF.tmp.mp4"
            
            set "SUCCESS=0"
            REM 嚴格安全性驗證:檢查轉碼後的 .tmp.mp4 是否存在,且檔案大小 GTR 0 (大於 0 Byte)
            if exist "%%~dpnF.tmp.mp4" (
                for %%A in ("%%~dpnF.tmp.mp4") do if %%~zA GTR 0 (
                    del /f /q "%%F"               REM 刪除原始影片
                    del /f /q "%%~dpnF.srt"        REM 刪除已打包的外掛 SRT 字幕
                    ren "%%~dpnF.tmp.mp4" "%%~nF.mp4" REM 將臨時檔更名為正式的 .mp4
                    echo [成功] 已完成轉碼並修復音訊相容性!
                    set "SUCCESS=1"
                )
            )
            REM 若轉碼失敗,清理殘留的無效 0 byte 臨時檔
            if "!SUCCESS!"=="0" (
                echo [失敗] 打包外掛字幕失敗,完好保留原始檔案。
                if exist "%%~dpnF.tmp.mp4" del /f /q "%%~dpnF.tmp.mp4"
            )

        REM ------------------------------------------------------------------------------
        REM 【情況 B】無外掛 SRT 檔,嘗試打包影片內部自帶的「所有音軌與內建字幕」
        REM ------------------------------------------------------------------------------
        ) else (
            echo 未發現外掛字幕,嘗試保留所有音軌(自動相容老舊音訊)與內建字幕...
            REM "-map 0:s?"映射影片所有字幕軌。問號?代表即使影片完全沒有字幕,也不會報錯中斷
            ffmpeg -y -fflags +genpts -err_detect ignore_err -i "%%F" -map 0:v:0 -map 0:a? -map 0:s? -map 0:t? -c:v libx264 -vf "scale=1080:-2" -preset faster -crf 30 -c:a aac -q:a 2 -b:a 192k -c:s copy "%%~dpnF.tmp.mp4"

            set "SUCCESS=0"
            REM 驗證轉碼成果
            if exist "%%~dpnF.tmp.mp4" (
                for %%A in ("%%~dpnF.tmp.mp4") do if %%~zA GTR 0 (
                    del /f /q "%%F"
                    ren "%%~dpnF.tmp.mp4" "%%~nF.mp4"
                    echo [成功] 已保留所有音軌與字幕,完成轉碼。
                    set "SUCCESS=1"
                )
            )

            REM --------------------------------------------------------------------------
            REM 【情況 C】情況 B 失敗時的自動降級備案(備用機制)
            REM 原因:若 MKV 內含 MP4 容器無法封裝的「圖像字幕」(如 Blu-ray PGS 或 DVD VOBSub),
            REM      情況 B 會轉碼失敗。此時自動切換為「保留所有音軌,但剔除字幕」重新轉碼。
            REM --------------------------------------------------------------------------
            if "!SUCCESS!"=="0" (
                if exist "%%~dpnF.tmp.mp4" del /f /q "%%~dpnF.tmp.mp4"
                echo [警告] 包含不相容字幕格式,改為保留所有音軌(修正音訊)並無視字幕...
                
                REM -sn : 停用字幕(Skip Subtitles),確保影片與多聲道音軌能順利輸出
                ffmpeg -y -i "%%F" -map 0:v:0 -map 0:a? -c:v libx264 -vf "scale=1024:-2" -preset faster -crf 28 -c:a aac -q:a 2 -b:a 192k -sn "%%~dpnF.tmp.mp4"

                if exist "%%~dpnF.tmp.mp4" (
                    for %%A in ("%%~dpnF.tmp.mp4") do if %%~zA GTR 0 (
                        del /f /q "%%F"
                        ren "%%~dpnF.tmp.mp4" "%%~nF.mp4"
                        echo [成功] 已修正音訊並完成壓縮(無視不相容字幕)。
                        set "SUCCESS=1"
                    )
                )
                REM 最終防護:若三次轉碼均失敗,絕對不刪除原始影片,安全退出
                if "!SUCCESS!"=="0" (
                    echo [失敗] 轉碼失敗,完好保留原始檔案。
                    if exist "%%~dpnF.tmp.mp4" del /f /q "%%~dpnF.tmp.mp4"
                )
            )
        )
    )
)

echo.
echo ===================================================
echo 所有影片處理完成!
echo ===================================================

REM 卸載由 pushd 自動建立的臨時虛擬磁碟機
popd

REM 暫停畫面,讓使用者查看執行結果
pause

已發佈

分類:

,

作者:

標籤: