← All posts

如何用 FFmpeg 转换视频格式

FFmpeg 视频转格式实操:MP4、MOV、AVI、WebM、MKV 互转,编码器选择、画质控制、批量脚本。

FFHub·2026-04-21
如何用 FFmpeg 转换视频格式

视频转格式是日常处理中最常见的活——网页要 MP4、Apple 工作流要 MOV、开源项目要 WebM。FFmpeg 一条命令搞定。这篇文章从最简单的命令讲起,到编码器选择和批量脚本。

最简单的转格式

只换容器格式时,FFmpeg 会根据输出文件后缀自动决定目标格式:

# Convert MKV to MP4
ffmpeg -i input.mkv output.mp4

# Convert AVI to MOV
ffmpeg -i input.avi output.mov

# Convert MP4 to WebM
ffmpeg -i input.mp4 output.webm

不指定编码器时,FFmpeg 会按目标容器选默认值。能跑通,但画质和兼容性都不在你手里。

容器和编码器是两回事

往下看之前先把这两个概念分清楚:

  • 容器(container):MP4、MKV、MOV、AVI、WebM——装视频、音频、元数据的"盒子"
  • 视频编码器(codec):H.264、H.265、VP9、AV1——视频数据怎么压
  • 音频编码器:AAC、Opus、MP3、FLAC——音频数据怎么压

容器是盒子,编码器是装在里面的东西。同一个编码器可以放进不同容器。

容器常见视频编码器常见音频编码器适合场景
MP4H.264、H.265、AV1AAC、MP3网页、移动端、通用
MKV任意任意存档、多轨
MOVH.264、H.265、ProResAAC、PCMApple、剪辑
WebMVP8、VP9、AV1Vorbis、Opus网页(开源)
AVIH.264、MPEG-4MP3、PCM老设备兼容

怎么选编码器

H.264:兼容性最好

H.264(libx264)几乎所有设备和浏览器都能播。要保证别人都能打开,选它。

ffmpeg -i input.avi -c:v libx264 -crf 23 -preset medium -c:a aac -b:a 128k output.mp4

H.265 (HEVC):体积更小

同画质下文件体积大约减一半。代价是支持还没普及。

ffmpeg -i input.avi -c:v libx265 -crf 28 -preset medium -c:a aac -b:a 128k output.mp4

注意 H.265 的 CRF 刻度和 H.264 不一样。H.265 的 CRF 28 大致等价于 H.264 的 CRF 23。

VP9:免版税,网页友好

VP9 是 Google 的免版税编码器,配 WebM 容器,所有现代浏览器都支持。

ffmpeg -i input.mp4 -c:v libvpx-vp9 -crf 30 -b:v 0 -c:a libopus -b:a 128k output.webm

-b:v 0 是告诉 FFmpeg 走纯 CRF 模式(不限码率上限)。

AV1:下一代,但很慢

压缩率最强,编码速度也最慢。不赶时间、文件越小越好时再用。

ffmpeg -i input.mp4 -c:v libaom-av1 -crf 30 -cpu-used 4 -c:a libopus -b:a 128k output.mkv

-cpu-used 4 是个加速档位(0-8,越大越快但画质会降)。

编码器横向对比

编码器压缩率速度浏览器支持授权
H.264一般全平台需授权
H.265较好在普及需授权
VP9较好现代浏览器免版税
AV1最好很慢在普及免版税

音频编码器怎么配

不同容器有自己适合的音频编码器:

# MP4 + AAC(最常见)
ffmpeg -i input.mkv -c:v libx264 -crf 23 -c:a aac -b:a 192k output.mp4

# WebM + Opus(同码率下音质最好)
ffmpeg -i input.mp4 -c:v libvpx-vp9 -crf 30 -b:v 0 -c:a libopus -b:a 128k output.webm

# MKV + FLAC(无损音频)
ffmpeg -i input.mov -c:v libx264 -crf 18 -c:a flac output.mkv

# MOV + PCM(未压缩,剪辑用)
ffmpeg -i input.mp4 -c:v copy -c:a pcm_s16le output.mov
音频编码器音质体积适配容器
AAC一般MP4、MOV
Opus优秀最小WebM、MKV
MP3一般MP4、AVI、MKV
FLAC无损MKV
PCM无损很大MOV、WAV

流复制:秒转

源文件的编码器和目标容器兼容时,直接复制流不重新编码。瞬时完成、无损:

# MKV 重新封装成 MP4,不重编码
ffmpeg -i input.mkv -c copy output.mp4

# 视频流直接复制,只重编音频
ffmpeg -i input.mkv -c:v copy -c:a aac -b:a 128k output.mp4

只有目标容器支持该编码器时才能流复制。比如 VP9 装不进 AVI。

画质和体积怎么平衡

CRF 模式:本地文件首选

CRF(Constant Rate Factor,恒定质量因子)画质和体积比最划算,编码器会按场景动态调码率。压缩相关的细节可以看视频压缩教程

# 高画质(文件大)
ffmpeg -i input.avi -c:v libx264 -crf 18 -c:a aac -b:a 192k output.mp4

# 平衡
ffmpeg -i input.avi -c:v libx264 -crf 23 -c:a aac -b:a 128k output.mp4

# 小文件(画质降)
ffmpeg -i input.avi -c:v libx264 -crf 28 -c:a aac -b:a 96k output.mp4

双 pass 编码:要精确控大小

需要把文件压到指定大小时用 two-pass:

# Pass 1:分析
ffmpeg -i input.avi -c:v libx264 -b:v 2M -pass 1 -an -f null /dev/null

# Pass 2:编码
ffmpeg -i input.avi -c:v libx264 -b:v 2M -pass 2 -c:a aac -b:a 128k output.mp4

preset:速度换体积

同画质下,preset 越慢文件越小:

# 编码快,文件大
ffmpeg -i input.avi -c:v libx264 -crf 23 -preset fast -c:a aac output.mp4

# 编码慢,文件小
ffmpeg -i input.avi -c:v libx264 -crf 23 -preset slow -c:a aac output.mp4

转格式时顺手改分辨率

格式和缩放可以一起做:

# 转成 720p MP4
ffmpeg -i input.mkv -c:v libx264 -crf 23 -vf "scale=-2:720" -c:a aac -b:a 128k output.mp4

# 转成 1080p WebM
ffmpeg -i input.avi -c:v libvpx-vp9 -crf 30 -b:v 0 -vf "scale=-2:1080" -c:a libopus output.webm

批量脚本

转换整个目录

# 所有 AVI 转 MP4
for f in *.avi; do
  ffmpeg -i "$f" -c:v libx264 -crf 23 -c:a aac -b:a 128k "${f%.avi}.mp4"
done

# 所有 MKV 流复制成 MP4
for f in *.mkv; do
  ffmpeg -i "$f" -c copy "${f%.mkv}.mp4"
done

一份源文件输出多种格式

#!/bin/bash
# 一个源文件批量输出多种格式
INPUT="input.mp4"

# 网页用 MP4
ffmpeg -i "$INPUT" -c:v libx264 -crf 23 -preset medium -c:a aac -b:a 128k -movflags +faststart web.mp4

# 高质量 MKV 存档
ffmpeg -i "$INPUT" -c:v libx265 -crf 22 -preset slow -c:a flac archive.mkv

# WebM 走开源托管
ffmpeg -i "$INPUT" -c:v libvpx-vp9 -crf 30 -b:v 0 -c:a libopus -b:a 128k web.webm

递归转换

# 递归找所有 AVI 转 MP4
find . -name "*.avi" -exec sh -c '
  ffmpeg -i "$1" -c:v libx264 -crf 23 -c:a aac "${1%.avi}.mp4"
' _ {} \;

网页 MP4 必加 faststart

MP4 给网页播时一定要加 -movflags +faststart,把元数据挪到文件头,这样还没下完就能开始播:

ffmpeg -i input.mkv -c:v libx264 -crf 23 -c:a aac -movflags +faststart output.mp4

常用场景速查

# iPhone 的 MOV 转 MP4 用于分享
ffmpeg -i input.mov -c:v libx264 -crf 23 -c:a aac -b:a 128k -movflags +faststart output.mp4

# AVI 转 MP4(重编码)
ffmpeg -i input.avi -c:v libx264 -crf 23 -preset medium -c:a aac -b:a 128k output.mp4

# MP4 转 WebM 用于网页嵌入
ffmpeg -i input.mp4 -c:v libvpx-vp9 -crf 30 -b:v 0 -c:a libopus -b:a 128k output.webm

# MKV 流复制成 MP4(无损)
ffmpeg -i input.mkv -c copy -movflags +faststart output.mp4

# 任意视频转 GIF(短片段)
ffmpeg -i input.mp4 -vf "fps=10,scale=320:-1" -t 5 output.gif

# MP4 切成 HLS
ffmpeg -i input.mp4 -c copy -hls_time 10 -hls_list_size 0 output.m3u8

常见坑

"Discarding packet" 警告:源容器有点问题。加 -err_detect ignore_err 跳过坏包。

"Non-monotonous DTS" 报错:时间戳乱了。加 -fflags +genpts 重建:

ffmpeg -i input.mkv -fflags +genpts -c:v libx264 -crf 23 -c:a aac output.mp4

容器不接受这个编码器:典型例子,VP9 塞不进 AVI。要么换容器,要么重编成兼容的编码器。

输出比输入还大:从高效编码器转回低效编码器,或者源已经被压得很狠。降 CRF 或者换更高效的编码器。

想跑在云上:FFHub

本地转单个文件没问题,但批量任务能把机器锁住几个小时。FFHub 让你通过 API 把同样的 FFmpeg 命令丢到云端跑——语法一样,不占本地 CPU。

适合的场景:批量转换、Web 应用集成、机器上没装 FFmpeg。

小结

  • 编码器兼容时用流复制-c copy)——秒转
  • 通用兼容选 H.264 + AAC + MP4
  • 网页免版税选 VP9 + Opus + WebM
  • 看重画质走 CRF 模式
  • 网页 MP4 别忘了 -movflags +faststart
  • 整目录处理写个批量脚本

延伸阅读

如何用 FFmpeg 转换视频格式 | FFHub