• 为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找不到而导致播放失败的问题。

  • 相关阅读:
    Python字典的初识、增删改查及嵌套
    Python列表的增删改查
    模块基础
    开放封闭原则和装饰器
    多层装饰器叠加装饰
    Python字符串的常用方法
    可迭代对象、迭代器对象和生成器对象
    日程安排组件dhtmlxScheduler汉化(转)
    dedecms在软件列表页调出下载链接
    [下载]《SAP R/3 IDES 4.71 中文版》
  • 原文地址:https://www.cnblogs.com/harlanc/p/8711449.html
Copyright © 2020-2023  润新知