提示

FFmpeg 从入门到放弃:我的踩坑记录与常用命令

最近在做一个视频转码的小工具,折腾 FFmpeg 折腾了两天,踩了七八个坑。干脆把过程整理出来,方便自己以后查阅,也给同样在坑里的朋友一点参考。

一、为什么还要用 FFmpeg

现在剪映、PR 满天飞,但做批量处理、服务器端转码、或者简单的水印/格式转换,FFmpeg 还是绕不开。命令行一敲搞定的事情,没必要开个几百兆的 GUI。

二、安装(顺便说说我遇到的坑)

Linux (Ubuntu/Debian)

sudo apt update
sudo apt install ffmpeg

看似简单,但 apt 带的版本通常老半年以上。我一开始没注意,结果用某些新滤镜的时候报错 No such filter。后来还是老老实实从源码编译——但其实有更简单的办法:用静态编译好的二进制包。

推荐去 johnvansickle.com/ffmpeg 下载静态构建版本,解压丢到 /usr/local/bin 就行,省事。

macOS

brew install ffmpeg

注意 brew 默认不会开启所有编解码器,比如我想用 libx265,得额外装:

brew install ffmpeg --with-libx265
# 新版brew改了,要用:
brew install ffmpeg
# 然后看提示,可能需要 brew reinstall ffmpeg --enable-xxx ?其实现在 homebrew-ffmpeg 也有额外 tap

反正我踩过:转码时提示 Unknown encoder 'libx265',才发现没装全。建议直接 brew install ffmpeg --with-* 把常用库都加上,或者跑一次 ffmpeg -encoders | grep x265 确认。

Windows

去官网下载 ffmpeg-release-full.7z,解压后把 bin 目录加到系统环境变量 PATH。记得下 full 版,不然缺库。我朋友下过 essentials 版,连 h264 都转不了。

安装完后验证:

ffmpeg -version

看到一堆配置选项(比如 --enable-libx264)就对了。

三、快速测试:一行命令转码

随便找个 mp4 文件,转成 h265 试试:

ffmpeg -i input.mp4 -c:v libx265 -preset medium -crf 28 output.mp4

如果跑通了,FFmpeg 基本可用。注意 preset 和 crf 是控制质量/速度的,后面会讲。

四、常用参数(我实际工作中用到的)

4.1 基础参数

参数             含义                                  例子
-i           输入文件                                 -i video.mp4
-y           覆盖输出文件不询问        写脚本时必加
-an          不要音频                                 只取视频流
-vn          不要视频                                只取音频或静图
-t            时长    -t 30                               只处理前30秒
-ss           起始时间点                       -ss 00:01:00 从1分钟开始
-to           结束时间点                       -ss 00:01 -to 00:02

4.2 视频编码参数

我常用这套组合拳:

-c:v libx264    # 用h264编码,兼容性好
-c:v libx265    # 用h265编码,文件小但编码慢
-preset faster  # 可选: ultrafast, faster, fast, medium, slow, veryslow ... 越慢压缩率越高
-crf 23         # 质量,0-51,值越小质量越高,默认23,18左右视觉无损
-profile:v high # 高级profile,不写有时默认main

踩坑提醒:-preset veryfast 和 -preset slower 出来的文件大小能差一倍,但编码时间差十几倍。不一定越慢越好,我一般用 fast 或 medium。

4.3 音频编码

-c:a aac -b:a 128k   # aac 码率128k
-c:a mp3 -b:a 192k

注意:如果原视频是多音轨(比如带两条评论音轨),想保留第一条:

-map 0:v:0 -map 0:a:0

五、实战:几个我常用的命令

  1. 压缩视频到指定大小(近似)
ffmpeg -i input.mp4 -b:v 1M -maxrate 1.5M -bufsize 2M -b:a 128k output.mp4

用 -b:v 指定视频平均码率,可以预估文件大小。但 crf 方式更智能,除非你严格需要 ≤100MB 才用这招。

  1. 去掉片头片尾 (30秒到1分45秒)
ffmpeg -i input.mp4 -ss 30 -to 105 -c copy output.mp4

-c copy 表示不重新编码,直接复制流,速度快到飞起。但注意切割点不精确(因为关键帧问题),如果要求精确到帧,不要用 copy,而是重新编码。

  1. 添加水印(图片)
ffmpeg -i video.mp4 -i logo.png -filter_complex "overlay=10:10" output.mp4

水印位置是左上角 (10,10)。想放右下角?计算视频宽高:overlay=W-w-10:H-h-10。踩坑:png 必须带透明通道,否则会挡住画面。

  1. 批量转码(bash 循环)
for f in *.avi; do 
  ffmpeg -i "$f" -c:v libx264 -c:a aac "${f%.avi}.mp4"
done

Windows 下用 for %f in (*.avi) do ffmpeg -i "%f" ...。注意文件名有空格要加双引号,我第一次忘加了,炸了一堆。

六、问题汇总(都是我真实遇到的)

  1. Unknown encoder 'libx264'
原因:编译时没开启 x264 支持。
解决:换完整版二进制,或者自己编译加 --enable-libx264。
检查方法:ffmpeg -encoders | grep x264
  1. 音视频不同步
常见场景:从网络流录制,或者用 -ss  -c copy 切割时。
原因:-ss 放在 -i 前面和后面行为不一样。
解法:

    如果要用 -c copy 快速切割,把 -ss 放在 -i 后面:ffmpeg -i input -ss 30 -t 10 -c copy out.mp4 (但这样首帧可能不精确)
    需要精确到帧,去掉 -c copy:ffmpeg -ss 30 -i input -t 10 -c:v libx264 out.mp4(慢但准)
  1. 转出来的视频播放器打不开,但 VLC 能开
    原因:可能是 moov 原子不在文件头部。流媒体播放需要 faststart。
    解决:加参数 -movflags +faststart:
ffmpeg -i input.mp4 -c copy -movflags +faststart output.mp4
  1. 处理速度太慢,CPU 吃满
FFmpeg 默认充分利用多核,但有些滤镜(比如 scale)是单线程的。如果想限制 CPU 占用,用 -threads 2 限制线程数。
另外 -preset ultrafast 会快很多,但文件体积飙升。
  1. “Buffer queue overflow, dropping frames”
原因:复杂滤镜链(比如同时缩放、加水印、调色)时,其中一个滤镜处理速度跟不上。
解决:在滤镜后面加 -max_muxing_queue_size 1024,或者简化滤镜链,分步处理。
  1. 从视频提取帧为图片,结果全是花屏
ffmpeg -i video.mov -vf "fps=1" out%d.png

踩坑:视频如果是非标准格式(比如某些相机拍的 H.264 编码 mov),用 -vf 之前最好先转成 yuv420p:

ffmpeg -i video.mov -pix_fmt yuv420p -vf "fps=1" out%d.png
  1. 合并多个视频,结果画面卡在第一个视频最后一帧
    典型错误:用 concat 协议没加 -c copy,或者各视频的编码参数不一致(比如有的有 b 帧,有的没有)。
    正确做法:先确保所有视频参数一致(分辨率、fps、编码格式),然后用:
ffmpeg -f concat -safe 0 -i mylist.txt -c copy merged.mp4

mylist.txt 内容:

file 'part1.mp4'
file 'part2.mp4'

七、一点小建议

每次调参数前,先用 -t 10 截一小段测试,别拿大文件硬扛。

保存常用命令为别名或脚本,比如 alias compress='ffmpeg -i "$1" -c:v libx265 -crf 24 "$1"_compressed.mp4'

FFmpeg 官方文档很全但不友好,遇到问题先搜错误信息 + “FFmpeg”,Stack Overflow 一般有答案。

最后,不要试图记住所有参数,记住 -i、-c copy、-ss、-to、-crf、-preset 这六七个就够了。其他的随用随查。

写完这篇博客,我发现我并不是「从入门到放弃」,而是「从入门到还债」——每次用一次就改一次脚本,加一个新的 -movflags。欢迎补充你遇到过的奇葩问题。
顶部
×
🔖
收藏本站
将本站添加到浏览器书签,方便下次访问
Ctrl + D (Windows/Linux)
+ D (Mac)