srs可以用java开发吗,为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找不到而導致播放失敗的問題。
關于找一找教程網
本站文章僅代表作者觀點,不代表本站立場,所有文章非營利性免費分享。
本站提供了軟件編程、網站開發技術、服務器運維、人工智能等等IT技術文章,希望廣大程序員努力學習,讓我們用科技改變世界。
[為SRS流媒體服務器添加HLS加密功能(附源碼)]http://www.zyiz.net/tech/detail-118040.html
總結
以上是生活随笔為你收集整理的srs可以用java开发吗,为SRS流媒体服务器添加HLS加密功能(附源码)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 梦幻古龙服务器 文档,梦幻古龙GM命令大
- 下一篇: centos查看端口占用情况