基於nginx-rtmp-module模塊實現的基於HTTP協議的FLV直播模塊(nginx-http-flv-module)

近幾年直播行業火爆,開源的直播軟件解決方案有SRS(Simple-RTMP-Server)和nginx-rtmp-module,前者是國人發起的一個優秀的開源項目,目前國內不少公司都使用它做爲直播解決方案,由C++編寫;後者依賴Nginx,以第三方模塊的方式提供直播功能,由C編寫。SRS採用多線程方式,性能優秀,經受住了衆多場景的考驗,可是SRS3已經閉源(更正,中間一段時間閉源,如今又開源了);nginx-rtmp-module是採用多進程方式,Nginx的性能優秀,可是據網友測試,nginx-rtmp-module的性能不如SRS,而且nginx-rtmp-module的做者已經好久沒有更新版本了,支持的功能也有限,例如不支持HTTP方式的FLV直播,而這是國內直播行業廣泛採用的方式;不支持虛擬主機功能,在有多個IP地址的主機上沒法根據域名選擇不一樣配置;還有飽受詬病的播放響應延遲時間很長的問題(即俗稱的不能秒播)等。html

我在nginx-rtmp-module的基礎上實現了基於HTTP方式的FLV直播功能,支持GOP緩存,減小播放響應延遲時間;支持流式和Transfer-Encoding: chunked兩種HTTP響應格式;支持根據域名匹配不一樣配置的虛擬主機功能;修復nginx-rtmp-module沒有listen配置項時,推流失敗的問題;解決nginx-rtmp-module已知的bug,見nginx-http-flv-module,歡迎下載測試和修復bug。nginx

典型的nginx.conf以下:git

worker_processes  4; #Nginx開啓4個子進程,子進程個數最好跟CPU的核心數同樣
worker_cpu_affinity 0001 0010 0100 1000; #CPU的mask,子進程使用它來綁定CPU核心,避免進程切換形成性能損失github

error_log logs/error.log error; #錯誤日誌位置和日誌級別,若是使用默認編譯選項,位置爲/usr/local/nginx/logs/error.log,error表示只打印錯誤日誌緩存

events {
    worker_connections  1024; #Nginx處理的最大鏈接數
}服務器

http {
    include       mime.types;
    default_type  application/octet-stream;多線程

keepalive_timeout  65;app

server {
        listen       80; #Nginx監聽的HTTP請求端口dom

location / {
            root   /var/www; #HTTP請求URL映射到服務器的位置
            index  index.html index.htm; #HTTP請求優先請求的文件,如http://localhost/,若是有index.html在/var/www目錄下,那麼請求的是/var/www/index.html
        }socket

error_page   500 502 503 504  /50x.html; #若是遇到這些HTTP請求錯誤,Nginx返回50x.html的內容
        location = /50x.html {
            root   html; #由於/配置了root /var/www,因此這兒html對應的是/var/www/html,因此50x.html的路徑是/var/www/html/50x.html
        }

location /live {
            flv_live on; #當HTTP請求以/live結尾,匹配這兒,這個選項表示開啓了flv直播播放功能
            chunked  on; #HTTP協議開啓Transfer-Encoding: chunked;方式回覆
        }
    }
}

rtmp_auto_push on; #由於Nginx可能開啓多個子進程,這個選項表示推流時,媒體流會發布到多個子進程
rtmp_auto_push_reconnect 1s;
rtmp_socket_dir /tmp; #多個子進程狀況下,推流時,最開始只有一個子進程在競爭中接收到數據,而後它再relay給其餘子進程,他們之間經過unix domain socket傳輸數據,這個選項表示unix domain socket的路徑

rtmp {
    out_queue   4096;
    out_cork    16;
    max_streams 64; #Nginx能接受的最大的推流數

server {
        listen 1935; #Nginx監聽的RTMP推流/拉流端口,能夠省略,默認監聽1935

application myapp {
            live on; #當推流時,RTMP路徑中的APP(RTMP中一個概念)匹配myapp時,開啓直播
            gop_cache on; #開啓GOP(Group of Picture)緩存,播放器解碼時,收到一個完整的GOP纔會開始播放,這個是減小播放延遲的選項
        }

}

server {

listen 1935;

server_name .test.com; #虛擬主機功能,還支持www.test./www.test.com格式

application myapp {

live on;

gop_cache on; #開啓GOP緩存,減小首屏播放時間

}

}

}

推流的通用命令:ffmpeg -i -re xxx.mp4(或者與RTMP兼容的媒體文件)-vcodec copy -acodec copy -f flv rtmp://example.com[:port]/app/stream,後面也能夠像HTTP的URL那樣加參數,目前沒仔細研究過,若是想推流到myapp,那麼app換成myapp,stream隨便取名。

播放的通用URL:http://example.com[:port]/dir?[port=xxx&]app=xxx&stream=xxx,其中dir是nginx配置文件中http {}中的某個location,如「location /live { ... }」,第一個port是nginx配置文件中http {}中的端口,若是不指定,那麼使用默認值80,第二個port是nginx配置文件中rtmp {}中的端口,若是不指定,使用默認值1935;app的值與上述推流命令中的app保持一致,stream的值與上述推流命令中的stream保持一致。

詳細使用方法能夠查看github上的README.CN.md,這個文件是中文說明,README.md是英文說明。測試截圖以下,其中網頁是用RTMP方式播放,VLC是HTTP方式播放:

最後,nginx-http-flv-module支持的nginx版本我測試到最舊的版本是1.2.6,更舊的版本沒有測試過,不保證兼容性。

目前商用已知有3家,其中一家反饋過很多bug,都一一修復。有問題能夠加QQ羣711969608詳聊,拒絕提供各平臺已經編譯好的可執行文件,提倡本身動手,豐衣足食。

相關文章
相關標籤/搜索