RTMP在NGINX的启动
本文主要介紹通過前文介紹的將rtmp模塊編譯進nginx情況下,啟動nginx時rtmp模塊主要做了哪些工作
Nginx的模塊開發三段式
定義nginx模塊需要定義三個變量:command,ctx,module。RTMP此三段式在rtmp.c文件中,模塊參考代碼如下:
static ngx_command_t ngx_rtmp_commands[] = {{ ngx_string("rtmp"),NGX_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,ngx_rtmp_block,0,0,NULL },ngx_null_command };static ngx_core_module_t ngx_rtmp_module_ctx = {ngx_string("rtmp"),NULL,NULL };ngx_module_t ngx_rtmp_module = {NGX_MODULE_V1,&ngx_rtmp_module_ctx, /* module context */ngx_rtmp_commands, /* module directives */NGX_CORE_MODULE, /* module type */NULL, /* init master */NULL, /* init module */ngx_rtmp_init_process, /* init process */NULL, /* init thread */NULL, /* exit thread */NULL, /* exit process */NULL, /* exit master */NGX_MODULE_V1_PADDING };RTMP模塊如何啟動?
RTMP模塊的啟動函數在ngx_rtmp_commands申明的ngx_rtmp_block()。下面主要講解如何調用:
- ngx_rtmp_commands的類型為ngx_command_t,其定義為: struct ngx_command_s {ngx_str_t name;ngx_uint_t type;char *(*set)(ngx_conf_t *cf, ngx_command_t *cmd, void*conf);ngx_uint_t conf;ngx_uint_t offset;void *post; }; rtmp_block對應是set指針
 -  
set的是在nginx啟動的時候,ngx_conf_handler()中調用,其簡化代碼如下。可以看出,其主要根據編譯時生成的ngx_modules變量,以此取出module定義的command和ctx,調用command的set函數依次啟動各個模塊
for (i = 0; ngx_modules[i]; i++) {cmd = ngx_modules[i]->commands;for ( /* void */ ; cmd->name.len; cmd++) {/* set up the directive's configuration context */conf = NULL;if (cmd->type & NGX_DIRECT_CONF) {conf = ((void **) cf->ctx)[ngx_modules[i]->index];} else if (cmd->type & NGX_MAIN_CONF) {conf = &(((void **) cf->ctx)[ngx_modules[i]->index]);} else if (cf->ctx) {confp = *(void **) ((char *) cf->ctx + cmd->conf);if (confp) {conf = confp[ngx_modules[i]->ctx_index];}}rv = cmd->set(cf, cmd, conf);} }調用鏈如下:
static ngx_int_t ngx_conf_handler(ngx_conf_t *cf, ngx_int_t last) ->char * ngx_conf_parse(ngx_conf_t *cf, ngx_str_t *filename) ->char * ngx_conf_param(ngx_conf_t *cf) ->ngx_cycle_t * ngx_init_cycle(ngx_cycle_t *old_cycle) ->int ngx_cdecl main(int argc, char *const *argv) -  
RTMP啟動做了什么?
RTMP啟動具體做了什么其實就是ngx_rtmp_block()的功能,此處簡略說明:
1、 計算RTMP模塊數并設置每個模塊的上下文索引
2、 為每個RTMP模塊創建main_conf
3、 為每個RTMP模塊創建srv_conf
4、 為每個RTMP模塊創建app_conf
5、 調用各個RTMP模塊preconfiguration
6、 初始化各個RTMP模塊 init_main_conf
7、 初始化各個RTMP模塊各個APP的merge_srv_conf
8、 初始化各個RTMP模塊各個APP的merge_app_conf
9、 初始化各個RTMP服務事件 
10、調用各個模塊postconfiguration,主要是注冊回調,具體如下
- NGX_RTMP_CONNECT
注冊模塊:ngx_rtmp_limit_module
注冊回調:ngx_rtmp_limit_connect; - NGX_RTMP_HANDSHAKE_DONE
注冊模塊:ngx_rtmp_relay_module中初始化
注冊回調:ngx_rtmp_relay_handshake_done - NGX_RTMP_DISCONNECT
注冊模塊:ngx_rtmp_cmd_module
注冊回調:ngx_rtmp_cmd_disconnect_init;
注冊模塊:ngx_rtmp_codec_module
注冊回調:ngx_rtmp_codec_disconnect;
注冊模塊:ngx_rtmp_limit_module
注冊回調:ngx_rtmp_limit_disconnect;
注冊模塊:ngx_rtmp_log_module
注冊回調:ngx_rtmp_log_disconnect;
注冊模塊:ngx_rtmp_netcall_module
注冊回調:ngx_rtmp_netcall_disconnect; - NGX_RTMP_MSG_AUDIO
注冊模塊:ngx_rtmp_codec_module
注冊回調:ngx_rtmp_codec_av
注冊模塊:ngx_rtmp_dash_module
注冊回調:ngx_rtmp_dash_video
注冊模塊:ngx_rtmp_hls_module
注冊回調:ngx_rtmp_hls_audio
注冊模塊:ngx_rtmp_live_module
注冊回調:ngx_rtmp_live_av
注冊模塊:ngx_rtmp_record_module
注冊回調:ngx_rtmp_record_av - NGX_RTMP_MSG_VIDEO
注冊模塊:ngx_rtmp_codec_module
注冊回調:ngx_rtmp_codec_av
注冊模塊:ngx_rtmp_dash_module
注冊回調:ngx_rtmp_dash_video
注冊模塊:ngx_rtmp_hls_module
注冊回調:ngx_rtmp_hls_audio
注冊模塊:ngx_rtmp_live_module
注冊回調:ngx_rtmp_live_av
注冊模塊:ngx_rtmp_record_module
注冊回調:ngx_rtmp_record_av 
11、 初始化事件處理,主要是AMF消息,特殊消息,處理回調注冊
static size_t pm_events[] = {NGX_RTMP_MSG_CHUNK_SIZE,NGX_RTMP_MSG_ABORT,NGX_RTMP_MSG_ACK,NGX_RTMP_MSG_ACK_SIZE,NGX_RTMP_MSG_BANDWIDTH};static size_t amf_events[] = {NGX_RTMP_MSG_AMF_CMD,NGX_RTMP_MSG_AMF_META,NGX_RTMP_MSG_AMF_SHARED,NGX_RTMP_MSG_AMF3_CMD,NGX_RTMP_MSG_AMF3_META,NGX_RTMP_MSG_AMF3_SHARED};/* init standard protocol events */for(n = 0; n < sizeof(pm_events) / sizeof(pm_events[0]); ++n) {eh = ngx_array_push(&cmcf->events[pm_events[n]]);*eh = ngx_rtmp_protocol_message_handler;}/* init amf events */for(n = 0; n < sizeof(amf_events) / sizeof(amf_events[0]); ++n) {eh = ngx_array_push(&cmcf->events[amf_events[n]]);*eh = ngx_rtmp_amf_message_handler;}/* init user protocol events */eh = ngx_array_push(&cmcf->events[NGX_RTMP_MSG_USER]);*eh = ngx_rtmp_user_message_handler;/* aggregate to audio/video map */eh = ngx_array_push(&cmcf->events[NGX_RTMP_MSG_AGGREGATE]);*eh = ngx_rtmp_aggregate_message_handler;特別需要提出的是在ngx_rtmp_cmd_module模塊,對相應的用戶控制消息進行注冊,代碼如下:
static ngx_rtmp_amf_handler_t ngx_rtmp_cmd_map[] = { { ngx_string("connect"), ngx_rtmp_cmd_connect_init }, { ngx_string("createStream"), ngx_rtmp_cmd_create_stream_init }, { ngx_string("closeStream"), ngx_rtmp_cmd_close_stream_init }, { ngx_string("deleteStream"), ngx_rtmp_cmd_delete_stream_init }, { ngx_string("publish"), ngx_rtmp_cmd_publish_init }, { ngx_string("play"), ngx_rtmp_cmd_play_init }, { ngx_string("play2"), ngx_rtmp_cmd_play2_init }, { ngx_string("seek"), ngx_rtmp_cmd_seek_init }, { ngx_string("pause"), ngx_rtmp_cmd_pause_init }, { ngx_string("pauseraw"), ngx_rtmp_cmd_pause_init }, };...... ncalls = sizeof(ngx_rtmp_cmd_map) / sizeof(ngx_rtmp_cmd_map[0]); ch = ngx_array_push_n(&cmcf->amf, ncalls); bh = ngx_rtmp_cmd_map; for(n = 0; n < ncalls; ++n, ++ch, ++bh) {*ch = *bh; } ......12、開始各個RTMP服務偵聽,注冊連接到時時執行ngx_rtmp_init_connection的回調
作者:黃澤武
鏈接:http://www.jianshu.com/p/7c934e1889e9
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
總結
以上是生活随笔為你收集整理的RTMP在NGINX的启动的全部內容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: AAC音频裸码流时间戳与时间长度的关系
 - 下一篇: 直播协议HTTP-FLV标准解读与技术实