FFmpeg 是视频处理最常用的开源软件,这是它命令行工具的说明文档:ffmpeg Documentation。
A complete, cross-platform solution to record, convert and stream audio and video.
几个基本概念(FFmpeg 视频处理入门教程):
容器
视频文件本身是一个容器,里面包括了视频和音频,以及字幕等其他内容。
一般来说,视频文件的后缀名反映了它的容器格式。譬如:mp4、mkv、avi,命令 ffmpeg -formats
可以查看支持的容器。
编码
视频和音频都需要经过编码,才能保存成文件。不同的编码格式(CODEC),有不同的压缩率,会导致文件大小和清晰度的差异。
常见的视频编码:H.262、H.264、H.265,常见的音频编码:mp3、aac,命令 ffmpeg -codecs
可以查看支持的编码格式。
编/解码器
顾名思义编/解码器就是用来实现某种编/解码的库文件。
一些常见的视频编码器:
- libx264:最流行的开源 H.264 编码器
- NVENC:基于 NVIDIA GPU 的 H.264 编码器
- libx265:开源的 HEVC 编码器
- libvpx:谷歌的 VP8 和 VP9 编码器
- libaom:AV1 编码器
一些常见的音频编码器:
- libfdk-aac
- aac
命令:ffmpeg -encoders
、ffmpeg -decoders
软编码:使用CPU进行编码。实现直接、简单,参数调整方便,升级易,但 CPU 负载重,性能较硬编码低,低码率下质量通常比硬编码要好。
硬编码:使用非 CPU 进行编码,如显卡 GPU、专用的 DSP、FPGA、ASIC 芯片等。性能高,低码率下通常质量低于软编码器,但部分产品在 GPU 硬件平台移植了优秀的软编码算法(如 X264),质量基本等同于软编码。
- h264_amf to access AMD gpu, (windows only)
- h264_nvenc use nvidia gpu cards (work with windows and linux)
- h264_omx raspberry pi encoder
- h264_qsv use Intel Quick Sync Video (hardware embedded in modern Intel CPU)
- h264_v4l2m2m use V4L2 Linux kernel api to access hardware codecs
- h264_vaapi use VAAPI which is another abstraction API to access video acceleration hardware (Linux only)
- h264_videotoolbox use videotoolbox an API to access hardware on macOS
libx264 is the default encoder which does not use any specific hardware this can be changed to the desired encoder.
1. 命令及参数
ffmpeg 命令格式:ffmpeg {1} {2} -i {3} {4} {5}
- 全局参数
- 输入文件参数
- 输入文件
- 输出文件参数
- 输出文件
2-3,4-5 都是可以存在多次的,分别表示以多个源做为输入和输出到不同的目的地。
常用的命令行参数如下:
-c
:指定编码器-c:v
:指定视频编码器-c:a
:指定音频编码器-c copy
:直接复制,不经过重新编码(这样比较快)-an
:去除音频流-vn
:去除视频流-y
:不经过确认,输出时直接覆盖同名文件。- -hide_banner:不打印 copyright notice, build options and library versions 等信息
- -f:输入、输出格式
- -t:时长
- -vframes:视频输出的总帧数
- -r:每秒帧数(fps)
- -s:分辨率
- -aframes:音频输出总帧数
- -ar:音频采样率
- -ac:音频通道数
- -b:v:视频码率
- -b:a:音频码率
2. 常见用法
查看视频信息:ffmpeg -i input.mp4
转码:ffmpeg -i input.mp4 -c:v libx264 output.mp4
转容器:ffmpeg -i input.mp4 -c copy output.avi
提取音频:ffmpeg -i input.mp4 -c:a copy -vn output.aac
提取视频:ffmpeg -i input.mp4 -c:v copy -an output.mp4
添加音轨:ffmpeg -i input.aac -i input.mp4 output.mp4
添加封面:ffmpeg -loop 1 -i cover.jpg -i input.mp3 -c:v libx264 -c:a aac -b:a 192k -shortest output.mp4
,-shortest
参数表示音频文件结束,输出视频就结束。
截图:
1
2
3
4
5
6
# 截一张图则只截取一帧,-q:v 2 表示输出的图片质量,一般是 1 到 5 之间(1 为质量最高)
ffmpeg -i input.mp4 -ss 01:23:45 -vframes 1 -q:v 2 output.jpg
# -r 表示每一秒几帧
ffmpeg -i input.mp4 -r 1 -q:v 2 -f image2 pic-%03d.jpeg
# 从 ss 开始截取 10s,每秒 1 帧
ffmpeg -i input.mp4 -ss 00:00:20 -t 10 -r 1 -q:v 2 -f image2 pic-%03d.jpeg
剪切视频:ffmpeg -ss 00:00:15 -t 00:00:05 -i input.mp4 -c copy output.mp4
,从 15 秒开始剪切 5 秒的视频。
码率控制:
1
2
3
ffmpeg -i input.mp4 -b:v 2M output.mp4
ffmpeg -i input.mp4 -b:v 2M -bufsize 2M output.mp4
ffmpeg -i input.mp4 -b:v 2M -bufsize 2M -maxrate 2.5M output.mp4
更改分辨率:ffmpeg -i input.mp4 -vf scale=480:-1 output.mp4
,-1 表示保持原始宽高比。
加水印:
1
2
3
4
5
6
7
8
# 左上角
ffmpeg -i input.mp4 -i logo.png -filter_complex overlay output.mp4
# 右上角
ffmpeg -i input.mp4 -i logo.png -filter_complex overlay=W-w output.mp4
# 左下角
ffmpeg -i input.mp4 -i logo.png -filter_complex overlay=0:H-h output.mp4
# 右下角:
ffmpeg -i input.mp4 -i logo.png -filter_complex overlay=W-w:H-h output.mp4
去水印:
1
2
3
4
5
6
# 语法:-vf delogo=x:y:w:h[:t[:show]]
# x:y 离左上角的坐标
# w:h logo 的宽和高
# t: 矩形边缘的厚度默认值 4
# show:若设置为 1 有一个绿色的矩形,默认值 0
ffmpeg -i input.mp4 -vf delogo=0:0:220:90:100:1 output.mp4
2.1 录制
麦克风:
1
2
3
4
5
6
7
8
# 列出声卡
$ arecord -l
card 1: U0x46d0x81b [USB Device 0x46d:0x81b], device 0: USB Audio [USB Audio]
...
$ ffmpeg -f alsa -ac 1 -i hw:1 -c:a aac output.mp3
# 或
$ ffmpeg -f alsa -ac 1 -i front:CARD=U0x46d0x81b -c:a aac out.mp3
摄像头:
1
ffmpeg -f v4l2 -s 640x480 -i /dev/video0 -b:v 1.5M -c:v libx264 -r 25 -s 640x480 out.mp4
桌面:
1
ffmpeg -f x11grab -s 1920x1080 -i :0.0 -c:v libx264 out.mp4
录制桌面+摄像头+麦克风:
1
ffmpeg -thread_queue_size 10240 -f x11grab -s 1920x1080 -i :0.0 -f v4l2 -s 640x480 -i /dev/video0 -f alsa -ac 1 -i hw:1 -filter_complex '[0:v][1:v]overlay=x=main_w-overlay_w-10:y=main_h-overlay_h-10[out]' -map '[out]' -map 2:a -c:v libx264 -c:a aac output.mp4
直播推流:
1
ffmpeg -thread_queue_size 10240 -f alsa -ac 1 -i hw:1 -f v4l2 -s 640x360 -i /dev/video0 -r 25 -s 640x360 -b:v 1.5M -c:v h264_omx -b:a 128k -f flv rtmp://xxx:1935/xxx/xxx