使用 FFmpeg 進行影片與音訊處理。適用於格式轉換、尺寸調整、壓縮、音訊擷取,以及為 Remotion 準備素材。觸發情境包括將 GIF 轉為 MP4、調整影片尺寸、擷取音訊、壓縮檔案,或任何媒體轉換任務。
影片製作的 FFmpeg 指南
FFmpeg 是處理影片/音訊的必備工具。本技能涵蓋 Remotion 影片專案的常見操作。
快速參考
GIF 轉 MP4(Remotion 相容)
ffmpeg -i input.gif -movflags faststart -pix_fmt yuv420p \
-vf "scale=trunc(iw/2)*2:trunc(ih/2)*2" output.mp4
為什麼使用這些參數:
-movflags faststart- 將中繼資料移至檔頭,適合網路串流-pix_fmt yuv420p- 確保與多數播放器相容scale=trunc(...)- 強制偶數尺寸(多數編碼器要求)
調整影片尺寸
# 改為 1920x1080(維持比例,補黑邊)
ffmpeg -i input.mp4 -vf "scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2" output.mp4
# 改為 1920x1080(裁切填滿)
ffmpeg -i input.mp4 -vf "scale=1920:1080:force_original_aspect_ratio=increase,crop=1920:1080" output.mp4
# 指定寬度,高度自動
ffmpeg -i input.mp4 -vf "scale=1280:-2" output.mp4
壓縮影片
# 品質佳、檔案小(CRF 23 為預設值,數值越低品質越好)
ffmpeg -i input.mp4 -c:v libx264 -crf 23 -preset medium -c:a aac -b:a 128k output.mp4
# 積極壓縮,適合網頁預覽
ffmpeg -i input.mp4 -c:v libx264 -crf 28 -preset fast -c:a aac -b:a 96k output.mp4
# 指定目標檔案大小(例如 60 秒影片約 10MB = 約 1.3Mbps)
ffmpeg -i input.mp4 -c:v libx264 -b:v 1300k -c:a aac -b:a 128k output.mp4
擷取音訊
# 擷取為 MP3
ffmpeg -i input.mp4 -vn -acodec libmp3lame -q:a 2 output.mp3
# 擷取為 AAC
ffmpeg -i input.mp4 -vn -acodec aac -b:a 192k output.m4a
# 擷取為 WAV(無壓縮)
ffmpeg -i input.mp4 -vn output.wav
轉換音訊格式
# M4A 轉 MP3(適用於 ElevenLabs 語音樣本)
ffmpeg -i input.m4a -codec:a libmp3lame -qscale:a 2 output.mp3
# WAV 轉 MP3
ffmpeg -i input.wav -codec:a libmp3lame -b:a 192k output.mp3
# 調整音量
ffmpeg -i input.mp3 -filter:a "volume=1.5" output.mp3
修剪/裁切影片
# 從時間戳開始,指定長度(建議使用,較可靠)
ffmpeg -i input.mp4 -ss 00:00:30 -t 00:00:15 -c:v libx264 -c:a aac output.mp4
# 從時間戳到時間戳
ffmpeg -i input.mp4 -ss 00:00:30 -to 00:00:45 -c:v libx264 -c:a aac output.mp4
# 串流複製(較快,但裁切點可能掉幀)
# 僅在來源有頻繁關鍵幀時使用
ffmpeg -i input.mp4 -ss 00:00:30 -t 00:00:15 -c copy output.mp4
注意: 建議使用重新編碼來修剪。串流複製(-c copy)若搜尋點未對齊關鍵幀,可能會無聲地丟棄影片。
加速 / 慢放
# 2 倍速(影片與音訊)
ffmpeg -i input.mp4 -filter_complex "[0:v]setpts=0.5*PTS[v];[0:a]atempo=2.0[a]" -map "[v]" -map "[a]" output.mp4
# 0.5 倍速(慢動作)
ffmpeg -i input.mp4 -filter_complex "[0:v]setpts=2.0*PTS[v];[0:a]atempo=0.5[a]" -map "[v]" -map "[a]" output.mp4
# 僅影片(無音訊)
ffmpeg -i input.mp4 -filter:v "setpts=0.5*PTS" -an output.mp4
合併影片
# 建立檔案清單
echo "file 'clip1.mp4'" > list.txt
echo "file 'clip2.mp4'" >> list.txt
echo "file 'clip3.mp4'" >> list.txt
# 合併(相同編碼/解析度)
ffmpeg -f concat -safe 0 -i list.txt -c copy output.mp4
# 合併並重新編碼(不同來源)
ffmpeg -f concat -safe 0 -i list.txt -c:v libx264 -c:a aac output.mp4
加入淡入/淡出
# 前 1 秒淡入,後 1 秒淡出(30fps 影片)
ffmpeg -i input.mp4 -vf "fade=t=in:st=0:d=1,fade=t=out:st=9:d=1" -c:a copy output.mp4
# 音訊淡入淡出
ffmpeg -i input.mp4 -af "afade=t=in:st=0:d=1,afade=t=out:st=9:d=1" -c:v copy output.mp4
取得影片資訊
# 長度、解析度、編碼資訊
ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 input.mp4
# 完整資訊
ffprobe -v quiet -print_format json -show_format -show_streams input.mp4
Remotion 專用模式
為 Remotion 調整影片速度
何時使用 FFmpeg 與 Remotion 的 playbackRate:
| 情境 | 使用 FFmpeg | 使用 Remotion |
|---|---|---|
| 固定速度(1.5x、2x) | 兩者皆可 | ✅ 較簡單 |
| 極端速度(>4x 或 <0.25x) | ✅ 更可靠 | 可能出問題 |
| 可變速度(隨時間加速) | ✅ 預先處理 | 需要複雜繞道 |
| 需要完美音訊同步 | ✅ 保證 | 通常沒問題 |
| 示範需配合旁白時間 | ✅ 預先計算 | 執行時調整 |
Remotion 限制: playbackRate 必須為常數。動態插值如 playbackRate={interpolate(frame, [0, 100], [1, 5])} 無法正確運作,因為 Remotion 獨立評估每個影格。
# 加速示範以配合場景(例如 60 秒示範縮為 20 秒 = 3 倍速)
ffmpeg -i demo-raw.mp4 \
-filter_complex "[0:v]setpts=0.333*PTS[v];[0:a]atempo=3.0[a]" \
-map "[v]" -map "[a]" \
public/demos/demo-fast.mp4
# 慢動作強調(0.5 倍速)
ffmpeg -i action.mp4 \
-filter_complex "[0:v]setpts=2.0*PTS[v];[0:a]atempo=0.5[a]" \
-map "[v]" -map "[a]" \
public/demos/action-slow.mp4
# 僅加速影片(無音訊,常見於螢幕錄影)
ffmpeg -i demo.mp4 -filter:v "setpts=0.5*PTS" -an public/demos/demo-2x.mp4
# 縮時效果(10 倍速,移除音訊)
ffmpeg -i long-demo.mp4 -filter:v "setpts=0.1*PTS" -an public/demos/timelapse.mp4
計算速度倍率:
- 將 X 秒影片放入 Y 秒場景:
speed = X / Y - setpts 乘數 =
1 / speed(例如 3 倍速 = setpts=0.333*PTS) - atempo 值 =
speed(例如 3 倍速 = atempo=3.0)
極端速度(音訊 >2x): 串聯 atempo 濾鏡(每個限制在 0.5-2.0 範圍):
# 4 倍速音訊
-filter_complex "[0:a]atempo=2.0,atempo=2.0[a]"
# 8 倍速音訊
-filter_complex "[0:a]atempo=2.0,atempo=2.0,atempo=2.0[a]"
為 Remotion 準備示範錄影
# 標準 1080p、30fps、Remotion 就緒
ffmpeg -i raw-recording.mp4 \
-vf "scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2,fps=30" \
-c:v libx264 -crf 18 -preset slow \
-c:a aac -b:a 192k \
-movflags faststart \
public/demos/demo.mp4
螢幕錄影轉 Remotion 素材
# 從 iPhone/iPad 錄影(通常 60fps,解析度可變)
ffmpeg -i iphone-recording.mov \
-vf "scale=1920:-2,fps=30" \
-c:v libx264 -crf 20 \
-an \
public/demos/mobile-demo.mp4
批次轉換 GIF
for f in assets/*.gif; do
ffmpeg -i "$f" -movflags faststart -pix_fmt yuv420p \
-vf "scale=trunc(iw/2)*2:trunc(ih/2)*2" \
"public/demos/$(basename "$f" .gif).mp4"
done
常見問題
「高度無法被 2 整除」
加入縮放濾鏡:-vf "scale=trunc(iw/2)*2:trunc(ih/2)*2"
影片在瀏覽器中無法播放
使用:-movflags faststart -pix_fmt yuv420p -c:v libx264
速度變更後音訊不同步
使用 filter_complex 搭配 atempo:-filter_complex "[0:v]setpts=0.5*PTS[v];[0:a]atempo=2.0[a]"
檔案太大
提高 CRF(23→28)或降低解析度
品質指南
| 用途 | CRF | Preset | 備註 |
|---|---|---|---|
| 封存/母版 | 18 | slow | 最佳品質,檔案大 |
| 正式輸出 | 20-22 | medium | 良好平衡 |
| 網頁/預覽 | 23-25 | fast | 較小檔案 |
| 草稿/快速 | 28+ | veryfast | 快速編碼 |
各平台輸出最佳化
Remotion 渲染影片後(通常輸出至 out/video.mp4),使用 FFmpeg 針對各發布平台進行最佳化。
工作流程整合
Remotion 渲染(母版) FFmpeg 最佳化 平台上傳
↓ ↓ ↓
out/video.mp4 ────────→ out/video-youtube.mp4 ───→ YouTube
────────→ out/video-twitter.mp4 ───→ Twitter/X
────────→ out/video-linkedin.mp4 ───→ LinkedIn
────────→ out/video-web.mp4 ───→ 網站嵌入
YouTube(建議設定)
YouTube 會重新編碼所有內容,因此上傳高品質版本:
# YouTube 最佳化(1080p)
ffmpeg -i out/video.mp4 \
-c:v libx264 -preset slow -crf 18 \
-profile:v high -level 4.0 \
-bf 2 -g 30 \
-c:a aac -b:a 192k -ar 48000 \
-movflags +faststart \
out/video-youtube.mp4
# YouTube Shorts(直式 1080x1920)
ffmpeg -i out/video.mp4 \
-vf "scale=1080:1920:force_original_aspect_ratio=decrease,pad=1080:1920:(ow-iw)/2:(oh-ih)/2" \
-c:v libx264 -crf 18 -c:a aac -b:a 192k \
out/video-shorts.mp4
Twitter/X
Twitter 有嚴格限制:最長 140 秒、512MB、1920x1200:
# Twitter 最佳化(目標小於 15MB 以快速上傳)
ffmpeg -i out/video.mp4 \
-c:v libx264 -preset medium -crf 24 \
-profile:v main -level 3.1 \
-vf "scale='min(1280,iw)':'min(720,ih)':force_original_aspect_ratio=decrease" \
-c:a aac -b:a 128k -ar 44100 \
-movflags +faststart \
-fs 15M \
out/video-twitter.mp4
# 檢查檔案大小與長度
ffprobe -v error -show_entries format=duration,size -of csv=p=0 out/video-twitter.mp4
LinkedIn 偏好 MP4 搭配 AAC 音訊,最長 10 分鐘:
# LinkedIn 最佳化
ffmpeg -i out/video.mp4 \
-c:v libx264 -preset medium -crf 22 \
-profile:v main \
-vf "scale='min(1920,iw)':'min(1080,ih)':force_original_aspect_ratio=decrease" \
-c:a aac -b:a 192k -ar 48000 \
-movflags +faststart \
out/video-linkedin.mp4
網站/嵌入(最佳化快速載入)
# 網頁最佳化 MP4(小檔案,漸進式載入)
ffmpeg -i out/video.mp4 \
-c:v libx264 -preset medium -crf 26 \
-profile:v baseline -level 3.0 \
-vf "scale=1280:720" \
-c:a aac -b:a 128k \
-movflags +faststart \
out/video-web.mp4
# WebM 替代方案(壓縮更好,瀏覽器支援更廣)
ffmpeg -i out/video.mp4 \
-c:v libvpx-vp9 -crf 30 -b:v 0 \
-vf "scale=1280:720" \
-c:a libopus -b:a 128k \
-deadline good \
out/video-web.webm
GIF(預覽/縮圖用)
# 高品質 GIF(前 5 秒)
ffmpeg -i out/video.mp4 -t 5 \
-vf "fps=15,scale=480:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" \
out/preview.gif
# 較小檔案 GIF
ffmpeg -i out/video.mp4 -t 3 \
-vf "fps=10,scale=320:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" \
out/preview-small.gif
各平台需求快速參考
| 平台 | 最大解析度 | 最大大小 | 最長長度 | 音訊 |
|---|---|---|---|---|
| YouTube | 8K | 256GB | 12 小時 | AAC 48kHz |
| Twitter/X | 1920x1200 | 512MB | 140 秒 | AAC 44.1kHz |
| 4096x2304 | 5GB | 10 分鐘 | AAC 48kHz | |
| Instagram 動態 | 1080x1350 | 4GB | 60 秒 | AAC 48kHz |
| Instagram Reels | 1080x1920 | 4GB | 90 秒 | AAC 48kHz |
| TikTok | 1080x1920 | 287MB | 10 分鐘 | AAC |
批次匯出至所有平台
#!/bin/bash
# 儲存為:export-all-platforms.sh
INPUT="out/video.mp4"
# YouTube(高品質)
ffmpeg -i "$INPUT" -c:v libx264 -preset slow -crf 18 \
-c:a aac -b:a 192k -movflags +faststart \
out/video-youtube.mp4
# Twitter(壓縮)
ffmpeg -i "$INPUT" -c:v libx264 -crf 24 \
-vf "scale='min(1280,iw)':'-2'" \
-c:a aac -b:a 128k -movflags +faststart \
out/video-twitter.mp4
# LinkedIn
ffmpeg -i "$INPUT" -c:v libx264 -crf 22 \
-c:a aac -b:a 192k -movflags +faststart \
out/video-linkedin.mp4
# 網頁嵌入(小檔案)
ffmpeg -i "$INPUT" -c:v libx264 -crf 26 \
-vf "scale=1280:720" \
-c:a aac -b:a 128k -movflags +faststart \
out/video-web.mp4
echo "已匯出:"
ls -lh out/video-*.mp4
錯誤處理
處理影片時的常見錯誤與修正:
# 檢查 FFmpeg 是否成功
ffmpeg -i input.mp4 -c:v libx264 output.mp4 && echo "成功" || echo "失敗:請檢查輸入檔案"
# 驗證輸出檔案可播放
ffprobe -v error -select_streams v:0 -show_entries stream=codec_name -of csv=p=0 output.mp4
# 取得詳細錯誤資訊
ffmpeg -v error -i input.mp4 -f null - 2>&1 | head -20
處理常見失敗
| 錯誤 | 原因 | 修正 |
|---|---|---|
| "No such file" | 輸入路徑錯誤 | 檢查路徑,路徑含空格時使用引號 |
| "Invalid data" | 輸入檔案損毀 | 重新下載或重新錄製來源 |
| "height not divisible by 2" | 奇數尺寸 | 加入含 trunc 的縮放濾鏡 |
| "encoder not found" | 缺少編碼器 | 安裝完整編碼器的 FFmpeg |
| 輸出 0 位元組 | 無聲失敗 | 檢查完整 ffmpeg 輸出以取得錯誤 |
意見回饋與貢獻
如果本技能缺少資訊或可改進:
- 缺少某個指令? 描述您需要的功能
- 發現錯誤? 告訴我哪裡有問題
- 想貢獻? 我可以協助您:
- 更新此技能以加入改進
- 建立 PR 至 github.com/digitalsamba/claude-code-video-toolkit
只要說「改進此技能」,我就會引導您更新 .claude/skills/ffmpeg/SKILL.md。






