首頁  >  文章  >  運維  >  如何理解基於nginx-rtmp-module模組實現的HTTP-FLV直播模組nginx-http-flv-module

如何理解基於nginx-rtmp-module模組實現的HTTP-FLV直播模組nginx-http-flv-module

坏嘻嘻
坏嘻嘻原創
2018-09-17 10:08:473356瀏覽

本篇文章帶給大家的內容是關於如何理解基於nginx-rtmp-module模組實現的HTTP-FLV直播模組nginx-http-flv-module,有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。

目前已經有很多個人和廠商準備將本模組商用,據網友回饋,國外已經有直播網站在用這個模組。準備商用的廠商中最著名的是華為,網友和廠商陸續回饋不少bug,修復後功能已經越來越穩定,在此表示感謝。

2018-06-04:CDN廠商正式上線nginx-http-flv-module,使用RTMP方式,開gop_cache配置(關閉interleave配置,打開會卡頓或沒有聲音,目前暫時不知如何修復),他們的客戶包括映客和微吼。

2018-06-28:網路視訊廠商正式上線nginx-http-flv-module,使用HTTP-FLV方式,不開gop_cache配置,目前還沒開全量,等待觀察穩定性。

2018-07-28:應一部分網友的需求,已經提供RHEL6(CentOS 6)和RHEL7(CentOS 7)的rpm安裝包,見nginx-http-flv-module -packages。

        nginx-http-flv-module與nginx-rtmp-module的功能比較:

#功能 nginx-http-flv-module nginx-rtmp-module 備註
HTTP-FLV #√ × nginx-http-flv-module支援HTTPS-FLV
#GOP快取 ##√ ×  
vhost ×  
省略listen設定 x

 

JSON風格的stat x  
RTMP 302 Beta × nginx-http-flv-module作為伺服器或客戶端
#

2018-03-09更新:

最近這段時間主要在不同平台測試模組的穩定性,目前播放這塊沒發現問題,由於條件限制,除了FreeBSD平台沒測試過,Windows 7,Debian 7.x和macOS Sierra都測試過了,由於Nginx官方對Windows支援不太好,沒用Windows平台最強大的IOCP介面(使用的select),所以導致Windows平台上運作效率不太高,表現在推流等待時間長,3s ,首屏時間很長,4s ,select本身原因限制客戶端個數,預設是1024。推流等待時間和首屏時間最短的是macOS Sierra,本機上測試時基本上是秒推秒開。昨晚特別注意了一下,在macOS Sierra下編譯時,SO_REUSEPORT和TCP_FASTOPEN兩項都支持,前者讓Nginx的每個子進程都可以listen,都有一個專門的accept隊列,解決了驚群效應;後者則是在發起SYN時就已經攜帶實際數據,而不是握手完畢後再傳輸實際數據。秒推秒開可能跟這兩個選項有關。但是macOS Sierra並不支援將某個進程綁定到某個CPU上,所以可能進程上下文切換會有開銷,系統負載較大時可能效率不如Linux。由於macOS Sierra是公司的電腦,所以未做壓力測試。我的筆記本裝的是Debian 7.x,因為核心版本較低,所以macOS Sierra上支援的兩個選項都不支援。測試時推流等待時間和首屏時間都介於Windows 7和macOS Sierra之間,在伺服器上測試時(系統CentOS 6.4,支援SO_REUSEPORT但是不支援TCP_FASTOPEN)跟macOS Sierra上差不多,但考慮到伺服器的CPU效能強大得多,所以負載不高情況下,macOS Sierra的表現是最好的。由於macOS Sierra是從Mac OS X更新來的,而Mac OS X的底層最初是在FreeBSD基礎上開發的,所以推測在FreeBSD上的表現應該也不錯。

另外最近在嘗試加入RTMP 302重定向轉HTTP 302重定向的功能,由於許多播放器不支援RTMP 302重定向,但支援HTTP 302重定向的功能基本上是標配,實測VLC是支持的。目前功能基本上已經完成,但是困擾的地方還是使用HTTP框架的發送介面時,鍊錶在長時間播放後會形成環,所以進展不下去了,沒有更新到github上。下面是nginx的rtmp主要設定片段和VLC播放時的HTTP 302重定向截圖:其中推流是在名為hls的application上推的(FFmpeg也不支援RTMP 302重定向,所以只能往hls推)。

application myapp {

    rewrite '^/myapp/(.*)' '/hsl/$1';

##}

1.HTTP 302重定向抓包簡圖

如何理解基於nginx-rtmp-module模組實現的HTTP-FLV直播模組nginx-http-flv-module

2.HTTP 302重定向抓包詳情

如何理解基於nginx-rtmp-module模組實現的HTTP-FLV直播模組nginx-http-flv-module

2018-03- 15更新:

有網友回饋on_play指令不能使用,經過調試,是因為加入的ngx_http_flv_live模組的順序有問題,現修改為不改變模組順序的前提下,經過一些狀態的修改繞過它,後續再呼叫其中的一些函數,以保證與原來的nginx-rtmp-module的功能一致。

2018-03-16更新:

部分網友們提出的CORS(跨域)功能已經可用,HTTP-FLV的回應資料不再使用硬編碼,而是使用部分HTTP框架的程式碼重寫了。另外,on_connect功能有問題,暫時不能用,等待修復。

2018-03-18更新:

on_connect的問題已經修復。

2018-03-20更新:

修正因為要尋找的application不在第一個server區塊中造成找不到對應的on_connect和on_play的bug,經查是由於沒有匹配到正確的server配置,已修復。

2018-03-22更新:

很久之前有網友提出過設定idle_streams為off(預設為on)時,使用HTTP-FLV方式播pull會失敗,現已修復。

2018-03-25更新:

有網友使用flv.js播放nginx-http-flv-module拉的直播串流,發現一個bug:當(1)使用的Nginx版本號為1.13.9,(2)播放器為flv.js,(3)播放pull的串流時,會出現無法播放的情況,經查是因為flv.js發送了HTTP頭“Connection: keep-alive” ,nginx-http-flv-module在向上游發起請求時,下游請求一般在上游請求還沒有返回時就已經返回,但是Nginx從版本1.13.1起,刪除了一個r->blocked判斷,而“ Connection: keep-alive」導致ngx_http_finalize_request呼叫ngx_http_set_keepalive,這個函數會呼叫已註冊的cleanup函數來關閉下游的請求,導致播放失敗。已經修復。也正是在調試這個bug的過程中,發現

nginx-http-flv-module在打開gop_cache配置項目的情況下,flv.js跟其他主流的播放器(如vlc)相較,首屏時間是最快的,幾乎沒有延遲,使用的pull源是香港衛視的直播源:rtmp://live.hkstv.hk.lxdns.com/live/hks

2018-03-27更新:

順手改點程式碼就有bug,真是惱人。最近為了回應一些網友要求添加定制的HTTP頭的功能,修改了發送功能,再次嘗試將Nginx的HTTP框架的filter接口引入,還是失敗了,所以簡單粗暴地把最後一個filter模組和header_filter模組挑出來,刪除了很多用不到的程式碼。 github上編譯用的是Nginx官方的穩定版nginx-1.12.2。結果今天有網友回饋編譯不過去,經查剛好這幾個找不到的宏是在我從修改nginx-rtmp-module就一直使用的nginx-1.11.10中加入的,而網友用的版本低一些就編譯不過去,已經修復。

2018-03-29更新:

前幾天有網友回饋使用nginx-1.13.1以及以上的版本與nginx-http-flv-module一起編譯時,使用flv. js播放pull串流會失敗,見2018-03-25更新,結果修復了那個問題,又出了先推流,然後使用flv.js播放會失敗的問題,真是隨手改出bug,問題已經修復,最新版本的Nginx和稍微舊的版本(nginx-1.11.10)都已經測試通過。

2018-04-05記錄:

這次不是更新:)昨天有網友回饋使用flv.js播放推流時,一直播放不了,我還以為nginx-http-flv -module又出問題了,自己測試了一下,用最新的nginx-1.13.10一起編譯,播放推流和拉流都沒問題,又用官方的穩定版nginx-1.12.2一起編譯,還是沒問題,晚上準備看看哪裡出問題的時候,網友反饋是瀏覽器限制了flv.js的數量,他用的是Chrome,據測試單瀏覽器只能開6個flv.js,今天中午我用Firefox測試了一下,也是同樣的問題,第7個flv.js播放不了,然後開VLC播放,沒有問題,由此可以確認不是nginx-http-flv-module的問題。不過這是個很重要的訊息,瀏覽器對flv.js的播放支援是有數量限制的,Chrome和Firefox的限制數量都是6個,其他瀏覽器未測試。

2018-04-06更新:

之前的統計數據一直沒有把http-flv直播的accepted數量和輸出計入,現在已經增加。現在flv.js的支援已經穩定,以下是使用flv.js播放的截圖:

如何理解基於nginx-rtmp-module模組實現的HTTP-FLV直播模組nginx-http-flv-module

一個商用廠商回饋影片來源是純影片時,不管使用什麼播放器,播放連線沒問題,但是一直接收不到視訊數據,經調試發現是因為判斷純音訊的邏輯有bug,導致nginx-http-flv-module在發送音訊視訊資料的介面中無限循環了,現已修復。

2018-04-14更新:

有網友昨天反饋開啟gop_cache選項時,推流會導致記憶體洩露,已查明是推流關閉時沒有釋放gop cache模組分配的記憶體造成的,已修復。另外,根據網友回饋,在多進程模式下,on_connect和on_play指令有問題,暫時別在多進程模式下用這兩個指令,等待修復。

2018-04-15更新:

一個商用廠商反饋隨機閃斷測試時,內存會不斷增長,懷疑有內存洩露,晚上調試時確認確實有內存洩露,是由於沒有釋放ngx_http_request_t結構中的記憶體池造成的,已修復。

2018-04-21更新:

有網友回饋多進程模式下,使用on_play進行鑑權操作,但是在推流的時候,本地relay(接受推流的子進程將流推給別的子程序)也會執行on_play鑑權,這是不太合理的(但其實不算bug),因為之前已經進行過鑑權了。現在將本地relay的on_play操作去掉了,nginx-http-flv-module並不關心on_play用來做什麼,但是考慮到本地relay不應該再執行on_play操作了,修改的程式碼也比較簡單,恢復也很容易,所以先暫時這樣修改。另外網友@qqzzzx 回饋的壓測崩潰的問題已經修復一部分,現在還存在的問題是壓測群斷後會有內存洩漏的問題,修復後會更新到github上。

2018-04-25更新:

壓力測試崩潰的問題已經修復,捎帶解決了可能出現的CPU使用率過高的問題,已壓力測試1個多小時(srs -bench自備的測試視頻,500路HTTP-FLV和200路RTMP),暫未發現問題,歡迎反饋bug。

2018-05-12更新:

有網友回饋開啟gop_cache選項,某些情況下壓力測試會特別耗費內存,不確定是不是有記憶體外洩。壓測多次不能復現,網友提示壓測工具和伺服器不在同一主機上比較容易重現。以這種方式壓測果然比較容易復現,但是出現耗費內存比較大的情況下,停止壓力測試,然後再次壓力測試且並發數不變,內存不會增長,證明不是內存洩露的問題。後來反覆查看原始碼後,猜想是因為發送GOP的時候,一次性將GOP資料放入發送環形數組中,由於Nginx是異步非阻塞的,所以Nginx不一定會馬上將資料從環形數組中真正發送到網路(如伺服器和客戶端之間的網路頻寬不足的情況),造成已分配的記憶體不能馬上循環使用,而且真正發送完GOP後,已分配的記憶體不再釋放(在記憶體池中,並且與連接無關,只跟配置結構體有關)。後續的資料傳輸不像GOP資料是一次全部發送,所以導致回收的記憶體不能充分使用,有很大一部分閒置了。現將gop cache模組修改為使用自己獨立的記憶體池,等GOP發送完後,釋放這個記憶體池。

2018-05-14更新:

修正了一個2018-05-12更新引入的記憶體外洩的bug,屬於程式碼久了看不懂,然後一改就出問題的情況如何理解基於nginx-rtmp-module模組實現的HTTP-FLV直播模組nginx-http-flv-module。修復高版本gcc編譯工程失敗(在網上查了一下,gcc-7.x.x在添加了某些編譯選項時,會檢查switch的case是否有fall through)的bug,不過我手頭沒有很高版本的gcc ,所以可能還存在一些沒被發現的編譯錯誤,目前正等待網友的回覆。

2018-05-16更新:

在白天編譯安裝了gcc-7.2.0,找出了所有的fall through編譯警告(Nginx的編譯選項中被視為錯誤),已修復bug。

2018-05-18記錄:

這次不是更新,2018-05-12更新我猜想壓力測試(使用的工具是srs-bench)時開啟gop_cache選項會特別耗費記憶體的原因,今晚經過查看日誌,發現之前的猜想其實不是主要原因。從日誌中可以看到Nginx在接收資料時一直都是128字節,而在配置中如果沒有指明chunk_size配置項時,預設是4096個字節,就是說伺服器發送Set Chunk Size協定控制訊息後,客戶端並沒有回應Set Chunk Size協定控制訊息,所以伺服器一直沿用之前的128字節,最糟糕的情況下,會導致nginx-http-flv-module在接收到資料後,分配記憶體對資料進行打包時,用(4096 RTMP頭最大大小)這麼多位元組的空間來打包128位元組的數據,白白浪費了32倍多的數據。使用ffmpeg進行比較測試,ffmpeg是會回應Set Chunk Size協定控制訊息的,所以不會造成記憶體浪費。已經給SRS(Simple-RTMP-Server)的作者提issue了。後續有空我會更新nginx-http-flv-module對此異常的處理。

2018-05-20更新:

某些情況下特別耗費記憶體的問題已經修復,如果耗費使用量還很大,那麼可能是上面說的那個次要原因引起的了。

2018-06-14更新:

修正一個網友回饋的問題,ngx_stat_active參數在運行一段時間後值不正確,經查是由於重複減去操作造成的,已修復,不影響正常功能使用。

2018-06-19更新:

同步了幾個nginx-rtmp-module的pull requests裡的bug修復,基本上都是一些很明顯的bug,大的修改沒同步過來。另外,目前在nginx-http-flv-module基礎上添加了直接推送fmp4的功能,今晚已經實現直接推送純視頻的fmp4到支援MSE(Media Source Extensions,目前iOS上的Safari不支援)的瀏覽器中播放,後續會將音訊一起加上。

2018-06-25更新:

推送fmp4的基本功能基本上已經完成。有網友推了支援JSON格式的stat的PR,已經合併,試用了下,感覺非常不錯,另外修復了一個小bug。

2018-06-29更新:

將stat中原有的rtmp資訊修改為http-flv,鑑於已經有兩個廠商分別正式商用RTMP(開啟gop_cache)和HTTP-FLV (不開gop_cache),發布了里程碑版本1.2.4。

2018-07-09更新:

修正了3個小bug:開啟DASH功能時,有可能因為從檔案讀取的資料為0導致無限迴圈;修復xml方式的stat中不能顯示nginx-http-flv-module的版本號碼的問題(網友的PR);修正HEAD請求沒有配置flv_live的locations時回傳405(Method Not Allowed)的bug

以上是如何理解基於nginx-rtmp-module模組實現的HTTP-FLV直播模組nginx-http-flv-module的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn