使用FFmpeg进行HLS加密时,能否为每个TS片段配置随机IV?
如何为HLS每个TS片段配置随机IV?
FFmpeg原生不支持自动为每个TS片段生成完全随机的IV(默认要么固定IV,要么按序列递增IV),但可以通过以下两种方式实现需求:
方法一:脚本批量拆分+逐段加密(推荐)
先将源文件拆分为未加密的TS片段,再为每个片段生成随机IV并单独加密,最后手动生成包含对应IV的m3u8列表。
步骤1:拆分源文件为未加密TS片段
用FFmpeg将音频拆分成指定时长的未加密TS片段:
ffmpeg -hide_banner -i audio1.mp3 -i audio2.mp3 \ -map 0 -map 1 \ -c:a aac \ -f segment \ -segment_time 10 \ -segment_format mpegts \ -segment_filename "temp_%v/%03d.ts" \ -var_stream_map "a:0,agroup:music,default:yes,name:mp3 a:1,agroup:audio,default:no,name:music" \ -y
步骤2:编写脚本逐段加密并生成随机IV
以Bash脚本为例,遍历所有未加密片段,为每个片段生成128位随机IV,并用FFmpeg加密:
#!/bin/bash KEY_FILE="keyfile.key" KEY_HEX=$(cat $KEY_FILE | xxd -p) # 处理mp3码率流 for ts in temp_mp3/*.ts; do # 生成16字节(32位十六进制)随机IV RANDOM_IV=$(openssl rand -hex 16) # 输出文件名 OUT_TS="stream_mp3/$(basename $ts)" # 加密TS片段 ffmpeg -i "$ts" \ -c copy \ -encryption_scheme cbc \ -encryption_key $KEY_HEX \ -encryption_iv $RANDOM_IV \ "$OUT_TS" -y # 记录IV到临时文件,用于生成m3u8 echo "$OUT_TS $RANDOM_IV" >> mp3_ivs.txt done # 同理处理music码率流 for ts in temp_music/*.ts; do RANDOM_IV=$(openssl rand -hex 16) OUT_TS="stream_music/$(basename $ts)" ffmpeg -i "$ts" \ -c copy \ -encryption_scheme cbc \ -encryption_key $KEY_HEX \ -encryption_iv $RANDOM_IV \ "$OUT_TS" -y echo "$OUT_TS $RANDOM_IV" >> music_ivs.txt
步骤3:生成包含随机IV的m3u8播放列表
根据记录的IV信息,编写符合HLS规范的m3u8文件,示例格式如下:
#EXTM3U #EXT-X-VERSION:3 #EXT-X-MEDIA-SEQUENCE:0 #EXT-X-ALLOW-CACHE:YES #EXT-X-TARGETDURATION:11 #EXT-X-KEY:METHOD=AES-128,URI="http://example.com/keyfile.key",IV=0xb279c05ae6a3d0ffd45da748cf305dd9 #EXTINF:10.927589, stream_mp3/000.ts #EXT-X-KEY:METHOD=AES-128,URI="http://example.com/keyfile.key",IV=0x4aec782ea1419fb7865ba5452cbd9413 #EXTINF:9.342667, stream_mp3/001.ts
方法二:动态更新keyinfo文件配合periodic_rekey
利用FFmpeg的-hls_flags periodic_rekey特性,该参数会定期重新读取keyinfo.txt,通过脚本实时更新文件中的IV值,实现每个片段使用随机IV:
步骤1:编写IV自动更新脚本
用脚本监控keyinfo.txt的读取事件,每次FFmpeg读取前生成随机IV并写入文件:
#!/bin/bash KEY_INFO="keyinfo.txt" KEY_URL="http://example.com/keyfile.key" KEY_PATH="keyfile.key" while true; do # 等待FFmpeg读取keyinfo文件的事件 inotifywait -e access $KEY_INFO # 生成随机IV RANDOM_IV=$(openssl rand -hex 16) # 更新keyinfo.txt内容 echo -e "$KEY_URL\n$KEY_PATH\n$RANDOM_IV" > $KEY_INFO done
步骤2:启动脚本并运行FFmpeg
先后台启动IV更新脚本,再执行FFmpeg命令:
# 后台运行IV更新脚本 ./update_iv.sh & # 执行FFmpeg命令 ffmpeg -hide_banner -i audio1.mp3 -i audio2.mp3 \ -map 0 -map 1 \ -c:a aac \ -f hls \ -hls_list_size 0 \ -hls_flags independent_segments+periodic_rekey \ -hls_segment_filename "stream_%v/%03d.ts" \ -hls_time 10 \ -master_pl_name master.m3u8 \ -var_stream_map "a:0,agroup:music,default:yes,name:mp3 a:1,agroup:audio,default:no,name:music" \ -hls_key_info_file keyinfo.txt \ "stream_%v/stream.m3u8" -y
注意事项
- 随机IV必须为128位(16字节,对应32个十六进制字符),符合AES-128加密要求
- 确保m3u8中的IV与对应TS片段加密时使用的IV完全一致,否则会导致解密失败
- 多码率流场景下,可根据需求选择为对应片段使用相同IV或各自独立随机IV
内容的提问来源于stack exchange,提问作者LF-DevJourney
相关产品推荐
相关产品推荐

