如何用 FFmpeg 转换视频格式

2026/04/21

视频格式转换是媒体处理中最常见的操作之一。无论你需要 MP4 用于网页分发、MOV 用于 Apple 工作流,还是 WebM 用于开源项目,FFmpeg 都能从命令行轻松搞定。本文涵盖从基础转换到高级编码器选择和批量处理的所有内容。

基础格式转换

最简单的转换只需改变容器格式,FFmpeg 会根据输出文件扩展名自动识别目标格式:

# 将 MKV 转为 MP4
ffmpeg -i input.mkv output.mp4

# 将 AVI 转为 MOV
ffmpeg -i input.avi output.mov

# 将 MP4 转为 WebM
ffmpeg -i input.mp4 output.webm

不指定编码器时,FFmpeg 会为目标容器选择默认编码器。这种方式可以用,但无法控制画质和兼容性。

容器与编码器的区别

在深入之前,先了解两个概念:

  • 容器(MP4、MKV、MOV、AVI、WebM)— 存放视频、音频和元数据的文件格式
  • 视频编码器(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) — 压缩率更高

H.265(libx265)在相同画质下文件体积约减少 50%,但支持范围尚未普及。

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

注意:H.265 的 CRF 值体系不同,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 — 下一代编码器

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(恒定质量因子)能提供最佳的画质与体积比。编码器会逐场景调整码率。如果想深入了解压缩技巧,请参阅视频压缩教程

# 高画质(文件较大)
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

双通道编码 — 精确控制文件大小

需要精确控制输出文件大小时,使用双通道编码:

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

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

预设 — 速度与压缩率的平衡

越慢的预设在相同画质下文件越小:

# 快速编码,文件较大
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 文件
find . -name "*.avi" -exec sh -c '
  ffmpeg -i "$1" -c:v libx264 -crf 23 -c:a aac "${1%.avi}.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" 错误 — 源文件时间戳有问题,用以下命令修复:

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 压缩视频 - 使用 CRF、预设和分辨率缩放减小文件体积
  • 如何用 FFmpeg 提取音频 - 从任意视频格式中提取音频轨道
  • FFmpeg 视频压缩最佳实践 - 更高级的编码策略,兼顾画质与体积
FFHub

FFHub

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