学习nginx-rtmp:replay push代码流程
来源:互联网 发布:淘宝网冬之恋羊绒线 编辑:程序博客网 时间:2024/05/13 09:52
1, 如何触发connect到push上游服务器的
h = ngx_array_push(&cmcf->events[NGX_RTMP_HANDSHAKE_DONE]);
*h = ngx_rtmp_relay_handshake_done;
在服务器有流push上来后,也就是NGX_RTMP_HANDSHAKE_DONE事件后,触发ngx_rtmp_relay_handshake_done,完成向上游的rtmp connect。
ngx_rtmp_relay_handshake_done---->ngx_rtmp_relay_send_connect--------->ngx_rtmp_send_chunk_size,ngx_rtmp_send_ack_size, ngx_rtmp_send_amf(connect)
2, 如何完成后续rtmp create, push的收发的
cmcf = ngx_rtmp_conf_get_module_main_conf(cf, ngx_rtmp_core_module);
ch = ngx_array_push(&cmcf->amf);
ngx_str_set(&ch->name, "_result");
ch->handler = ngx_rtmp_relay_on_result;//注册了与上游rtmp服务器的协议处理函数
在ngx_rtmp_relay_on_result函数中,处理了协议回调:
static ngx_int_t
ngx_rtmp_relay_on_result(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h, ngx_chain_t *in){
......
switch ((ngx_int_t)v.trans) {
case NGX_RTMP_RELAY_CONNECT_TRANS://如果rtmp connect返回后,立马发送create_stream
return ngx_rtmp_relay_send_create_stream(s);
case NGX_RTMP_RELAY_CREATE_STREAM_TRANS://如果create_stream返回后,立马发送rtmp_publish
if (ctx->publish != ctx && !s->static_relay) {
if (ngx_rtmp_relay_send_publish(s) != NGX_OK) {
return NGX_ERROR;
}
//这个ngx_rtmp_relay_play_local函数比较有意思,就是从本地拉流一份。
//其实就是把对上游rtmp的session作为订阅者,放入这个application stream的订阅者列表中。
//然后本地的会在发送给所有订阅者列表循环中,把rtmp流发送给上游rtmp服务器
return ngx_rtmp_relay_play_local(s);
} else {
if (ngx_rtmp_relay_send_play(s) != NGX_OK) {
return NGX_ERROR;
}
return ngx_rtmp_relay_publish_local(s);
}
default:
return NGX_OK;
}
}
在函数ngx_rtmp_relay_play_local中,调用ngx_rtmp_play
static ngx_int_t ngx_rtmp_relay_play_local(ngx_rtmp_session_t *s)
{
......
return ngx_rtmp_play(s, &v);//这里的指针指向:ngx_rtmp_relay_play
}
static ngx_int_tngx_rtmp_relay_play(ngx_rtmp_session_t *s, ngx_rtmp_play_t *v)
{
ngx_rtmp_relay_ctx_t *ctx;
ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_relay_module);
if (ctx && s->relay) {
goto next;//条件满足,其实意思就是,这个play不是去pull别人,是pull自己的流给上游,直接到next_play中去
}
next:
return next_play(s, v);//这里的next_play = ngx_rtmp_live_play
}
static ngx_int_t ngx_rtmp_live_play(ngx_rtmp_session_t *s, ngx_rtmp_play_t *v){
........
/* join stream as subscriber */
ngx_rtmp_live_join(s, v->name, 0);//把上游rtmp服务器的session加入到这个流的订阅者中去
........
}
------------------------------------------------------------------------------------------------
关键数据结构:
typedef struct {
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;//application下push和pull的配置信息
pulls, pushes: 成员就是ngx_rtmp_relay_target_t,主要保存url等信息
typedef struct {
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 counter; /* mutable connection counter */
} ngx_rtmp_relay_target_t;//目的url(push或pull)的相关信息
typedef structngx_rtmp_relay_ctx_s ngx_rtmp_relay_ctx_t;
struct ngx_rtmp_relay_ctx_s {//这个module的ctx信息,包含session
ngx_str_t name;
ngx_str_t url;
ngx_log_t log;
ngx_rtmp_session_t *session;
ngx_rtmp_relay_ctx_t *publish;
ngx_rtmp_relay_ctx_t *play;
ngx_rtmp_relay_ctx_t *next;
ngx_str_t app;
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;
ngx_event_t push_evt;
ngx_event_t *static_evt;
void *tag;
void *data;
};
typedef struct {//ngx_rtmp_session_t, 顾名思义,就是连接上游的session信息
uint32_t signature; /* "RTMP" */ /* <-- FIXME wtf */
ngx_event_t close;
void **ctx;
void **main_conf;
void **srv_conf;
void **app_conf;
ngx_str_t *addr_text;
int connected;
#if (nginx_version >= 1007005)
ngx_queue_t posted_dry_events;
#else
ngx_event_t *posted_dry_events;
#endif
/* client buffer time in msec */
uint32_t buflen;
uint32_t ack_size;
/* connection parameters */
ngx_str_t app;
ngx_str_t args;
ngx_str_t flashver;
ngx_str_t swf_url;
ngx_str_t tc_url;
uint32_t acodecs;
uint32_t vcodecs;
ngx_str_t page_url;
/* handshake data */
ngx_buf_t *hs_buf;
u_char *hs_digest;
unsigned hs_old:1;
ngx_uint_t hs_stage;
/* connection timestamps */
ngx_msec_t epoch;
ngx_msec_t peer_epoch;
ngx_msec_t base_time;
uint32_t current_time;
/* ping */
ngx_event_t ping_evt;
unsigned ping_active:1;
unsigned ping_reset:1;
/* auto-pushed? */
unsigned auto_pushed:1;
unsigned relay:1;
unsigned static_relay:1;
/* input stream 0 (reserved by RTMP spec)
* is used as free chain link */
ngx_rtmp_stream_t *in_streams;
uint32_t in_csid;
ngx_uint_t in_chunk_size;
ngx_pool_t *in_pool;
uint32_t in_bytes;
uint32_t in_last_ack;
ngx_pool_t *in_old_pool;
ngx_int_t in_chunk_size_changing;
ngx_connection_t *connection;
/* circular buffer of RTMP message pointers */
ngx_msec_t timeout;
uint32_t out_bytes;
size_t out_pos, out_last;
ngx_chain_t *out_chain;
u_char *out_bpos;
unsigned out_buffer:1;
size_t out_queue;
size_t out_cork;
ngx_chain_t *out[0];
} ngx_rtmp_session_t;
0 0
- 学习nginx-rtmp:replay push代码流程
- nginx-rtmp-module代码学习 - relay
- Git push 代码流程
- nginx 搭建rtmp流媒体服务器流程笔记
- nginx 搭建rtmp流媒体服务器流程笔记
- Nginx-rtmp模块实现流媒体play、push、pull功能
- 用nginx-rtmp-module直播写代码
- nginx-rtmp
- nginx rtmp
- nginx+rtmp
- nginx rtmp代码架构1 hook点总结
- nginx rtmp代码架构1 hook点总结
- nginx读取文件代码流程
- simple rtmp server代码学习 (1)
- srs代码学习(8)--rtmp发送
- RTMP Protocol Intro - Nginx + RTMP
- Nginx学习笔记(十三):Nginx启动流程
- Nginx学习(12)—Nginx启动流程
- JS爬虫,Java爬虫
- Spring @Value注解失败
- java实现输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
- 单例模式的常见应用场景
- MySQL数据库(23)
- 学习nginx-rtmp:replay push代码流程
- tensorflow之训练数据制作
- 【小程序码
- UVa 437 巴比伦塔(The Tower of Babylon)详细题解
- 3.excel 生成 sql
- 第二章 Spring MVC入门 —— 跟开涛学SpringMVC
- python-为被装饰的函数保存元数据-26
- 基于sping-data-mongodb的基础框架搭建
- 如何解决Android7.0及以上的权限崩溃问题