nginx模塊概述
1:??Module Configuration Struct(s)模塊配置結(jié)構(gòu)
這個(gè)結(jié)構(gòu)的命名規(guī)則為ngx_http_[module-name]_[main|srv|loc]_conf_t仰猖。
main,srv,loc表示這個(gè)模塊的作用范圍是配置文件中的main/server/location三種范圍(這個(gè)需要記住邢隧,后面會(huì)經(jīng)常用到)
2: Module Directives模塊命令結(jié)構(gòu)
static?ngx_command_t ngx_http_echo_commands[] = {
{
ngx_string("echo"), //命令名字
NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, //代表是local配置群发,帶一個(gè)參數(shù)
ngx_http_echo, //組裝模塊配置結(jié)構(gòu)
NGX_HTTP_LOC_CONF_OFFSET, //上面的組裝模塊配置獲取完參數(shù)后存放到 哪里领虹?使用這個(gè)和下面的offset參數(shù)來進(jìn)行定位
offsetof(ngx_http_echo_loc_conf_t, ed), //同上?
},
ngx_null_command //必須使用ngx_null_command作為commands的結(jié)束標(biāo)記
};
3: The Module Context模塊內(nèi)容
static ngx_http_module_t???ngx_http_circle_gif_module_ctx
主要是定義了一些鉤子函數(shù), nginx會(huì)在不同時(shí)期會(huì)調(diào)用
4: The Module Definition模塊整合
ngx_module_t ngx_http_<module name>_module = {
NGX_MODULE_V1,
&ngx_http__module_ctx, /* module context模塊內(nèi)容 */
ngx_http__commands, /* module directives模塊命令*/
NGX_HTTP_MODULE, /* module type模塊類型,HTTP模塊揍移,或者HTTPS*/
5: Module Installation模塊安裝
nginx-rtmp的兩個(gè)核心模塊
1: ngx_rtmp_live_module
直播模塊:推拉流同點(diǎn), 不涉及回源
2: ngx_rtmp_relay_module
中繼模塊: ?1:回源pull ?2: 轉(zhuǎn)推: push
nginx-rtmp的總體流程分析
一:? 建立rtmp連接, 需要握手
??????1: ngx_rtmp_handshake_recv()開始握手
? ? ? 2: NGX_RTMP_HANDSHAKE_DONE()握手完成
? ? ? 3: ngx_rtmp_cycle()重新設(shè)置讀寫handler
二:? 建立網(wǎng)絡(luò)連接
????建立rtmp連接之后, ngx_rtmp_recv函數(shù)會(huì)利用ngx_event_t結(jié)構(gòu)會(huì)獲取推送過來的原始數(shù)據(jù), 接受到的數(shù)據(jù)會(huì)存放到ngx_rtmp_stream_t的in鏈表結(jié)構(gòu)中.
1:接受chunk數(shù)據(jù)
2:分析處理chunk數(shù)據(jù), 如果message還沒接受完, 繼續(xù)接受數(shù)據(jù)
3:將chunk組成一個(gè)rtmp message, 然后交給ngx_rtmp_receive_message處理, 這個(gè)函數(shù)根據(jù)消息的類型找對(duì)應(yīng)的handle
三:? 建立網(wǎng)絡(luò)流
????????在建立網(wǎng)絡(luò)連接后,就需要建立網(wǎng)絡(luò)流了, 網(wǎng)絡(luò)流代表了發(fā)送多媒體數(shù)據(jù)的通道. 服務(wù)器和客戶端只能建立一個(gè)網(wǎng)絡(luò)連接, 且多個(gè)網(wǎng)絡(luò)流可以復(fù)用這一個(gè)網(wǎng)絡(luò)連接
1: ngx_rtmp_recv接受數(shù)據(jù)后交給ngx_rtmp_receive_handler, 它會(huì)根據(jù)類型區(qū)別處理, 此時(shí)客戶端發(fā)送ngx_rtmp_msg_chunk_size類型的消息
2:接受message后跳轉(zhuǎn)到處理函數(shù)ngx_rtmp_amf_message_handler. 處理客戶端發(fā)送的amf控制消息. 此時(shí)連續(xù)接受3個(gè)amf數(shù)據(jù).
3:調(diào)用ngx_rtmp_cmd_create_stream_init初始化網(wǎng)絡(luò)流. 利用ngx_rtmp_receive_amf獲取接受的amf數(shù)據(jù).
4:調(diào)用ngx_rtmp_cmd_create_stream創(chuàng)建網(wǎng)絡(luò)流, 利用ngx_rtmp_send_amf向客戶端發(fā)送amf控制消息
四:? 傳輸媒體數(shù)據(jù)
在客戶端和服務(wù)端建立網(wǎng)絡(luò)流之后,接下來就可以傳輸媒體數(shù)據(jù)了, 一般來講, 媒體數(shù)據(jù)分為兩部分, 一部分為meta元信息, 另一部分是音視頻數(shù)據(jù), 首先傳送的是meta元信息. 然后推送媒體. 服務(wù)器處理如下:
1:從客戶端接受amf命令信息, 然后服務(wù)端會(huì)利用ngx_rtmp_cmd_publish_init來初始化發(fā)布環(huán)境. ?函數(shù)功能: 會(huì)讀取剛接受端amf信息
2:利用ngx_rtmp_auto_push_publish, ngx_rtmp_notify_publish, ngx_rtmp_exec_publish建立發(fā)布環(huán)境,
3:如果conf配置了record命令記錄媒體文件, 此時(shí)會(huì)調(diào)用ngx_rtmp_record_publish來初始化記錄環(huán)境;
4:執(zhí)行ngx_rtmp_access_publish;
[if !supportLists]l?[endif]meta信息:
5:接受客戶端amf, 并調(diào)用ngx_rtmp_codec_meta_data獲取meta元信息;
6:結(jié)合服務(wù)器的參數(shù), 利用ngx_rtmp_codec_reconstruct_meta接口重構(gòu)meta元信息, 并調(diào)用ngx_rtmp_prepare_message組成消息保存
[if !supportLists]l?[endif]媒體數(shù)據(jù):
7:接受客戶端推送, 根據(jù)類型轉(zhuǎn)到ngx_rtmp_codec_av來處理音視頻數(shù)據(jù); 其中利用函數(shù)ngx_rtmp_codec_parse_avc_header來處理頭部信息
8:調(diào)用record模塊記錄數(shù)據(jù), 接口為ngx_rtmp_codec_av;
9:調(diào)用live模塊來廣播發(fā)布數(shù)據(jù), 接口為ngx_rtmp_live_av, 廣播到所有觀察者, 第一次調(diào)用接口ngx_rtmp_live_start創(chuàng)建廣播, 之后直接調(diào)用ngx_rtmp_append_shared-bufs
?
rtmp的信令交互圖:
ngx_rtmp_relay_module: pull模型分析
1:?播放器端發(fā)起play
2: ngx_rtmp_relay_play()
3: ngx_rtmp_relay_pull() --主要建立pull請(qǐng)求, 將遠(yuǎn)程拉流的上下文和本地上下文放到鏈表中
????ngx_rtmp_relay_create_local_ctx()創(chuàng)建本地上下文
????ngx_rtmp_relay_create_remote_ctx()創(chuàng)建遠(yuǎn)端上下文
4: ngx_rtmp_relay_create_remote_ctx詳解: ?創(chuàng)建遠(yuǎn)端session, 開始rtmp信令交互
? ? ? ?1: ngx_rtmp_relay_create_connection ?
????????2: ngx_rtmp_init_session
注意:此時(shí)session中的flashver為“ngx-local-relay“
5: rtmp信令交互流程
核心函數(shù): ngx_rtmp_relay_on_result主要用來接收對(duì)端服務(wù)端發(fā)送的amf消息包只损,而后按正常rtmp協(xié)議請(qǐng)求進(jìn)行下一步交互,這個(gè)主要是當(dāng)前服務(wù)端做為客戶端發(fā)起遠(yuǎn)程rtmp請(qǐng)求流程
例如:? ?ngx_rtmp_client_handshake(發(fā)起握手)
? ? ? ? ?握手完成后調(diào)用回調(diào)函數(shù): ngx_rtmp_relay_handshake_done
? ? ? ?ngx_rtmp_relay_send_connect:發(fā)起連接請(qǐng)求, 接著參考rtmp信令交互圖
ngx_rtmp_live_module模塊簡(jiǎn)介
????????核心功能:向nginx推送一個(gè)直播流包各,該直播流經(jīng) nginx-rtmp 的 ngx_rtmp_live_module 模塊轉(zhuǎn)發(fā)給 application live 應(yīng)用摘仅,然后使用vlc連接 live,播放該直播流问畅。本質(zhì)上就是1對(duì)多的廣播
開啟debug日志
參考:http://nginx.org/en/docs/debugging_log.html
nginx-rtmp資料
1: Nginx-rtmp-module模塊源碼學(xué)習(xí)
https://blog.evanxia.com/2017/02/1264
2: nginx_rtmp_relay_module模塊解讀
https://www.shangmayuan.com/a/d74b78669f804fb5b12cae5a.html
3:開發(fā)手冊(cè)中文版:包含指令介紹