为SRS流媒体服务器添加HLS加密功能(附源码)
为SRS流媒体服务器添加HLS加密功能(附源码)#
之前测试使用过nginx的HLS加密功能,会使用到一个叫做nginx-rtmp-module的插件,但此插件很久不更新了,网上搜索到一个中国制造的叫做SRS的流媒体服务器,比较活跃,而且据说这个流媒体服务器的性能和功能都强大不少,但遗憾的是没有HLS加密功能。原作者没有加这个功能,所以决定自己动手,花了几个晚上的时间自己参考nginx-rtmp实现了一下。代码放到了github上(源码已经merge到了3.0release主分支上,pull request)。
功能介绍##
几个新添加的参数配置项###
hls_keys on;
hls_fragments_per_key 4;
hls_key_file [app]/[stream]-[seq].key;
hls_key_file_path ./objs/nginx/html;
hls_key_url http://localhost:8080/live/h265.m3u8;
分别代表如下含义:
- hls_keys: 是否开启hls加密,默认关闭。
- hls_fragments_per_key: 每个key可以加密多少个ts片段,默认值是10。
- hls_key_file: key文件相对路径的生成模板,包括一个[app]文件夹以及名字[stream]-[seq],后缀为.key,默认值为[app]/[stream]-[seq].key。
- hls_key_file_path: 可以为key文件的生成指定本地目录,默认为hls_path(存放ts的目录)。
- hls_key_url: 可以为key指定一个HTTP url。
实现过程中的几个关键点##
需要实现的功能点包括一下几个方面:
从配置文件读取配置项####
这个仿照srs的实现添加,比较简单。
key和iv的自动生成和保存####
在这里每隔hls_fragments_per_key个ts会自动的生成随机的16bytes的key和iv。key会保存在hls_key_file_path路径中,iv会保存在m3u8文件中。
在代码实现中,key和iv在内存中保存了三份。SrsHlsMuxer中保存了一份,用于提供每次new SrsHlsSegment时需要的key和iv。因为每次刷新m3u8(refresh_m3u8)时,都要从头重新生成一次m3u8文件,所以需要为每个SrsHlsSegment对象备份一份iv。最后是传递给writer的key和iv,用于AES128加密。
AES128加密###
材料都准备好了,最后的关键问题就是加密。在这里使用了Openssl的加密库,SRS的实现是每次写一个packet(188bytes),而AES128需要加密的raw数据是16的倍数,因此需要在原有SrsFileWriter的实现上加一层缓冲。缓冲到16的倍数后(也就是188*4),加密一次数据,然后写到文件中。具体实现是下面的样子:
srs_error_t SrsEncFileWriter::write(void* buf, size_t count, ssize_t* pnwrite)
{
srs_assert(count == SRS_TS_PACKET_SIZE);
srs_error_t err = srs_success;
if(buflength != HLS_AES_ENCRYPT_BLOCK_LENGTH)
{
memcpy(tmpbuf+buflength,(char*)buf,SRS_TS_PACKET_SIZE);
buflength += SRS_TS_PACKET_SIZE;
}
if(buflength == HLS_AES_ENCRYPT_BLOCK_LENGTH)
{
unsigned char encryptedbuf[HLS_AES_ENCRYPT_BLOCK_LENGTH];
memset(encryptedbuf,0,HLS_AES_ENCRYPT_BLOCK_LENGTH);
AES_cbc_encrypt((unsigned char *)tmpbuf, (unsigned char *)encryptedbuf, HLS_AES_ENCRYPT_BLOCK_LENGTH, &key, iv, AES_ENCRYPT);
buflength = 0;
memset(tmpbuf,0,HLS_AES_ENCRYPT_BLOCK_LENGTH);
return SrsFileWriter::write(encryptedbuf,HLS_AES_ENCRYPT_BLOCK_LENGTH,pnwrite);
}
else
{
return err;
}
};
需要注意的是每次close TS文件的FD时需要判断缓冲中有没有数据,如果有的话需要添加填充数据(添加到正好为16的倍数即可),然后加密,写文件,关闭文件:
int addBytes = 16 - buflength % 16;
memset(tmpbuf + buflength, addBytes, addBytes);
unsigned char encryptedbuf[buflength+addBytes];
测试###
能够为HLS TS切片正常加密和播放。没有做充分的测试,对SRS了解的还不够深入。如果大家需要这个功能的话,可以尝试着使用一下,遇到问题联系我。
如何使用##
首先,在配置文件中添加以下配置项。
http_server {
enabled on;
listen 8080;
dir ./objs/nginx/html;
}
vhost __defaultVhost__ {
hls {
enabled on;
hls_fragment 10;
hls_window 600000;
hls_path ./objs/nginx/html;
hls_m3u8_file [app]/[stream].m3u8;
hls_ts_file [app]/[stream]-[seq].ts;
hls_keys on;
hls_fragments_per_key 4;
hls_key_file [app]/[stream]-[seq].key;
hls_key_file_path ./objs/nginx/html;
hls_key_url http://localhost:8080/live;
}
然后到trunk目录下启动:
./objs/srs -c conf/hls.conf
推送rtmp流的命令:
ffmpeg -re -i /Users/zexu/Movies/test.mp4 -c copy -f flv rtmp://localhost:1935/live/h265
最后在播放器中播放URL:
http://localhost:8080/live/h265.m3u8
关于配置项要注意的地方###
关于hls_key_file_path和hls_key_url,要么都不配置(注释掉即可),这样的话m3u8,ts和key文件都在一个目录下面。要么就都配置,需要自己保证两个地址能够对上。否则会出现key找不到而导致播放失败的问题。
为SRS流媒体服务器添加HLS加密功能(附源码)的更多相关文章
- leaflet结合geoserver利用WFS服务实现图层删除功能(附源码下载)
前言 leaflet 入门开发系列环境知识点了解: leaflet api文档介绍,详细介绍 leaflet 每个类的函数以及属性等等 leaflet 在线例子 leaflet 插件,leaflet ...
- MVC中使用SignalR打造酷炫实用的即时通讯功能附源码
前言,现在这世道写篇帖子没个前言真不好意思发出来.本贴的主要内容来自于本人在之前项目中所开发的一个小功能,用于OA中的即时通讯.由于当时走的太急,忘记把代码拿出来.想想这已经是大半年前的事情了,时间过 ...
- vue项目实现记住密码到cookie功能(附源码)
实现功能: 1.记住密码勾选,点登陆时,将账号和密码保存到cookie,下次登陆自动显示到表单内 2.不勾选,点登陆时候则清空之前保存到cookie的值,下次登陆需要手动输入 大体思路就是通过存/取/ ...
- Zookeeper+websocket实现对分布式服务器的实时监控(附源码下载)
我就是个封面 Zookeeper简介 Zookeeper是Hadoop的一个子项目,它是分布式系统中的协调系统. 简单来说就是一个Zookeeper注册同步中心,内部结构为一个树形目录,每个节点上 ...
- 【Android初级】如何动态添加菜单项(附源码+避坑)
我们平时在开发过程中,为了灵活多变,除了使用静态的菜单,还有动态添加菜单的需求.今天要分享的功能如下: 在界面的右上角有个更多选项,点开后,有两个子菜单:关于和退出 点击"关于", ...
- Winforn中实现ZedGraph自定义添加右键菜单项(附源码下载)
场景 Winform中实现ZedGraph中曲线右键显示为中文: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/100115292 ...
- leaflet 实现克里金插值功能(附源码下载)
前言 leaflet 入门开发系列环境知识点了解: leaflet api文档介绍,详细介绍 leaflet 每个类的函数以及属性等等 leaflet 在线例子 leaflet 插件,leaflet ...
- openlayers6结合geoserver利用WFS服务实现图层新增功能(附源码下载)
内容概览 1.openlayers6结合geoserver利用WFS服务实现图层新增功能2.源代码demo下载 效果图如下: 本篇主要是openlayers6通过调用geoserver发布的地图服务W ...
- cesium 入门开发系列地图鹰眼功能(附源码下载)
前言 cesium 入门开发系列环境知识点了解:cesium api文档介绍,详细介绍 cesium 每个类的函数以及属性等等cesium 在线例子 内容概览 cesium 结合 leaflet 实现 ...
随机推荐
- 【Luogu3919】可持久化数组(主席树)
题面戳我 题解 放一个板子在这里 用主席树维护一下每个版本就可以啦... #include<iostream> #include<cstdio> #include<cst ...
- CentOS 静态IP分配,提示Error, some other host already uses address解决办法
(一)第一 修改 ifup-eth vi /etc/sysconfig/network-scripts/ifup-eth #if ! /sbin/arping -q -c 2 -w 3 -D -I $ ...
- 创建Maven项目时提示web.xml is missing and <failOnMissingWebXml> is set to true错误解决方案
1. 右键点击Deployment Descriptor 2. 选择Generate Deployment Descriptor Stub P.S.下面顺便提一个小技巧: 创建动态web时先右键项目, ...
- 网页提示错误(net::ERR_EMPTY_RESPONSE)
突然个别网页打不开,报上面的错,本来还以为是网页的问题,结果发现是自己的电脑的问题..因为从别的设备上可以打开相同网页. 1.运行→regedit→进入注册表, 在 HKEY_LOCAL_MACHIN ...
- Sqlite 梳理
前言 LZ最近失业,梳理下最近一个项目的 项目结构-供应链系统 接着上一篇博客 http://www.cnblogs.com/buruainiaaaa/p/6786527.html 上篇说到整套系统分 ...
- delphi简单的分页实现(高手可以不看)
适合初学者,练习几个控件的使用 1.先放一张界面控件布局: 4个button,2个label,1个edit,1个TRzsplitter(把界面分割成上下2部分),1一个adoquery,1个adoco ...
- 【RMAN】Oracle中如何备份控制文件?备份控制文件的方式有哪几种?
真题1. 如何备份控制文件?备份控制文件的方式有哪几种? 答案:备份控制文件的方式有多种. ① 备份控制文件可以在线进行: SQL> ALTER DATABASE BACKUP CONTROLF ...
- 边做边学入门微信小程序之仿豆瓣评分
微信小程序由于适用性强.逻辑简要.开发迅速的特性,叠加具有海量活跃用户的腾讯公司背景,逐渐成为了轻量级单一功能应用场景的较佳承载方式,诸如电影购票.外卖点餐.移动商城.生活服务等场景服务提供商迅速切入 ...
- Gauge----自动化测试工具
* Gauge是一个自动化测试工具,主要是通过.spec 文件指定执行的步骤,然后由Java代码去测试 安装: * 安装插件 Gauge--install-all *在IDEA中安装Gauge插件 基 ...
- 动画:UIViewAnimationOptions类型
动画 1.常规动画属性设置(可以同时选择多个进行设置) UIViewAnimationOptionLayoutSubviews:动画过程中保证子视图跟随运动.**提交动画的时候布局子控件,表示子控件将 ...