近幾年直播行業火爆,開源的直播軟件解決方案有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詳聊,拒絕提供各平臺已經編譯好的可執行文件,提倡本身動手,豐衣足食。