用於影片製作的 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 vs Remotion 的 playbackRate:
| 情境 | 使用 FFmpeg | 使用 Remotion |
|---|---|---|
| 恆定速度(1.5 倍、2 倍) | 兩者皆可 | ✅ 更簡單 |
| 極端速度(>4 倍或 <0.25 倍) | ✅ 更可靠 | 可能會有問題 |
| 可變速度(隨時間加速) | ✅ 預先處理 | 需要複雜的變通方法 |
| 需要完美的音訊同步 | ✅ 保證 | 通常沒問題 |
| 演示需要配合配音時間 | ✅ 預先計算 | 執行時調整 |
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)
極端速度(>2 倍音訊): 連結 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
常見問題
"Height not divisible by 2"
加入 scale 濾鏡:-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 偏好使用 AAC 音訊的 MP4,最長 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 的 scale 濾鏡 |
| "encoder not found" | 缺少編解碼器 | 安裝完整編解碼器的 FFmpeg |
| 輸出為 0 位元組 | 靜默失敗 | 檢查完整的 ffmpeg 輸出以取得錯誤資訊 |
意見回饋與貢獻
如果此技能缺少資訊或可以改進:
- 缺少某個指令? 描述您需要的功能
- 發現錯誤? 告訴我哪裡有問題
- 想貢獻? 我可以幫助您:
- 使用改進內容更新此技能
- 向 github.com/digitalsamba/claude-code-video-toolkit 建立 PR
只需說「改進此技能」,我將引導您更新 .claude/skills/ffmpeg/SKILL.md。