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