FFmpeg

1   基础

ffmpeg -i input.avi -metadata key=value -codec copy output.avi
ffprobe "file" #查看metadata

1.1   查询命令

1
2
3
4
5
ffmpeg.exe -h -> help.txt # 打印帮助文件
ffmpeg -h encoder=libx264
ffmpeg -hwaccels # 查看支持的硬件加速选项
ffmpeg -codecs | grep cuvid # 查看cuvid提供的GPU编解码器(grep为Linux命令)
ffmpeg -f lavfi -i nullsrc -c:v nvenc -gpu list -f null none_output (-hwaccel_device N 和 -gpu N)

1.2   硬件编码

1
2
3
4
5
6
-c:v h264_nvenc -rc:v vbr_hq -cq:v 19 -b:v 2500k -maxrate:v 5000k -profile:v high
ffmpeg -hwaccel cuvid -c:v h264_cuvid -i <input> -c:v h264_nvenc -b:v 2048k -vf scale_npp=1280:-1 -y <output>
ffmpeg -vsync 0 -hwaccel cuvid -c:v h264_cuvid -i input.mp4 -c:a copy -c:v h264_nvenc -b:v 5M output.mp4
-hwaccel cuda -hwaccel_output_format cuda
ffmpeg -vsync 0 –hwaccel cuvid -c:v h264_cuvid –resize 1280x720 -i input.mp4 -c:a copy -c:v h264_nvenc -b:v 5M output.mp4
ffmpeg -r 30 -f image2 -i %4d.jpg -r 30 -c:v h264_nvenc -profile:v high -level 5.1 -preset slow -rc:v vbr_hq -cq:v 19 -b:v 2500k -maxrate:v 5000k ../output.mp4

2   实战案例

2.1   合并多个视频文件

1
2
3
4
5
6
ffmpeg -f concat -i filelist.txt -c copy output.mp4
# filelist.txt
# file '1.flv'
# file '2.flv'
# file '3.flv'
# file '4.flv'

3   常见知识点

  • yuv420p的p代表planar
  • k和K都是表示$10^3/2^{10}$,K之后的只有大写,比如M表示$10^6/2^{20}$(详见Expression Evaluation
  • bufsize配合maxrate参数使用可控制编码时的码率波动,例如264的cbr恒定码率编码中,同时设置b:v maxrate minrate bufsize(前三个都是设置为1M,bufsize设置为50k,最后编码出来的码率波动最小996kbit/s,1001kbit/s)。bufsize is the "rate control buffer",即码率控制缓存。作用是每次达到bufsize大小,都是计算并调整到average平均码率。
  • filter chain之间的filter用分号,普通的filter之间用逗号
  • aac编码:网络视频128k;高质量192k

4   常见错误/警告

4.1   时间戳问题

常见于 Non-monotonous DTS in output stream

完美的解决方式暂未找到,网上的解决方法基本为:先转为 mts 文件,后转为 mp4。(本质是重新编码,确实可以解决时间戳错误,但也会劣化音质和画质。)

4.2   deprecated pixel format used, make sure you did set range correctly

This is just a warning, not an error. You can safely ignore it when using ffmpeg from the command-line, and you don't have to fix anything.

The warning occurs when converting from a yuv420p source to JPEG, which makes ffmpeg choose yuvj420p as output format. That format is required for writing files with the mjpeg encoder.

These two pixel formats have different color ranges: the former is from 16–235, which is "limited range" (also called "MPEG" range), the latter defaults to 0–255, which is "full range". The warning is meant for using FFmpeg as a library in your own code (like here). See also the comments on this question.