http://ffmpeg.org/ffmpeg-all.html#hls-3
21.13 hls
方式一: hls_key_info_file key_info_file
加密
$ catdemo.sh
#!/bin/sh
BASE_URL=$
opensslrand16> file.key
echo$BASE_URL/file.key > file.keyinfo
echofile.key >> file.keyinfo
echo$(openssl rand -hex 16)>> file.keyinfo
exportLD_LIBRARY_PATH=./lib:$LD_LIBRARY_PATH
./bin/ffmpeg-flavfi-re-itestsrc-c:v h264-hls_flagsdelete_segments \
-hls_key_info_filefile.keyinfo out.m3u8
$
解密
方式二
-hls_enc enc
Enable (1) or disable (0) the AES128 encryption. When enabled every segment generated is encrypted and the encryption key is saved as playlist name.key.
-hls_enc_key key
Hex-coded 16byte key to encrypt the segments, by default it is randomly generated.
-hls_enc_key_url keyurl
If set, keyurl is prepended instead of baseurl to the key filename in the playlist.
Fmpeg-n4.0.2/libavformat/hlsenc.c
{"hls_enc_key_url","url to access the key to decrypt the segments",
-hls_enc_iv iv
Hex-coded 16byte initialization vector for every segment instead of the autogenerated ones.
Fmpeg-n4.0.2/libavformat/hlsenc.c
{"hls_enc_key_url","url to access the key to decrypt the segments",
#1.没有指定 -hls_enc_key_url 时,在当前目录下产生一个 out.m3u8.key 的文件为 密钥
exportLD_LIBRARY_PATH=./lib:$LD_LIBRARY_PATH
./bin/ffmpeg-flavfi-re-itestsrc-c:v h264-hls_flagsdelete_segments \
-hls_enc1-hls_enc_key"123456890abcdef"-hls_enc_iv"1122334455aabbcc"out.m3u8
$catout.m3u8
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:9
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-KEY:METHOD=AES-128,URI="out.m3u8.key",IV=0x31313232333334343535616162626363
#EXTINF:9.360000,
out0.ts
#EXT-X-ENDLIST
#解密,密钥 out.m3u8.key
strkey=$(hexdump -v -e '16/1 "%02x"' out.m3u8.key)
#iv=$(awk 'NR==3' file.keyinfo )
iv=31313232333334343535616162626363
opensslaes-128-cbc-d-inout27.ts-outout27_decrypto.ts-nosalt-iv$iv-K$strkey
#2. 指定了hls_enc_key_url ,ffmpeg 通过 http 1.1协议 发送16字节的密钥 (Transfer-Encoding: chunked)
$exportLD_LIBRARY_PATH=./lib:$LD_LIBRARY_PATH
$./bin/ffmpeg-flavfi-re-itestsrc-c:v h264-hls_flagsdelete_segments-hls_enc1-hls_enc_key"123456890abcdef"-hls_enc_key_url"http://127.0.0.1:8000"-hls_enc_iv"1122334455aabbcc"out.m3u8
[fanshuang@zhifudev01v python]$ pythonpost.py
('127.0.0.1',49950)
POST
/
HTTP/1.1
Transfer-Encoding: chunked
User-Agent: Lavf/58.12.100
Accept: */*
Connection: close
Host:127.0.0.1:8000
Icy-MetaData:1
begin http1.1 chunked ..........
chunk-size hex: 0X10
, need recv16bytes
chunk-data:123456890abcdef
('str_chunk_size_hex:[\r\n] , ValueError:', ValueError("invalid literal for int() with base 16: ''",))
begin http1.1 end ..........
127.0.0.1--[11/Nov/201814:56:03]"POST / HTTP/1.1"200-
$$catpost.py
#coding=utf-8
from BaseHTTPServer import BaseHTTPRequestHandler
import cgi
class PostHandler(BaseHTTPRequestHandler):
def chunked_proc(self):
print'begin http1.1 chunked .......... \n'
str_chunk_size_hex=self.rfile.readline(65537)
len=int(str_chunk_size_hex.upper(),16)
whilelen >:
print"chunk-size hex: 0X"+str_chunk_size_hex+', need recv '+str(len)+' bytes \n'
print"chunk-data:"+self.rfile.readline(len)
str_chunk_size_hex=self.rfile.readline(65537)
try:
len=int(str_chunk_size_hex,16)
except ValueError as e:
len=
print('str_chunk_size_hex:['+str_chunk_size_hex+']'+' , ValueError:',e)
print'begin http1.1 end .......... \n'
def do_POST(self):
print self.client_address
print self.server
print self.command
print self.path
print self.request_version
print self.headers
print self.rfile
ifself.headers['Transfer-Encoding']=='chunked':
self.chunked_proc()
#self.send_header('Transfer-Encoding', 'chunked')
#self.send_header('Connection', 'keepalive')
self.send_response(200)
self.end_headers()
#print self.responses
return
def StartServer():
from BaseHTTPServer import HTTPServer
sever=HTTPServer(("",8000),PostHandler)
sever.serve_forever()
if__name__=='__main__':
StartServer()
$
$ find.-name"*.c"| xargsgrephls_enc_key_url
./libavformat/hlsenc.c: {"hls_enc_key_url","url to access the key to decrypt the segments", OFFSET(key_url), AV_OPT_TYPE_STRING, {.str=NULL},,, E},
$
Fmpeg-n4.0.2/libavformat/hlsenc.c
{"hls_enc_key_url","url to access the key to decrypt the segments",
urltoaccessthekeytodecryptthesegments
staticconstAVOptionoptions[]={
//....
{"hls_enc","enable AES128 encryption support",OFFSET(encrypt),AV_OPT_TYPE_BOOL, {.i64=},,1,E},
{"hls_enc_key","hex-coded 16 byte key to encrypt the segments",OFFSET(key),AV_OPT_TYPE_STRING, .flags=E},
{"hls_enc_key_url","url to access the key to decrypt the segments",OFFSET(key_url),AV_OPT_TYPE_STRING, {.str=NULL},,,E},
{"hls_enc_iv","hex-coded 16 byte initialization vector",OFFSET(iv),AV_OPT_TYPE_STRING, .flags=E},
{NULL},
};
staticintdo_encrypt(AVFormatContext*s,VariantStream*vs){
//.....
av_strlcpy(hls->key_basename,s->url,len);
av_strlcat(hls->key_basename,".key",len);
if(hls->key_url) {
av_strlcpy(hls->key_file,hls->key_url,sizeof(hls->key_file));
av_strlcpy(hls->key_uri,hls->key_url,sizeof(hls->key_uri));
}else{
av_strlcpy(hls->key_file,hls->key_basename,sizeof(hls->key_file));
av_strlcpy(hls->key_uri,hls->key_basename,sizeof(hls->key_uri));
}
//.....
}
领取专属 10元无门槛券
私享最新 技术干货