0. 前言html
這段時間在搭建一個IPCamera項目服務器。視頻點對點通話,客戶端會查看設備端的音視頻實時流。爲了省流量,是經過P2P進行穿透。可是因爲NAT設備的緣由和IPV4的枯竭。有些設備是沒法進行點對點傳輸實時流。因此須要進行服務器轉發。這裏爲了快速實現原型,同時參考如今主流的流媒體協議。發現不少使用的是RTMP協議。java
下圖是整體設計圖,爲了整合多平臺,會自建RTMP流媒體服務器和使用雲廠商SaaS的RTMP流媒體服務。可是因爲有時候會傳輸一些非流媒體數據,須要傳輸一些二進制文件,因此會須要自定義媒體轉發服務。nginx
如下是我實際項目中,用到的架構實現流程圖。git
1 1. 客戶端A沒法進行P2P穿透,請求業務服務器要進行轉發。 2 2. 業務服務器根據客戶端A,請求類型,返回對應的轉發服務器地址和對應的房間號RoomID/Token等信息 3 3. 上述請求類型,能夠是請求自建RTMP流媒體服務,購買於雲廠商RTMP流媒體服務或者自定義協議媒體轉發服務 4 4. 客戶端A獲得業務服務器返回的媒體服務器地址和RoomID/Token 5 5. 經過信令服務器或者MQTT服務器,把對應的媒體服務器地址和RoomID/Token告訴另外一端客戶端B 6 6. 客戶端A和客戶端B同時進入相同房間Room,客戶端A進行推流,客戶端B進行拉流 7 7. 其餘媒體信息,如編解碼格式,清晰度,播放,暫停,拍照等命令,經過上述信令或MQTT服務器進行命令控制
1. 編譯Nginxgithub
RTMP流媒體服務器,現成的開源方案有不少,有SRS,Red5,wowoza,FMS等,我這裏使用的是Nginx的rtmp插件實現實時流轉發。web
下載 nginx-rtmp-module https://github.com/arut/nginx-rtmp-modulespring
從新編譯nginx 數據庫
1 --prefix=/opt/nginx --with-stream --with-http_ssl_module --with-stream_ssl_module --with-debug --add-module=../nginx-rtmp-module
2. 配置Nginx.conf小程序
基本的nginx配置,這裏就不進行介紹了,須要瞭解的能夠參考我其餘博客,裏面有介紹。這裏只介紹rtmp段的定義。微信小程序
1 rtmp{ 2 server{ 3 listen 8081; 4 access_log logs/rtmp_access.log; 5 on_connect http://127.0.0.1:8080/v1/rtmp/on_connect; 6 application rtmp { 7 live on; 8 notify_method get; 9 on_play http://127.0.0.1:8080/v1/rtmp/on_play; 10 on_publish http://127.0.0.1:8080/v1/rtmp/on_publish; 11 on_done http://127.0.0.1:8080/v1/rtmp/on_done; 12 on_play_done http://127.0.0.1:8080/v1/rtmp/on_play_done; 13 on_publish_done http://127.0.0.1:8080/v1/rtmp/on_publish_done; 14 on_record_done http://127.0.0.1:8080/v1/rtmp/on_record_done; 15 on_update http://127.0.0.1:8080/v1/rtmp/on_update; 16 notify_update_timeout 10s; 17 } 18 application vod { 19 play /opt/openresty/video; 20 } 21 } 22 }
3. HTTP異步通知回調
Nginx-rtmp-module插件實現了針對RTMP協議的一些命令作了事件通知。這裏我經過一個簡單的SpringBoot項目,快速搭建一個HTTP服務來接收RTMP的回調。
1 package com.wunaozai.rtmp.notify.controller; 2 3 import javax.servlet.http.HttpServletRequest; 4 5 import org.springframework.web.bind.annotation.GetMapping; 6 import org.springframework.web.bind.annotation.RequestMapping; 7 import org.springframework.web.bind.annotation.RestController; 8 9 @RestController 10 @RequestMapping(value="/v1/rtmp/") 11 public class RTMPNotifyController { 12 13 @GetMapping(value="/on_connect") 14 public String onConnect(HttpServletRequest request){ 15 debug(request, "on_connect"); 16 return "on_connect"; 17 } 18 @GetMapping(value="/on_play") 19 public String onPlay(HttpServletRequest request){ 20 debug(request, "on_play"); 21 return "on_play"; 22 } 23 @GetMapping(value="/on_publish") 24 public String onPublish(HttpServletRequest request){ 25 debug(request, "on_publish"); 26 return "on_publish"; 27 } 28 @GetMapping(value="/on_done") 29 public String onDone(HttpServletRequest request){ 30 debug(request, "on_done"); 31 return "on_done"; 32 } 33 @GetMapping(value="/on_play_done") 34 public String onPlayDone(HttpServletRequest request){ 35 debug(request, "on_play_done"); 36 return "on_play_done"; 37 } 38 @GetMapping(value="/on_publish_done") 39 public String onPublishDone(HttpServletRequest request){ 40 debug(request, "on_publish_done"); 41 return "on_publish_done"; 42 } 43 @GetMapping(value="/on_record_done") 44 public String onRecordDone(HttpServletRequest request){ 45 debug(request, "on_record_done"); 46 return "on_record_done"; 47 } 48 @GetMapping(value="/on_update") 49 public String onUpdate(HttpServletRequest request){ 50 debug(request, "on_update"); 51 return "on_update"; 52 } 53 54 private String debug(HttpServletRequest request, String action){ 55 String str = action + ": " + request.getRequestURI() + " " + request.getQueryString(); 56 System.out.println(str); 57 return str; 58 } 59 }
4. 運行效果
(1) 啓動nginx和SpringBoot
(2) 如下是SpringBoot打印信息(各位能夠簡單分析一下這些日誌的)
1 on_connect: /v1/rtmp/on_connect app=rtmp&flashver=FMLE/3.0%20(compatible%3B%20FMSc/1.0)&swfurl=&tcurl=rtmp://120.24.210.62:8081/rtmp&pageurl=&addr=113.74.127.195&epoch=178269841&call=connect 2 on_publish: /v1/rtmp/on_publish app=rtmp&flashver=FMLE/3.0%20(compatible%3B%20FMSc/1.0)&swfurl=&tcurl=rtmp://120.24.210.62:8081/rtmp&pageurl=&addr=113.74.127.195&clientid=541&call=publish&name=room&type=live 3 on_update: /v1/rtmp/on_update app=rtmp&flashver=FMLE/3.0%20(compatible%3B%20FMSc/1.0)&swfurl=&tcurl=rtmp://120.24.210.62:8081/rtmp&pageurl=&addr=113.74.127.195&clientid=541&call=update_publish&time=10×tamp=3999&name=room 4 on_done: /v1/rtmp/on_done app=rtmp&flashver=FMLE/3.0%20(compatible%3B%20FMSc/1.0)&swfurl=&tcurl=rtmp://120.24.210.62:8081/rtmp&pageurl=&addr=113.74.127.195&clientid=541&call=done&name=room 5 on_publish_done: /v1/rtmp/on_publish_done app=rtmp&flashver=FMLE/3.0%20(compatible%3B%20FMSc/1.0)&swfurl=&tcurl=rtmp://120.24.210.62:8081/rtmp&pageurl=&addr=113.74.127.195&clientid=541&call=publish_done&name=room 6 on_connect: /v1/rtmp/on_connect app=rtmp&flashver=FMLE/3.0%20(compatible%3B%20FMSc/1.0)&swfurl=&tcurl=rtmp://120.24.210.62:8081/rtmp&pageurl=&addr=113.74.127.195&epoch=178305623&call=connect 7 on_publish: /v1/rtmp/on_publish app=rtmp&flashver=FMLE/3.0%20(compatible%3B%20FMSc/1.0)&swfurl=&tcurl=rtmp://120.24.210.62:8081/rtmp&pageurl=&addr=113.74.127.195&clientid=547&call=publish&name=room&type=live 8 on_update: /v1/rtmp/on_update app=rtmp&flashver=FMLE/3.0%20(compatible%3B%20FMSc/1.0)&swfurl=&tcurl=rtmp://120.24.210.62:8081/rtmp&pageurl=&addr=113.74.127.195&clientid=547&call=update_publish&time=10×tamp=7296&name=room 9 on_update: /v1/rtmp/on_update app=rtmp&flashver=FMLE/3.0%20(compatible%3B%20FMSc/1.0)&swfurl=&tcurl=rtmp://120.24.210.62:8081/rtmp&pageurl=&addr=113.74.127.195&clientid=547&call=update_publish&time=20×tamp=17248&name=room 10 on_update: /v1/rtmp/on_update app=rtmp&flashver=FMLE/3.0%20(compatible%3B%20FMSc/1.0)&swfurl=&tcurl=rtmp://120.24.210.62:8081/rtmp&pageurl=&addr=113.74.127.195&clientid=547&call=update_publish&time=30×tamp=27328&name=room 11 on_update: /v1/rtmp/on_update app=rtmp&flashver=FMLE/3.0%20(compatible%3B%20FMSc/1.0)&swfurl=&tcurl=rtmp://120.24.210.62:8081/rtmp&pageurl=&addr=113.74.127.195&clientid=547&call=update_publish&time=40×tamp=37280&name=room 12 on_update: /v1/rtmp/on_update app=rtmp&flashver=FMLE/3.0%20(compatible%3B%20FMSc/1.0)&swfurl=&tcurl=rtmp://120.24.210.62:8081/rtmp&pageurl=&addr=113.74.127.195&clientid=547&call=update_publish&time=50×tamp=47296&name=room 13 on_update: /v1/rtmp/on_update app=rtmp&flashver=FMLE/3.0%20(compatible%3B%20FMSc/1.0)&swfurl=&tcurl=rtmp://120.24.210.62:8081/rtmp&pageurl=&addr=113.74.127.195&clientid=547&call=update_publish&time=60×tamp=57312&name=room 14 on_update: /v1/rtmp/on_update app=rtmp&flashver=FMLE/3.0%20(compatible%3B%20FMSc/1.0)&swfurl=&tcurl=rtmp://120.24.210.62:8081/rtmp&pageurl=&addr=113.74.127.195&clientid=547&call=update_publish&time=70×tamp=67264&name=room 15 on_connect: /v1/rtmp/on_connect app=rtmp&flashver=&swfurl=&tcurl=rtmp://rtmp.wunaozai.com:8081/rtmp&pageurl=&addr=113.74.127.195&epoch=178380351&call=connect 16 on_play: /v1/rtmp/on_play app=rtmp&flashver=&swfurl=&tcurl=rtmp://rtmp.wunaozai.com:8081/rtmp&pageurl=&addr=113.74.127.195&clientid=557&call=play&name=room&start=4294966296&duration=0&reset=0&pass=12345 17 on_play_done: /v1/rtmp/on_play_done app=rtmp&flashver=&swfurl=&tcurl=rtmp://rtmp.wunaozai.com:8081/rtmp&pageurl=&addr=113.74.127.195&clientid=557&call=play_done&name=room&pass=12345 18 on_done: /v1/rtmp/on_done app=rtmp&flashver=&swfurl=&tcurl=rtmp://rtmp.wunaozai.com:8081/rtmp&pageurl=&addr=113.74.127.195&clientid=557&call=done&name=room&pass=12345 19 on_update: /v1/rtmp/on_update app=rtmp&flashver=FMLE/3.0%20(compatible%3B%20FMSc/1.0)&swfurl=&tcurl=rtmp://120.24.210.62:8081/rtmp&pageurl=&addr=113.74.127.195&clientid=547&call=update_publish&time=80×tamp=77344&name=room 20 on_connect: /v1/rtmp/on_connect app=rtmp&flashver=&swfurl=&tcurl=rtmp://rtmp.wunaozai.com:8081/rtmp&pageurl=&addr=113.74.127.195&epoch=178388202&call=connect 21 on_play: /v1/rtmp/on_play app=rtmp&flashver=&swfurl=&tcurl=rtmp://rtmp.wunaozai.com:8081/rtmp&pageurl=&addr=113.74.127.195&clientid=563&call=play&name=room&start=4294966296&duration=0&reset=0&pass=12345 22 on_done: /v1/rtmp/on_done app=rtmp&flashver=&swfurl=&tcurl=rtmp://rtmp.wunaozai.com:8081/rtmp&pageurl=&addr=113.74.127.195&clientid=563&call=done&name=room&pass=12345 23 on_play_done: /v1/rtmp/on_play_done app=rtmp&flashver=&swfurl=&tcurl=rtmp://rtmp.wunaozai.com:8081/rtmp&pageurl=&addr=113.74.127.195&clientid=563&call=play_done&name=room&pass=12345 24 on_update: /v1/rtmp/on_update app=rtmp&flashver=FMLE/3.0%20(compatible%3B%20FMSc/1.0)&swfurl=&tcurl=rtmp://120.24.210.62:8081/rtmp&pageurl=&addr=113.74.127.195&clientid=547&call=update_publish&time=90×tamp=87360&name=room 25 on_connect: /v1/rtmp/on_connect app=rtmp&flashver=&swfurl=&tcurl=rtmp://rtmp.wunaozai.com:8081/rtmp&pageurl=&addr=113.74.127.195&epoch=178396146&call=connect 26 on_play: /v1/rtmp/on_play app=rtmp&flashver=&swfurl=&tcurl=rtmp://rtmp.wunaozai.com:8081/rtmp&pageurl=&addr=113.74.127.195&clientid=569&call=play&name=room&start=4294966296&duration=0&reset=0&pass=12345 27 on_done: /v1/rtmp/on_done app=rtmp&flashver=&swfurl=&tcurl=rtmp://rtmp.wunaozai.com:8081/rtmp&pageurl=&addr=113.74.127.195&clientid=569&call=done&name=room&pass=12345 28 on_play_done: /v1/rtmp/on_play_done app=rtmp&flashver=&swfurl=&tcurl=rtmp://rtmp.wunaozai.com:8081/rtmp&pageurl=&addr=113.74.127.195&clientid=569&call=play_done&name=room&pass=12345 29 on_connect: /v1/rtmp/on_connect app=rtmp&flashver=&swfurl=&tcurl=rtmp://rtmp.wunaozai.com:8081/rtmp&pageurl=&addr=113.74.127.195&epoch=178403666&call=connect 30 on_play: /v1/rtmp/on_play app=rtmp&flashver=&swfurl=&tcurl=rtmp://rtmp.wunaozai.com:8081/rtmp&pageurl=&addr=113.74.127.195&clientid=574&call=play&name=room&start=4294966296&duration=0&reset=0&pass=12345 31 on_update: /v1/rtmp/on_update app=rtmp&flashver=FMLE/3.0%20(compatible%3B%20FMSc/1.0)&swfurl=&tcurl=rtmp://120.24.210.62:8081/rtmp&pageurl=&addr=113.74.127.195&clientid=547&call=update_publish&time=100×tamp=97311&name=room 32 on_update: /v1/rtmp/on_update app=rtmp&flashver=&swfurl=&tcurl=rtmp://rtmp.wunaozai.com:8081/rtmp&pageurl=&addr=113.74.127.195&clientid=574&call=update_play&time=10×tamp=105504&name=room&pass=12345 33 on_update: /v1/rtmp/on_update app=rtmp&flashver=FMLE/3.0%20(compatible%3B%20FMSc/1.0)&swfurl=&tcurl=rtmp://120.24.210.62:8081/rtmp&pageurl=&addr=113.74.127.195&clientid=547&call=update_publish&time=110×tamp=107199&name=room 34 on_done: /v1/rtmp/on_done app=rtmp&flashver=&swfurl=&tcurl=rtmp://rtmp.wunaozai.com:8081/rtmp&pageurl=&addr=113.74.127.195&clientid=574&call=done&name=room&pass=12345 35 on_play_done: /v1/rtmp/on_play_done app=rtmp&flashver=&swfurl=&tcurl=rtmp://rtmp.wunaozai.com:8081/rtmp&pageurl=&addr=113.74.127.195&clientid=574&call=play_done&name=room&pass=12345 36 on_update: /v1/rtmp/on_update app=rtmp&flashver=FMLE/3.0%20(compatible%3B%20FMSc/1.0)&swfurl=&tcurl=rtmp://120.24.210.62:8081/rtmp&pageurl=&addr=113.74.127.195&clientid=547&call=update_publish&time=120×tamp=117344&name=room 37 on_update: /v1/rtmp/on_update app=rtmp&flashver=FMLE/3.0%20(compatible%3B%20FMSc/1.0)&swfurl=&tcurl=rtmp://120.24.210.62:8081/rtmp&pageurl=&addr=113.74.127.195&clientid=547&call=update_publish&time=130×tamp=122815&name=room
(3) 客戶端進行推流,這裏的推流軟件,我是使用這個 http://www.iavcast.com/html/ruanjian/iavcast.html
(4) 移動端,我使用微信小程序裏的 騰訊視頻雲 這個小程序裏面有RTMP測試
(5) nginx-rtmp 日誌
1 113.74.127.195 [05/Aug/2018:16:18:08 +0800] PUBLISH "rtmp" "room" "" - 2646572 687 "" "FMLE/3.0 (compatible; FMSc/1.0)" (1m 46s) 2 113.74.127.195 [05/Aug/2018:16:19:49 +0800] PLAY "rtmp" "room" "pass=12345" - 413 542 "" "" (4s) 3 113.74.127.195 [05/Aug/2018:16:19:57 +0800] PLAY "rtmp" "room" "pass=12345" - 413 542 "" "" (4s) 4 113.74.127.195 [05/Aug/2018:16:20:05 +0800] PLAY "rtmp" "room" "pass=12345" - 413 542 "" "" (4s) 5 113.74.127.195 [05/Aug/2018:16:20:13 +0800] PLAY "rtmp" "room" "pass=12345" - 413 542 "" "" (4s) 6 113.74.127.195 [05/Aug/2018:16:30:39 +0800] PLAY "rtmp" "room" "pass=12345" - 413 871 "" "" (4s) 7 113.74.127.195 [05/Aug/2018:16:30:54 +0800] PLAY "rtmp" "room" "pass=12345" - 413 647163 "" "" (12s) 8 113.74.127.195 [05/Aug/2018:16:31:08 +0800] PUBLISH "rtmp" "room" "" - 4961955 409 "" "FMLE/3.0 (compatible; FMSc/1.0)" (1m 30s) 9 113.74.127.195 [05/Aug/2018:23:06:47 +0800] PUBLISH "rtmp" "room" "" - 425763 529 "" "FMLE/3.0 (compatible; FMSc/1.0)" (13s) 10 113.74.127.195 [05/Aug/2018:23:08:29 +0800] PLAY "rtmp" "room" "pass=12345" - 413 871 "" "" (4s) 11 113.74.127.195 [05/Aug/2018:23:08:37 +0800] PLAY "rtmp" "room" "pass=12345" - 413 871 "" "" (4s) 12 113.74.127.195 [05/Aug/2018:23:08:45 +0800] PLAY "rtmp" "room" "pass=12345" - 413 871 "" "" (4s) 13 113.74.127.195 [05/Aug/2018:23:09:05 +0800] PLAY "rtmp" "room" "pass=12345" - 413 926026 "" "" (17s) 14 113.74.127.195 [05/Aug/2018:23:09:30 +0800] PUBLISH "rtmp" "room" "" - 7061016 409 "" "FMLE/3.0 (compatible; FMSc/1.0)" (2m 20s)
5. RTMP鑑權方式
通常商用的話,爲了防止被其餘人使用和安全性考慮,因此須要對RTMP進行鑑權處理。鑑權若是有特殊性的,能夠經過修改nginx-rtmp-module的源代碼,而後進行修改,其實就是增長個auth函數,這個函數能夠查詢數據庫之類的,而後決定返回0成功仍是-1表示失敗。
除了上面說到的方式,還能夠經過簡單的方式,就是上面提到的HTTP回調。若是HTTP回調返回的HTTP狀態碼是2xx的,表示成功。若是是返回5xx的狀態碼,那麼表示失敗。那樣的話,服務器就是斷開RTMP鏈接。
就是在rtmp://rtmp.wunaozai.com/rtmp_live/room?username=username&password=password
至於實現,這裏暫時尚未,其實就是在SpringBoot項目中對每一個請求,判斷一下參數便可。若是後面有機會就詳細寫一下,關聯Redis數據庫,實現房間號功能。可是可能不會寫了,由於實際上不難。就是整個流程跑通仍是比較多代碼要寫的,在博客裏貼太多代碼有點很差。博客最主要的仍是提供思路。實際實現就應該在項目中實現了。
6. 其餘
這裏是一些配置說明和示例
1 Application 建立一個RTMP應用,這裏有點區別於http的location 2 Timeout 60s 3 stocket超時,能夠配合keepalive和ping值來實現不讓服務器端長期處於監聽鏈接客戶端狀態,實現快速關掉socket 4 Ping 3m 5 ping_timeout 30s 6 RTMP ping用於檢查活動鏈接的協議。發送一個特殊的包遠程鏈接,在ping_timeout指定時間內期待一個回覆,若是沒有收到回覆,鏈接斷開 7 max_streams 32 8 設置RTMP流的最大數目,單一流數據最大限制,通常默認的32就能夠了 9 ack_window 5000000 10 設置RTMP窗口的大小 11 chunk_size 4096 12 數據塊大小 設置值越大CPU負載就越小 13 max_queue 14 最大隊列數,通常默認便可 15 max_message 1M 16 輸入數據消息的最大大小。全部輸入數據消息都會保存在內存中,等待完成流媒體轉發。在理論上傳入的消息能夠是很是大,對服務器穩定性影響較大,因此通常默認便可。 17 out_queue 18 out_cork 19 Buflen 5s 20 設置默認緩衝區長度。一般客戶端發送播放前RTMP set_buflen命令並重置該設置 21 22 訪問控制 23 Access 24 Allow/deny 25 容許來自指定地址或者全部地址發佈/播放 26 Allow public 127.0.0.1 27 Deny publish all; 28 Allow play 192.168.0.0/24 29 Deny play all; 30 31 Exec命令 32 Exce 33 exec_options on; 34 啓動一些exec指令選項,經過一些exec事件來干預整個RTMP流 35 能夠仔細一些外部編解碼功能 36 Exec ffmpeg -i rtmp://localhost?src/$name -vcodec libx264 -vprofile baseline -g 10 -s 300x200 -acodec libfaac -ar 44100 -ac 1 -f flv rtmp://localhost/hls/$name 2>> /var/log/ffmpeg-$name.log; 37 Exce_statc 38 相似exce,屬於靜態命令,不支持傳遞上下文參數 39 Exec_kill_signal term; 40 Exec_kill_signal user1; 41 Exec_kill_signal 3; 42 Exec_pull 43 Exec_push 44 Exec_publish 45 指定與參數外部命令要在發佈事件執行。 46 Exec_play 47 指定與要在打開事件執行外部命令 48 Exec_play_done 49 指定要在打開完成事件執行外部命令 50 Exec_publish_done 51 Exec_record_done 52 例子 53 exec_play bash -c 「echo $addr $pageurl >> /tmp/clients」 54 Exec_publish base -c 「echo $addr $flashver >> /tmp/publishers」 55 轉錄 56 Exec_record_done ffmpeg -y -i $path -acodec libmp31ame -ar 44100 -ac 1 -vcodec libx264 $dirname/$basename.mp4 57 58 Live 模式 59 Live on 60 切換直播模式,即一對多廣播 61 Meta on/copy/off 62 奇幻發送元數據到客戶端 默認on 63 Interleave on/off 64 切換交叉模式。在該模式下,音視頻會在同一個RTMPchunk流中傳輸。默認爲off 65 wait_key on|off 66 使視頻流從一個關鍵幀開始,默認爲off 67 wait_video on|off 68 在一個視頻幀發送前禁用音頻。默認off 69 經過wait_key/wait_video進行組合以使客戶端能夠收到具備全部其餘數據的視頻關鍵幀。但這樣會增長鏈接延遲。不過能夠經過編解碼器中調整關鍵幀間隔來減小延遲。 70 Publish_notify on 71 發送NetStream.Publish.Start和NetStream.Publish.Stop給用戶,默認off 72 Drop_idle_publisher 10s 73 終止指定時間內閒置(沒有音頻、視頻)的發佈鏈接,默認爲off。注意這個僅僅對於發佈模式的鏈接起做用(發送publish命令以後) 74 Sync 10ms 75 同步音視頻流。若是用戶帶寬不足以接收發布率,服務器會丟棄一些幀。這將致使同步問題。當時間戳差超過sync指定值,將會發送一個絕對幀來解決這個問題,默認爲300ms 76 Play_restart off 77 使nginx-rtmp可以在發佈啓動或者中止時發送NetStream.Play.Start 和 NetStrem.Play.Stop到每一個用戶。若是關閉的話,那麼每一個用戶就只能在回放的開始結束時收到該通知了。默認爲on 78 79 Record 模式 80 Record off|all|audio|video|keyframes|manual 81 切換錄製模式,流能夠被記錄到flv文件 82 Off 不錄製 83 All 錄製音頻和視頻 84 Audio 85 Video 86 Keyframes 只錄制關鍵視頻幀 87 Manual 不自動啓動錄製,使用控制接口來進行啓動和中止 88 Record_path /tmp/rec 89 指定錄製的flv文件存放目錄 90 Record_suffix -%d-%b-%y-%T.flv 91 錄製後綴strftime格式 92 Record_unique on|off 93 是否添加時間戳到錄製文件,防止文件被覆蓋,默認off 94 record_append on|off 95 切換文件附加模式。開啓後,錄製時將新數據附加到舊文件後面。默認off 96 record_lock on|off 97 鎖定文件,調用系統的fcntl 98 record_max_size 128K 99 設置錄製文件的最大值 100 Record_max_frames 2 101 設置每一個錄製文件的視頻幀最大數量 102 Record_interval 1s/15m 103 在這個指令指定的時間以後重啓錄製。默認off設置爲0表示錄製中無延遲。若是record_unique爲off時全部的記錄都會被寫到同一個文件中。不然就會以時間戳區分在不一樣文件 104 Record_notify on|off 105 奇幻當定義錄製啓動或者中止文件時發送NetStream.Record.Start和NetStream.Record.Stop狀態信息onStatus到發佈者。 106 107 應用 108 Application rtmp{ 109 Live on; 110 Record all; 111 Record_path /var/rec; 112 113 Recorder audio{ 114 Record audio; 115 Record_suffix .audio.flv; 116 } 117 Recorder chunked{ 118 Record all; 119 Record_interval 15s; 120 Record_path /var/rec/chunked; 121 } 122 } 123 建立錄製塊。能夠在單個application中建立多個記錄 。 124 125 VOD媒體 126 Play dir|http://loc 127 播放指定目錄或者HTTP地址的flv或者mp4文件。注意HTTP播放是要在整個文件下載完後纔開始播放。同一個play能夠播放多個視頻地址(用於負載)。MP4格式要在編解碼都被RTMP支持才能夠播放。通常常見的就是H264/AAC 128 Application vod{ 129 Play /var/flvs; 130 } 131 Application vod_http{ 132 Play http://localhost/vod; 133 } 134 Play_temp_path /www 135 設置遠程VOD文件徹底下載以後複製於play_temp_path以後的路徑。空值的話禁用此功能。 136 Play_local_path dir 137 在播放前設置遠程存儲VOD文件路徑,默認/tmp 138 Play_local_path /tmp/videos; 139 Paly /tmp/videos http://localhost/videos 140 表示播放視頻,先播放本地緩存,若是沒有的話,從localhost/videos下載到本地/tmp/videos後,在進行播放 141 142 143 Relay模式 144 Pull url [key=value] 145 建立pull中繼。主要是從遠程服務器拉取流媒體。並進行從新發布。 146 Url語法 [rtmp://]host[:port][/app[/playpath]] 若是application找不到那麼將會使用本地application名,若是找不到playpath那麼久用當前流名稱。 147 參數以下(使用Key=Value方式) 148 app 明確application名 149 Name 捆綁到relay的bending流名稱。若是爲空,那麼會使用application中全部本地流 150 tcUrl 151 pageUrl 152 swfUrl 153 flashVer 154 playPath 155 Live 156 Start 157 Stop 158 Static 159 Pull rtmp://cdn.example.com/main/ch?id=1234 name=channel; 160 Push url [key=value] 161 與pull相似,只是push推送發佈流到遠程服務器。 162 Push_reconnect 1s 163 在斷開鏈接後,在push從新鏈接錢等待的時間,默認3秒 164 Session_relay on; 165 切換會話relay模式。在這種狀況下關閉時relay銷燬。 166 167 Notify 模式 168 這個功能主要是提供HTTP回調。當發送一些鏈接操做是,一個HTTP請求異步發送。命令處理會被暫停掛起,知道它返回結果代碼。當HTTP返回2xx成功狀態碼時,RTMP會話繼續。3xx狀態碼會使RTMP重定向到另外一個從HTTP返回頭獲取到的application,不然鏈接丟失。其餘狀態碼,鏈接斷開。目前用來作簡單的鑑權。 169 On_connect url 170 設置HTTP鏈接回調。當客戶分發鏈接命令時。 171 例子: 172 On_connect http://localhost/my_auth; 173 Location /on_connect{ 174 If($arg_flashver != 「my_secret_flashver」){ 175 Rewrite ^.*$ fallback?permanent; 176 } 177 } 178 On_play url 179 設置HTTP播放回調。分發客戶分發播放命令時。 180 http { 181 Location /redirect { 182 Rewrite ^.*$ newname?permanent; 183 } 184 } 185 Rtmp{ 186 Application myqpp{ 187 Live on; 188 On_play http://localhost/redirect; 189 } 190 } 191 On_publish 192 On_doone 193 On_play_done 194 On_publish_done 195 On_record_done 196 On_update 197 Notify_update_timeout 198 設置on_update回調時間 199 Notify_update_strict on|off 200 Notify_relay_redirect on 201 Notify_method get 202 設置HTTP方法通知,默認是application/x-www-form-urlencodeed 的POST內容類型。有時候可能會須要GET方法,在nginx的http{}部分處理調用。在這種狀況下可使用arg_*變量去訪問參數。 203 例如若是是method爲get時 204 Location /on_play{ 205 If($arg_pageUrl ~* localhost){ 206 Return 200; 207 } 208 Return 500; 209 } 210 211 HLS 模式 212 Hls on|off 213 使application 切換HLS協議直播 214 Hls_path /tmp/hls; 215 設置HLS播放列表和分段目錄。這一目錄必須在nginx啓動前就已經存在。 216 Hls_fragment 15s; 217 設置HLS分段長度,默認5秒,這個跟直播延遲有比較大的影響 218 Hls_playlist_length 20m; 219 設置HLS播放列表長度,默認30秒。這個跟直播緩存有關。 220 Hls_sync time 221 設置HLS時間戳同步閾值。默認2ms。這個功能防止由低分辨率RTMP(1KHz)轉換到高分辨率MPEG-TS(90KHz)以後出現的噪音。 222 Hls_continuous on|off 223 切換HLS連續模式,默認off。 224 Hls_nested on|off 225 切換HLS嵌套模式。默認off。 226 Hls_cleanup on|off; 227 切換HLS清理。默認on 228 229 AccessLog日誌 230 Access_log off|path [format_name] 231 Log_format new_format ‘$remote_addr’; 232 Access_log logs/rtmp_access.log new_format; 233 Log_format 指定日誌格式 234 建立指定的日誌格式。日誌格式看起來很像 nginx HTTP 日誌格式。日誌格式裏支持的幾個變量有: 235 * connection - 鏈接數。 236 * remote_addr - 客戶端地址。 237 * app - application 名。 238 * name - 上一個流名。 239 * args - 上一個流播放/發佈參數。 240 * flashver - 客戶端 flash 版本。 241 * swfurl - 客戶端 swf url。 242 * tcurl - 客戶端 tcUrl。 243 * pageurl - 客戶端頁面 url。 244 * command - 客戶端發送的播放/發佈命令:NONE、PLAY、PUBLISH、PLAY+PUBLISH。 245 * bytes_sent - 發送到客戶端的字節數。 246 * bytes_received - 從客戶端接收到的字節數。 247 * time_local - 客戶端鏈接結束的本地時間。 248 * session_time - 持續鏈接的秒數。 249 * session_readable_time - 在可讀格式下的持續時間。 250 默認的日誌格式叫作 combined。這裏是這一格式的定義: 251 $remote_addr [$time_local] $command "$app" "$name" "$args" - 252 $bytes_received $bytes_sent "$pageurl" "$flashver" ($session_readable_time) 253 254 Limits限制 255 max_connections number; 256 設置rtmp引擎最大鏈接數,默認off 257 258 Application hls{ 259 Live on; 260 Hls on; 261 Hls_path /tmp/hls; 262 Hls_fragment 15s; 263 }
因爲開發是在Windows上完成的,因此須要有Windows環境,這樣測試起來比較方便。發現一個很好的功能: https://github.com/illuspas/nginx-rtmp-win32
參考資料
https://github.com/arut/nginx-rtmp-module
https://blog.csdn.net/cui918/article/details/53540397
http://www.javashuo.com/article/p-zcharmil-km.html
http://www.javashuo.com/article/p-pqryrlgi-kp.html