FFmpeg 视频转码怎么做?常用格式转换命令和参数详解
视频转码 = 解码 + 重新编码。最简单的形式是换个容器(MP4 转 MKV),最复杂的是同时改编码器、分辨率、码率、帧率。FFmpeg 一条命令搞定。
最基本的转码
bash# 让 FFmpeg 自动选择编码器(按输出文件后缀推断) ffmpeg -i input.avi output.mp4
这样 FFmpeg 会自动把 AVI 里的 MPEG-4 视频转成 H.264,音频转成 AAC。简单但不可控——你不知道它选了什么参数。
明确指定编码器:
bashffmpeg -i input.avi -c:v libx264 -c:a aac output.mp4
-c:v 指定视频编码器,-c:a 指定音频编码器。这是转码命令的基本骨架,所有高级参数都加在这个基础上。
常见转码场景
AVI/MKV 转 MP4(最常见)
bashffmpeg -i input.mkv -c:v libx264 -crf 23 -c:a aac -b:a 128k output.mp4
如果原视频已经是 H.264 编码,不需要重编码视频流,只换个容器:
bashffmpeg -i input.mkv -c:v copy -c:a aac -b:a 128k output.mp4
-c:v copy 直接拷贝视频流,几秒完成。但 MKV 支持的编码器比 MP4 多——如果 MKV 里是 H.265 或 VP9,copy 到 MP4 后部分播放器可能不兼容。
转 WebM(网页视频)
bashffmpeg -i input.mp4 -c:v libvpx-vp9 -crf 30 -b:v 0 -c:a libopus output.webm
VP9 编码必须用 -b:v 0 配合 CRF 模式,否则 CRF 不生效。Opus 是 WebM 的标准音频编码器,音质优于 AAC。
转 H.265(省空间)
bashffmpeg -i input.mp4 -c:v libx265 -crf 28 -c:a aac -b:a 128k output.mp4
H.265 的 CRF 28 大约等于 H.264 的 CRF 23,文件小 30-50%。编码慢 3-5 倍,老设备可能播不了。
只转视频或只转音频
bash# 只转视频,音频原样拷贝 ffmpeg -i input.mp4 -c:v libx264 -crf 23 -c:a copy output.mp4 # 只转音频,视频原样拷贝 ffmpeg -i input.mp4 -c:v copy -c:a aac -b:a 128k output.mp4 # 去掉视频只保留音频 ffmpeg -i input.mp4 -vn -c:a aac -b:a 128k output.aac
-vn 去掉视频,-an 去掉音频,-sn 去掉字幕。转码时去掉不需要的流可以节省时间。
硬件加速转码
CPU 编码太慢?用 GPU 加速:
bash# NVIDIA GPU(NVENC) ffmpeg -hwaccel cuda -i input.mp4 -c:v h264_nvenc -preset p4 -cq 23 -c:a aac output.mp4 # Intel GPU(QSV) ffmpeg -hwaccel qsv -i input.mp4 -c:v h264_qsv -preset medium -c:a aac output.mp4 # Apple Silicon(VideoToolbox) ffmpeg -hwaccel videotoolbox -i input.mp4 -c:v h264_videotoolbox -b:v 5M -c:a aac output.mp4
硬件编码速度是 CPU 的 5-10 倍,但同码率下画质略差(约 5-10%)。如果追求极致画质用 CPU libx264,追求速度用 NVENC。-preset p4 是 NVENC 的质量档位,p1 最快 p7 最慢质量最好。
转码时调分辨率和帧率
bash# 1080p 转 720p ffmpeg -i input.mp4 -vf "scale=1280:720" -c:v libx264 -crf 23 -c:a copy output.mp4 # 保持宽高比,只限宽度 ffmpeg -i input.mp4 -vf "scale=1280:-2" -c:v libx264 -crf 23 -c:a copy output.mp4 # 降帧率 60fps -> 30fps ffmpeg -i input.mp4 -r 30 -c:v libx264 -crf 23 -c:a copy output.mp4
-2 让 FFmpeg 自动计算高度保持比例,必须用偶数(有些编码器要求宽高都是偶数)。
两遍编码:精确控制文件大小
CRF 模式无法精确控制输出文件大小。如果需要视频刚好 100MB:
bash# 第一遍:分析(不输出视频) ffmpeg -i input.mp4 -c:v libx264 -b:v 1500k -pass 1 -an -f null /dev/null # 第二遍:实际编码 ffmpeg -i input.mp4 -c:v libx264 -b:v 1500k -pass 2 -c:a aac -b:a 128k output.mp4
第一遍分析视频复杂度分布,第二遍据此分配码率。两遍编码比单遍 CRF 质量稍好,但编码时间翻倍。通常只在需要精确文件大小(如 DVD/蓝光)时才用。