使用 FFmpeg 生成 ts 切片并使用 AES-128 加密
0x00 基本流程
- 目的:使用 FFmpeg 将一个 MP4 视频文件切割成多个 ts 切片,并在生成 ts 切片过程中对每一个切片使用 AES-128 加密,最后生成一个包含解密 Key 的 m3u8 视频播放索引文件。这些被加密的 ts 切片无法在其他地方播放,必须使用 m3u8 文件包含的解密 key 才可以。
- 工具:需要在 PC 配置 FFmpeg 环境,通过 Dos 命令行生成 ts 切片 + m3u8 配置文件,加密 key 文件需要配置 OpenSSL 来生成加密文件或者直接随便手写一段字符串也可以,区别是手写的是明文加密,使用 OpenSSL 生成的加密 key 文件是看不到明文的。
0x01 环境配置
0x02 使用 OpenSSL 生成密钥
openssl rand 16 > [你的密钥文件路径] 例 D:\encrypt.key
openssl rand -hex 16
0x03 使用 FFmpeg 生成加密文件
- 一行命令同时生成 ts 切片,m3u8 索引播放文件并加密
ffmpeg -y -i [原始视频文件路径] -c:v libx264 -c:a copy -f hls -hls_time 180 -hls_list_size 0 -hls_key_info_file [密钥文件路径] -hls_playlist_type vod -hls_segment_filename [切片文件路径] [索引文件路径]
-y |
直接覆盖已经存在的输出文件 |
-c |
指定输入输出的解码编码器 |
-f |
强制设置输入输出的文件格式,默认情况下ffmpeg会根据文件后缀名判断文件格式 |
-hls_time |
指定生成 ts 视频切片的时间长度s |
-hls_list_size 0 |
索引播放列表的最大列数 默认5,0 为不限制 |
-hls_playlist_type vod |
表示当前的视频流并不是一个直播流,而是点播流 |
-hls_segment_filename |
输出 ts m3u8 文件路径 |
- [原始文件路径] 例 D:\test.mp4
- [密钥文件路径] 文件后缀名需为 .keyinfo 否则可能会找不到解密文件,例 D:\key.keyinfo
- [切片文件路径] 例 D:\test_%03d.ts
- [索引文件路径] 例 D:\test.m3u8
0x04 相关参数与格式说明
#EXTM3U |
每个M3U文件第一行必须是这个tag |
#EXTINF:, |
duration表示持续的时间(秒)必须是整数,如果版本在3以上可以是浮点数 |
#EXTINF |
指定每个媒体段(ts)的持续时间,这个仅对其后面的URI有效,每两个媒体段URI间被这个tag分隔开 |
#EXT-X-TARGETDURATION |
指定最大的媒体段时间长(秒)。所以#EXTINF中指定的时间长度必须小于或是等于这个最大值。这个tag在整个PlayList文件中只能出现一次(在嵌套的情况下,一般有真正ts url的m3u8才会出现该tag) 格式如下:#EXT-X-TARGETDURATION: :s表示最大的秒数
|
#EXT-X-MEDIA-SEQUENCE |
每一个media URI 在 PlayList中只有唯一的序号,相邻之间序号+1 |
#EXT-X-KEY |
表示怎么对media segments进行解码。其作用范围是下次该tag出现前的所有media URI 格式如下:#EXT-X-KEY::NONE 或者 AES-128。如果是NONE,则URI以及IV属性必须不存在,如果是AES-128(Advanced Encryption Standard),则URI必须存在,IV可以不存在。对于AES-128的情况,keytag和URI属性共同表示了一个key文件,通过URI可以获得这个key,如果没有IV(Initialization Vector),则使用序列号作为IV进行编解码,将序列号的高位赋到16个字节的buffer中,左边补0;如果有IV,则将改值当成16个字节的16进制数。 |
#EXT-X-ALLOW-CACHE: |
是否允许做cache,这个可以在PlayList文件中任意地方出现,并且最多出现一次,作用效果是所有的媒体段 格式如下:#EXT-X-ALLOW-CACHE:YES、NO
|
- key.keyinfo 文件规则,该文件内容一共为三行
第一行 |
decrypt.key 文件路径 |
第二行 |
加密 encrypt.key 文件路径 |
第三行 |
IV 非必须 |
解密与加密 key 文件可以使用同一个
原文:使用 FFmpeg 生成 ts 切片并使用 AES-128 加密 · Qu