Nginx-rtmp 直播媒體實時流實現


這兩篇博客也是跟直播流媒體相關的(2019-11-08)

 

物聯網架構成長之路(41)-直播流媒體入門(RTSP篇) https://www.cnblogs.com/wunaozai/p/11772060.html
物聯網架構成長之路(42)-直播流媒體入門(RTMP篇) https://www.cnblogs.com/wunaozai/p/11772392.html

 

 

0. 前言

  這段時間在搭建一個IPCamera項目服務器。視頻點對點通話,客戶端會查看設備端的音視頻實時流。為了省流量,是通過P2P進行穿透。但是由於NAT設備的原因和IPV4的枯竭。有些設備是無法進行點對點傳輸實時流。所以需要進行服務器轉發。這里為了快速實現原型,同時參考現在主流的流媒體協議。發現很多使用的是RTMP協議。

  下圖是總體設計圖,為了整合多平台,會自建RTMP流媒體服務器和使用雲廠商SaaS的RTMP流媒體服務。但是由於有時候會傳輸一些非流媒體數據,需要傳輸一些二進制文件,所以會需要自定義媒體轉發服務。

  以下是我實際項目中,用到的架構實現流程圖。

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. 編譯Nginx

  RTMP流媒體服務器,現成的開源方案有很多,有SRS,Red5,wowoza,FMS等,我這里使用的是Nginx的rtmp插件實現實時流轉發。

  下載 nginx-rtmp-module  https://github.com/arut/nginx-rtmp-module

  重新編譯nginx 

1 --prefix=/opt/nginx --with-stream --with-http_ssl_module --with-stream_ssl_module --with-debug --add-module=../nginx-rtmp-module

  文末提供Windows版本已經編譯好的exe下載

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&timestamp=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&timestamp=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&timestamp=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&timestamp=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&timestamp=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&timestamp=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&timestamp=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&timestamp=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&timestamp=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&timestamp=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&timestamp=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&timestamp=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&timestamp=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&timestamp=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&timestamp=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

  https://www.cnblogs.com/zx-admin/p/5783523.html

  https://www.cnblogs.com/lidabo/p/7099501.html

  https://blog.csdn.net/wei389083222/article/details/78721074

Nginx-RTMP Windows二進制下載: https://files.cnblogs.com/files/wunaozai/nginx-rtmp-win32-master.rar

本文地址: https://www.cnblogs.com/wunaozai/p/9427730.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM