From f221540a784507d3c27aeee4a48d1761284c2f61 Mon Sep 17 00:00:00 2001 From: Roman Arutyunyan Date: Thu, 6 Sep 2012 16:10:21 +0400 Subject: [PATCH] implemented on_publish_done, on_play_done; fixed repeated on_done --- ngx_rtmp_notify_module.c | 140 ++++++++++++++++++++++++++++++++------- 1 file changed, 116 insertions(+), 24 deletions(-) diff --git a/ngx_rtmp_notify_module.c b/ngx_rtmp_notify_module.c index 7f5fc75..eeb0f9f 100644 --- a/ngx_rtmp_notify_module.c +++ b/ngx_rtmp_notify_module.c @@ -17,21 +17,29 @@ static ngx_rtmp_delete_stream_pt next_delete_stream; static char *ngx_rtmp_notify_on_event(ngx_conf_t *cf, ngx_command_t *cmd, - void *conf); + void *conf); static ngx_int_t ngx_rtmp_notify_postconfiguration(ngx_conf_t *cf); static void * ngx_rtmp_notify_create_app_conf(ngx_conf_t *cf); static char * ngx_rtmp_notify_merge_app_conf(ngx_conf_t *cf, - void *parent, void *child); + void *parent, void *child); +static ngx_int_t ngx_rtmp_notify_done(ngx_rtmp_session_t *s, char *cbname, + ngx_url_t *url); +#define NGX_RTMP_NOTIFY_PUBLISHING 0x01 +#define NGX_RTMP_NOTIFY_PLAYING 0x02 + typedef struct { ngx_url_t *publish_url; ngx_url_t *play_url; + ngx_url_t *publish_done_url; + ngx_url_t *play_done_url; ngx_url_t *done_url; } ngx_rtmp_notify_app_conf_t; typedef struct { + ngx_uint_t flags; u_char name[NGX_RTMP_MAX_NAME]; u_char args[NGX_RTMP_MAX_ARGS]; } ngx_rtmp_notify_ctx_t; @@ -53,6 +61,20 @@ static ngx_command_t ngx_rtmp_notify_commands[] = { 0, NULL }, + { ngx_string("on_publish_done"), + NGX_RTMP_MAIN_CONF|NGX_RTMP_SRV_CONF|NGX_RTMP_APP_CONF|NGX_CONF_TAKE1, + ngx_rtmp_notify_on_event, + NGX_RTMP_APP_CONF_OFFSET, + 0, + NULL }, + + { ngx_string("on_play_done"), + NGX_RTMP_MAIN_CONF|NGX_RTMP_SRV_CONF|NGX_RTMP_APP_CONF|NGX_CONF_TAKE1, + ngx_rtmp_notify_on_event, + NGX_RTMP_APP_CONF_OFFSET, + 0, + NULL }, + { ngx_string("on_done"), NGX_RTMP_MAIN_CONF|NGX_RTMP_SRV_CONF|NGX_RTMP_APP_CONF|NGX_CONF_TAKE1, ngx_rtmp_notify_on_event, @@ -283,10 +305,12 @@ static ngx_chain_t * ngx_rtmp_notify_done_create(ngx_rtmp_session_t *s, void *arg, ngx_pool_t *pool) { + u_char *cbname = arg; + ngx_rtmp_notify_app_conf_t *nacf; ngx_chain_t *hl, *cl, *pl; ngx_buf_t *b; - size_t name_len, args_len; + size_t cbname_len, name_len, args_len; ngx_str_t *addr_text; ngx_rtmp_notify_ctx_t *ctx; @@ -306,12 +330,13 @@ ngx_rtmp_notify_done_create(ngx_rtmp_session_t *s, void *arg, return NULL; } + cbname_len = ngx_strlen(cbname); name_len = ctx ? ngx_strlen(ctx->name) : 0; args_len = ctx ? ngx_strlen(ctx->args) : 0; addr_text = &s->connection->addr_text; b = ngx_create_temp_buf(pool, - sizeof("&call=done") + + sizeof("&call=") + cbname_len + sizeof("&addr=") + addr_text->len + sizeof("&name=") + name_len * 3 + 1 + args_len); @@ -417,22 +442,37 @@ ngx_rtmp_notify_play_handle(ngx_rtmp_session_t *s, static void -ngx_rtmp_notify_save_name_args(ngx_rtmp_session_t *s, - u_char name[NGX_RTMP_MAX_NAME], u_char args[NGX_RTMP_MAX_ARGS]) +ngx_rtmp_notify_init(ngx_rtmp_session_t *s, + u_char name[NGX_RTMP_MAX_NAME], u_char args[NGX_RTMP_MAX_ARGS], + ngx_uint_t flags) { ngx_rtmp_notify_ctx_t *ctx; + ngx_rtmp_notify_app_conf_t *nacf; + + nacf = ngx_rtmp_get_module_app_conf(s, ngx_rtmp_notify_module); + + if (nacf->done_url == NULL && + nacf->play_done_url == NULL && + nacf->publish_done_url == NULL) + { + return; + } ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_notify_module); + if (ctx == NULL) { ctx = ngx_pcalloc(s->connection->pool, sizeof(ngx_rtmp_notify_ctx_t)); if (ctx == NULL) { return; } + ngx_rtmp_set_ctx(s, ctx, ngx_rtmp_notify_module); } ngx_memcpy(ctx->name, name, NGX_RTMP_MAX_NAME); ngx_memcpy(ctx->args, args, NGX_RTMP_MAX_ARGS); + + ctx->flags |= flags; } @@ -447,19 +487,22 @@ ngx_rtmp_notify_publish(ngx_rtmp_session_t *s, ngx_rtmp_publish_t *v) } nacf = ngx_rtmp_get_module_app_conf(s, ngx_rtmp_notify_module); + if (nacf == NULL) { goto next; } - if (nacf->done_url) { - ngx_rtmp_notify_save_name_args(s, v->name, v->args); - } + ngx_rtmp_notify_init(s, v->name, v->args, NGX_RTMP_NOTIFY_PUBLISHING); if (nacf->publish_url == NULL) { goto next; } + ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0, + "notify: publish '%V'", &nacf->publish_url->url); + ngx_memzero(&ci, sizeof(ci)); + ci.url = nacf->publish_url; ci.create = ngx_rtmp_notify_publish_create; ci.handle = ngx_rtmp_notify_publish_handle; @@ -480,19 +523,22 @@ ngx_rtmp_notify_play(ngx_rtmp_session_t *s, ngx_rtmp_play_t *v) ngx_rtmp_netcall_init_t ci; nacf = ngx_rtmp_get_module_app_conf(s, ngx_rtmp_notify_module); + if (nacf == NULL) { goto next; } - if (nacf->done_url) { - ngx_rtmp_notify_save_name_args(s, v->name, v->args); - } + ngx_rtmp_notify_init(s, v->name, v->args, NGX_RTMP_NOTIFY_PLAYING); if (nacf->play_url == NULL) { goto next; } + ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0, + "notify: play '%V'", &nacf->play_url->url); + ngx_memzero(&ci, sizeof(ci)); + ci.url = nacf->play_url; ci.create = ngx_rtmp_notify_play_create; ci.handle = ngx_rtmp_notify_play_handle; @@ -510,32 +556,65 @@ static ngx_int_t ngx_rtmp_notify_delete_stream(ngx_rtmp_session_t *s, ngx_rtmp_delete_stream_t *v) { + ngx_rtmp_notify_ctx_t *ctx; ngx_rtmp_notify_app_conf_t *nacf; - ngx_rtmp_netcall_init_t ci; - nacf = ngx_rtmp_get_module_app_conf(s, ngx_rtmp_notify_module); - if (nacf == NULL || nacf->done_url == NULL) { + ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_notify_module); + + if (ctx == NULL) { goto next; } - ngx_memzero(&ci, sizeof(ci)); - ci.url = nacf->done_url; - ci.create = ngx_rtmp_notify_done_create; + nacf = ngx_rtmp_get_module_app_conf(s, ngx_rtmp_notify_module); - ngx_rtmp_netcall_create(s, &ci); + if (nacf == NULL) { + goto next; + } + + if (nacf->publish_done_url && (ctx->flags & NGX_RTMP_NOTIFY_PUBLISHING)) { + ngx_rtmp_notify_done(s, "publish_done", nacf->publish_done_url); + } + + if (nacf->play_done_url && (ctx->flags & NGX_RTMP_NOTIFY_PLAYING)) { + ngx_rtmp_notify_done(s, "play_done", nacf->play_done_url); + } + + if (nacf->done_url && ctx->flags) { + ngx_rtmp_notify_done(s, "done", nacf->done_url); + } + + ctx->flags = 0; next: return next_delete_stream(s, v); } +static ngx_int_t +ngx_rtmp_notify_done(ngx_rtmp_session_t *s, char *cbname, ngx_url_t *url) +{ + ngx_rtmp_netcall_init_t ci; + + ngx_log_debug2(NGX_LOG_DEBUG_RTMP, s->connection->log, 0, + "notify: %s '%V'", cbname, &url->url); + + ngx_memzero(&ci, sizeof(ci)); + + ci.url = url; + ci.arg = cbname; + ci.create = ngx_rtmp_notify_done_create; + + return ngx_rtmp_netcall_create(s, &ci); +} + + static char * ngx_rtmp_notify_on_event(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_rtmp_notify_app_conf_t *nacf; ngx_str_t *url, *name; ngx_url_t *u; - size_t add; + size_t add, len; ngx_str_t *value; value = cf->args->elts; @@ -568,13 +647,26 @@ ngx_rtmp_notify_on_event(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) nacf = ngx_rtmp_conf_get_module_app_conf(cf, ngx_rtmp_notify_module); + len = name->len; + switch (name->data[4]) { - case 'l': /* on_pLay */ - nacf->play_url = u; + + case 'l': /* on_pLay... */ + if (len == sizeof("on_play") - 1) { + nacf->play_url = u; + } else { + nacf->play_done_url = u; + } break; - case 'u': /* on_pUblish */ - nacf->publish_url = u; + + case 'u': /* on_pUblish... */ + if (len == sizeof("on_publish") - 1) { + nacf->publish_url = u; + } else { + nacf->publish_done_url = u; + } break; + case 'o': /* on_dOne */ nacf->done_url = u; }