Nginx Rtmp Module - HLS切片和级联播放
#Nginx Rtmp Module - HLS切片和播放
1、名詞解釋
媒體片段文件(.ts): 媒體片段是由源站生成的,基于編碼后的媒體源,并且是由一系列的 .ts 格式的文件組成,其中包含了你想通過 rtmp流攜帶的 H.264視頻和AAC 音頻。對于純音頻的直播,切片器可以生產(chǎn)MPEG 基礎(chǔ)音頻流,其中包含了 ADTS頭的AAC音頻。
HLS直播索引文件(.m3u8): 由源站附帶生成保存為 .m3u8 格式
下面是一個(gè)直播 .m3u8 的 playlist 文件樣例,其中包含了三個(gè)沒有加密的5秒鐘的媒體文件:
?? ?#EXTM3U#EXT-X-VERSION:3#EXT-X-MEDIA-SEQUENCE:2#EXT-X-TARGETDURATION:5#EXTINF:5.000,1475217437694.ts#EXTINF:5.000,1475217442714.ts#EXTINF:5.000,1475217447698.ts
HLS點(diǎn)播索引文件(.m3u8): 由源站附帶生成保存為 .m3u8 格式
下面是一個(gè) 點(diǎn)播 .m3u8 的 playlist 文件樣例,其中包含了三個(gè)沒有加密的5秒鐘的媒體文件:
?? ?#EXTM3U#EXT-X-VERSION:3#EXT-X-MEDIA-SEQUENCE:2#EXT-X-TARGETDURATION:5#EXTINF:5.000,1475217437694.ts#EXTINF:5.000,1475217442714.ts#EXTINF:5.000,1475217447698.ts#EXT-X-ENDLIST ? ? ?#點(diǎn)播特有的標(biāo)簽
HLS直播: 直播就是實(shí)時(shí)事件的錄制展示。它的索引文件一直處于動態(tài)變化的,你需要不斷的更新索引文件 playlist 然后移除舊的索引文件。這種類型通過向索引文件添加媒體地址可以很容易的轉(zhuǎn)化為VOD類型。在轉(zhuǎn)化時(shí)不要移除原來舊的源,而是通過添加一個(gè) #ET-X-ENDLIST 標(biāo)記來終止實(shí)時(shí)事件。轉(zhuǎn)化時(shí)如果你的索引文件中包含 EXT-X-PLAYLIST-TYPE 標(biāo)簽,你需要將值從 EVENT 改為 VOD。
HLS錄播: 點(diǎn)播的特點(diǎn)就是可以獲取到一個(gè)靜態(tài)的索引文件,該文件包含一套完整的資源文件地址。這種模式允許客戶端訪問全部節(jié)目
2、HLS直播
當(dāng)音頻和視頻數(shù)據(jù)經(jīng)過SLB的負(fù)載均衡,打到任意一個(gè)lmss進(jìn)程上之后,會分別被HLS直播和HLS錄播模塊處理,兩個(gè)模塊會根據(jù)自己的切片算法、索引文件生成算法 生成該模塊對應(yīng)的 m3u8和ts文件。直播模塊會將這兩個(gè)文件生成到內(nèi)存虛擬硬盤,然后在HLS直播中被CDN請求使用。
接下來將分別介紹HLS直播及錄播模塊。
2.1、HLS直播
HLS直播分為兩個(gè)子模塊: 負(fù)責(zé)hls本地 級連播放的HTTP HLS模塊和負(fù)責(zé)hls直播切片相關(guān)的RTMP HLS模塊。
2.1.1 RTMP HLS模塊
(1) 模塊配置
本地配置如下:
? ?
(2) hook函數(shù)回調(diào)
?? ?
?? ?
(3)HLS 對rtmp推流publish消息的處理(ngx_rtmp_hls_publish)
(4) HLS對視頻幀的處理(ngx_rtmp_hls_video)
對于視頻數(shù)據(jù),HLS直播模塊會解析每一個(gè)rtmp數(shù)據(jù)包,提取出h264 nal數(shù)據(jù),然后按照ts封裝格式封裝到ts文件里面。
(5) HLS對音頻幀的處理(ngx_rtmp_hls_audio函數(shù))
對于音頻幀,該模塊采用不同于視頻幀的處理方式, 區(qū)別如下:??? ?
?? ??? ?
?? ?? ?
?? ?
| 不同點(diǎn) | ?video | audio |
| dts | dts = timestamp * 90 | dts = (aframe_num * 90000 * 1024 / sample_rate) |
| pts | ?pts = dts + cts * 90 | pts = dts |
| 幀處理 | 每一幀都寫ts文件 | 音頻幀緩沖區(qū)填滿之后,一次寫入ts文件 |
?? ?
音頻幀處理流程如下:
對于音頻幀的處理,HLS直播模塊采用了先緩存,然后一并切入ts文件的方式,這種方式對于減少磁盤的i/o有很大的好處,同時(shí)HLS直播模塊對封裝好的ts文件,會被寫入虛擬內(nèi)存硬盤,而不是普通硬盤的目的,也是為了提高磁盤i/o的效率。
(6) HLS 切片處理(ngx_rtmp_hls_update_fragment)
該函數(shù)主要負(fù)責(zé)hls直播的核心切片邏輯。
切片流程如下:
其中藍(lán)色的部分是生成新的ts分片的邏輯:
- (1)當(dāng)前ts片的長度大于1.2倍的fraglen,即向上浮動20%,且強(qiáng)制切片
- (2)遇到視頻關(guān)鍵幀并且ts片的長度大于0.8 倍的fraglen,即向下浮動20%
- (3)出現(xiàn)異常情況,時(shí)間戳跳變,比如音視頻時(shí)間戳變小,則當(dāng)系統(tǒng)時(shí)間超過3倍的切片fraglen長度,強(qiáng)制切片
其中紅色的部分會在更新m3u8列表的時(shí)候,添加discontinue標(biāo)簽
- (1)出現(xiàn)第三種強(qiáng)制切片邏輯時(shí),則會在下一個(gè)ts分片的m3u8列表里,添加discontinue標(biāo)簽
- (2)出現(xiàn)異常情況,時(shí)間戳跳變,比如相鄰的音頻或者相鄰的視頻 時(shí)間戳變小,則會在當(dāng)前ts片,添加discontinue標(biāo)簽
(7) HLS 對rtmp推流結(jié)束消息的處理(ngx_rtmp_hls_close_stream)
該函數(shù)主要清理模塊的上下文。
(8) .m3u8索引文件生成算法
下面是一個(gè)直播 .m3u8 的 playlist 文件樣例:
對于HLS直播: .m3u8索引文件只會存儲最新的幾片ts文件,每生成一個(gè)新的ts文件就會更新索引文件,然后移除舊的索引文件,意味著它的索引文件一直是動態(tài)變化的。
(9) ts片清理邏輯(cleanup)
客戶端播放HLS直播,只會播放m3u8索引里面存儲的最新的ts文件,ts文件一旦從m3u8文件里面清除 ,即ts文件過期,LMSS將會做定期的清理這些文件。但是由于小部分網(wǎng)絡(luò)不好或者延時(shí)較大的用戶,可能仍會請求一些剛從m3u8列表清除的ts文件,所以文件清除的時(shí)間會比過期時(shí)間要大,規(guī)則如下:
| name? | 取值 |
| 掃描 目錄 | /dev/shm |
| 掃描 周期 | 30s |
| ts清除時(shí)間? | hls_playlist_length * 2.5 |
| m3u8清除時(shí)間 | ?hls_playlist_length * 1 |
?
? ?
??
原理如下:
2.1.2 HTTP HLS模塊
hls級連架構(gòu)圖:
目前級連有三種不同的方式:
1. 遠(yuǎn)程級連(位于不同機(jī)器上的lmss進(jìn)程級連) 2. 跨集群級連 (位于不同集群之間的lmss進(jìn)程級連)?
hls級連交互圖:
流程如下:
1. 推流端推送音視頻數(shù)據(jù)到任意一臺源站lmss A,lmss服務(wù)器 A進(jìn)行hls切片。 2. 播放端跟lmss B 請求.m3u8和.ts文件。 3. lmss B 發(fā)送http請求到lmds服務(wù)器,獲取級連信息。 4. lmss B嘗試從本地讀取文件,如果有則直接發(fā)送,否則從源節(jié)點(diǎn)請求數(shù)據(jù)。
---------------------?
作者:kingsoft-踏鋒?
來源:CSDN?
原文:https://blog.csdn.net/liwf616/article/details/77886991?
版權(quán)聲明:本文為博主原創(chuàng)文章,轉(zhuǎn)載請附上博文鏈接!
總結(jié)
以上是生活随笔為你收集整理的Nginx Rtmp Module - HLS切片和级联播放的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux平台关于内存,cpu,连接数,
- 下一篇: 我眼中的 Nginx(六):深入 Ngi