ffmpeg的基本使用技巧
# 安装
# FFmpeg Mp4加解密
# 基础知识
通过FFmpeg解封装或者封装Mp4容器时,可以进行解密或者加密,这是MP4容器提供的能力。
libavformat/movenc.c
:提供了mov、3gp、mp4、psp、3g2、ipod、ismv和f4v的Muxer。
libavformat/mov.c
:提供了mov、mp4、m4a、3gp、3g2和mj2的Demuxer。
针对加密,libavformat/movenc.c
提供了三个参数:
{ "encryption_scheme", "Configures the encryption scheme, allowed values are none, cenc-aes-ctr", offsetof(MOVMuxContext, encryption_scheme_str), AV_OPT_TYPE_STRING, {.str = NULL}, .flags = AV_OPT_FLAG_ENCODING_PARAM },
{ "encryption_key", "The media encryption key (hex)", offsetof(MOVMuxContext, encryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_ENCODING_PARAM },
{ "encryption_kid", "The media encryption key identifier (hex)", offsetof(MOVMuxContext, encryption_kid), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_ENCODING_PARAM },
1
2
3
2
3
加密时,需要指定上面三个参数。
针对解密,libavformat/mov.c
提供了一个参数:
{ "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM }
1
# 命令行操作
加密一个文件:
ffmpeg -i decryption.mp4 -vcodec copy -acodec copy -encryption_scheme cenc-aes-ctr -encryption_key c7e16c4403654b85847037383f0c2db3 -encryption_kid a7e61c373e219033c21091fa607bf3b8 encryption.mp4
1
播放加密的mp4文件:
ffplay -i encryption.mp4 -decryption_key c7e16c4403654b85847037383f0c2db3
1
针对加密的mp4文件,解密出一个未加密文件:
ffmpeg -decryption_key c7e16c4403654b85847037383f0c2db3 -i encryption.mp4 decryption.mp4
1
# 代码实现
加密:
AVDictionary *opts = NULL;
// 指定加密参数
av_dict_set(&format_opts, "encryption_scheme", "cenc-aes-ctr", 0);
av_dict_set(&format_opts, "encryption_key", "c7e16c4403654b85847037383f0c2db3", 0);
av_dict_set(&format_opts, "encryption_kid", "a7e61c373e219033c21091fa607bf3b8", 0);
ret = avformat_write_header(AVFormatContext, &format_opts);
1
2
3
4
5
6
2
3
4
5
6
解密:
AVDictionary *format_opts = NULL;
// 指定解密key
av_dict_set(&format_opts, "decryption_key", "c7e16c4403654b85847037383f0c2db3", 0);
err = avformat_open_input(&AVFormatContext, "path", AVInputFormat, &format_opts);
1
2
3
4
2
3
4
# 常用技巧
# 使用图片列表生成视频
ffmpeg -r 0.5 -f image2 -i ./%d.png video.webm
1
-r 0.5
表示2秒钟一张图片./%d.png
表示当前文件夹下的有序图片,比如 1.png,2.png-s 640*800
调整分辨率-crf 23
调整视频质量FFMPEG里取值范围为0-51,取值越高内容损失越多,视频质量更差。 ffmpeg的默认值是23,建议的取值范围是17-28。
需求:
- 将图片保存为视频
- 图片数量不是固定的,是由上游的webrtc传下的帧数据,转成的bitmap。所以只要webrtc开着,图片流就一直会有。
- 每帧图像的间隔时间依赖于不同的网络环境,所以不是固定的时间间隔。
ffmpeg -f image2pipe -use_wallclock_as_timestamps 1 -i - -c:v libx264 -pix_fmt yuv420p -vsync passthrough -maxrate 5000k -an -y 123.mp4
1
-c:v libx265
编码格式h265-f image2pipe
使用图片管道,我们可以将图片数据一直往管道里塞,ffmpeg会不断将其添加到mp4文件中。用来满足需求1和2.-use_wallclock_as_timestamps 1
开启此选项,ffmpeg就会将接收此图片的时间作为该帧的timestamp。这样生成的MP4播放速度才正常,满足需求3.-pix_fmt yuv420p
设置像素格式,解决生成的视频无法使用windows media player播放的问题。-vsync passthrough
可以理解为动态帧率,根据上游的帧率来决定输出mp4的帧率。默认有以下几个选项passthrough
使用帧原始的timestamp.cfr (1)
根据输出帧率的配置,进行自动插帧(上游帧率小于输入帧率)或者丢帧(上游帧率大于输入帧率)。vfr (2)
类似于passthrough, 不过当两帧具有timestamp时会丢弃其中一个。drop
类似于passthrough,只不过会丢弃帧原始的timstamp,然后重新生成符合帧率要求的timestamp。auto (-1)
默认行为。在cfr和vfr之前自动选择。
-maxrate 5000k
设置最大比特率
# 将多个视频合成一个视频
ffmpeg -f concat -i file.txt -c copy output.mp4
1
file.txt
file '1.mp4'
file '2.mp4'
file '3.mp4'
file '4.mp4'
1
2
3
4
2
3
4
# 将webm转为MP4
ffmpeg -i 3.webm -crf 17 -c:v libx264 3.mp4
1
上次更新: 2023/09/22, 16:54:32