基于nginx-1.8.1+nginx-rtmp-module方案
多种实时流请求触发中继的实现
1.概述
- 视频直播方案基于nginx+rtmp;
- 集群内区分边缘和源务服器,边缘与源是基于rtmp流做同步的,有relay模块实现;
- 集群内服务器除提供rtmp实时流基础功能外,基于rtmp实时流,还提供了httplive stream(hls)实时流及http live flv(hlf)实时流;
- hls流实现详见ngx_http_auth_hls_module、ngx_rtmp_hls_module模块;
- hlf流实现详见ngx_http_hlf_module、ngx_rtmp_hlf_module模块;
- relay模块实现了当客户向边缘服务器请求某一路rtmp实时流且该流不存在时,会向配置的源服务器请求该rtmp实时流,请求成功后该边缘服务器分发该流给请求的客户,即中继开始;当最后一个请求该rtmp实时流的客户关闭流时,该边缘服务器会自动断开与源服务器该实时流的请求,即中继结束;
- 现有relay中继联动源是基于rtmp流请求的,针对hls、hlf流的请求源存在缺失,本文档针对该功能的实现进行阐述;
2.现有中继方案剖析
跟中继功能相关模块,目前有三个,分别是notify,auto-push,relay。
其中notify模块暂不介绍。
2.1auto-push
模块名:ngx_rtmp_auto_push_module;
应用于nginx多进程工作方式,当某一进程受理rtmp实时推流时,同时向其它工作进程实时推流,保证所有工作进程都有该实时流数据,以便各工作进程基于该流的服务,从而保证nginx服务的完整性;
各进程流同步是基于本地套接字来实现的;
剖析主要的三个函数:
2.1.1ngx_rtmp_auto_push_init_process
next_publish= ngx_rtmp_publish;
ngx_rtmp_publish =ngx_rtmp_auto_push_publish;
next_delete_stream =ngx_rtmp_delete_stream;
ngx_rtmp_delete_stream = ngx_rtmp_auto_push_delete_stream;
初始化本地侦听套接字
1.根据ngx_rtmp_init_connection查找ngx_listening_t实例来复制;
2.sokcet_name:
saun->sun_family = AF_UNIX;
*ngx_snprintf((u_char *) saun->sun_path,sizeof(saun->sun_path),
"%V/"NGX_RTMP_AUTO_PUSH_SOCKNAME ".%i",
&apcf->socket_dir,ngx_process_slot) = 0;
3.该套接字请求产生的ngx_rtmp_session_t *s,其中s->auto_pushed = 1;
2.1.2ngx_rtmp_auto_push_publish
推流事件上来时:
typedefstruct ngx_rtmp_auto_push_ctx_s ngx_rtmp_auto_push_ctx_t;
structngx_rtmp_auto_push_ctx_s {
ngx_int_t *slots; /*NGX_MAX_PROCESSES */
u_char name[NGX_RTMP_MAX_NAME];
u_char args[NGX_RTMP_MAX_ARGS];
ngx_event_t push_evt;
};
1.生成ngx_rtmp_auto_push_ctx_t *ctx;//上下文;
2.调用ngx_rtmp_auto_push_reconnect函数;
3.ngx_rtmp_auto_push_reconnect函数内再调用relay模块的ngx_rtmp_relay_push()函数;
4.实现断开重连的功能;
2.1.3ngx_rtmp_auto_push_delete_stream
推流会话断开时:
1.源session会话(推流)断开时,清除重连事件即可;
2.目标主机session会话(拉流)断开时/* skipnon-relays & publishers */,激活断开重连定时器;
前提是ngx_rtmp_relay_module模块该session的上下文指示的publish存在,若不存在说明源session会话已断开,不需要重连;
2.2relay
模块名:ngx_rtmp_relay_module;
实现基于rtmp流的中继功能;
重点剖析以下几部分:
2.2.1数据结构
typedefstruct {
ngx_array_t pulls; /* ngx_rtmp_relay_target_t * */
ngx_array_t pushes; /* ngx_rtmp_relay_target_t * */
ngx_array_t static_pulls; /* ngx_rtmp_relay_target_t * */
ngx_array_t static_events; /* ngx_event_t* */
ngx_log_t *log;
ngx_uint_t nbuckets;
ngx_msec_t buflen;
ngx_flag_t session_relay;
ngx_msec_t push_reconnect;
ngx_msec_t pull_reconnect;
ngx_rtmp_relay_ctx_t **ctx;
}ngx_rtmp_relay_app_conf_t;
typedefstruct {
ngx_url_t url;
ngx_str_t app;
ngx_str_t name;
ngx_str_t tc_url;
ngx_str_t page_url;
ngx_str_t swf_url;
ngx_str_t flash_ver;
ngx_str_t play_path;
ngx_int_t live;
ngx_int_t start;
ngx_int_t stop;
void *tag; /* usually module reference */
void *data; /* module-specific data */
ngx_uint_t