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; ngx_str_t *value; value = cf->args->elts; name = &value[0]; url = &value[1]; add = 0; u = ngx_pcalloc(cf->pool, sizeof(ngx_url_t)); if (u == NULL) { return NGX_CONF_ERROR; } if (ngx_strncasecmp(url->data, (u_char *) "http://", 7) == 0) { add = 7; } u->url.len = url->len - add; u->url.data = url->data + add; u->default_port = 80; u->uri_part = 1; if (ngx_parse_url(cf->pool, u) != NGX_OK) { if (u->err) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s in url \"%V\"", u->err, &u->url); } return NGX_CONF_ERROR; } nacf = ngx_rtmp_conf_get_module_app_conf(cf, ngx_rtmp_notify_module); if (name->len == sizeof("on_play") - 1) { nacf->play_url = u; } else { /* on_publish */ nacf->publish_url = u; } return NGX_CONF_OK; }
static char * ngx_rtmp_notify_on_record_done(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_rtmp_record_app_conf_t *racf; ngx_str_t *url; ngx_url_t *u; size_t add; ngx_str_t *value; value = cf->args->elts; url = &value[1]; add = 0; u = ngx_pcalloc(cf->pool, sizeof(ngx_url_t)); if (u == NULL) { return NGX_CONF_ERROR; } if (ngx_strncasecmp(url->data, (u_char *) "http://", 7) == 0) { add = 7; } u->url.len = url->len - add; u->url.data = url->data + add; u->default_port = 80; u->uri_part = 1; if (ngx_parse_url(cf->pool, u) != NGX_OK) { if (u->err) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s in url \"%V\"", u->err, &u->url); } return NGX_CONF_ERROR; } racf = ngx_rtmp_conf_get_module_app_conf(cf, ngx_rtmp_record_module); racf->url = u; return NGX_CONF_OK; }
static char * ngx_rtmp_exec_exec(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_str_t *value; ngx_rtmp_exec_app_conf_t *eacf; size_t n, nargs; ngx_str_t *s; ngx_rtmp_exec_conf_t *ec; eacf = ngx_rtmp_conf_get_module_app_conf(cf, ngx_rtmp_exec_module); value = cf->args->elts; ec = ngx_array_push(&eacf->confs); if (ec == NULL) { return NGX_CONF_ERROR; } ec->cmd = value[1]; if (cf->args->nelts == 2) { return NGX_CONF_OK; } nargs = cf->args->nelts - 2; if (ngx_array_init(&ec->args, cf->pool, nargs, sizeof(ngx_str_t)) != NGX_OK) { return NGX_CONF_ERROR; } s = ngx_array_push_n(&ec->args, nargs); for (n = 2; n < cf->args->nelts; ++n, ++s) { *s = value[n]; } return NGX_CONF_OK; }
static char * ngx_rtmp_record_recorder(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { char *rv; ngx_int_t i; ngx_str_t *value; ngx_conf_t save; ngx_rtmp_module_t *module; ngx_rtmp_core_app_conf_t *cacf, **pcacf, *rcacf; ngx_rtmp_record_app_conf_t *racf, **pracf, *rracf; ngx_rtmp_conf_ctx_t *ctx, *pctx; value = cf->args->elts; cacf = ngx_rtmp_conf_get_module_app_conf(cf, ngx_rtmp_core_module); racf = ngx_rtmp_conf_get_module_app_conf(cf, ngx_rtmp_record_module); ctx = ngx_pcalloc(cf->pool, sizeof(ngx_rtmp_conf_ctx_t)); if (ctx == NULL) { return NGX_CONF_ERROR; } pctx = cf->ctx; ctx->main_conf = pctx->main_conf; ctx->srv_conf = pctx->srv_conf; ctx->app_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_rtmp_max_module); if (ctx->app_conf == NULL) { return NGX_CONF_ERROR; } for (i = 0; ngx_modules[i]; i++) { if (ngx_modules[i]->type != NGX_RTMP_MODULE) { continue; } module = ngx_modules[i]->ctx; if (module->create_app_conf) { ctx->app_conf[ngx_modules[i]->ctx_index] = module->create_app_conf(cf); if (ctx->app_conf[ngx_modules[i]->ctx_index] == NULL) { return NGX_CONF_ERROR; } } } /* add to sub-applications */ rcacf = ctx->app_conf[ngx_rtmp_core_module.ctx_index]; rcacf->app_conf = ctx->app_conf; pcacf = ngx_array_push(&cacf->applications); if (pcacf == NULL) { return NGX_CONF_ERROR; } *pcacf = rcacf; /* add to recorders */ rracf = ctx->app_conf[ngx_rtmp_record_module.ctx_index]; rracf->rec_conf = ctx->app_conf; pracf = ngx_array_push(&racf->rec); if (pracf == NULL) { return NGX_CONF_ERROR; } *pracf = rracf; rracf->id = value[1]; save = *cf; cf->ctx = ctx; cf->cmd_type = NGX_RTMP_REC_CONF; rv = ngx_conf_parse(cf, NULL); *cf= save; return rv; }
static char * ngx_rtmp_relay_push_pull(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_str_t *value, v, n; ngx_rtmp_relay_app_conf_t *racf; ngx_rtmp_relay_target_t *target, **t; ngx_url_t *u; ngx_uint_t i; u_char *p; value = cf->args->elts; racf = ngx_rtmp_conf_get_module_app_conf(cf, ngx_rtmp_relay_module); t = ngx_array_push(value[0].data[3] == 'h' ? &racf->pushes /* push */ : &racf->pulls /* pull */ ); if (t == NULL) { return NGX_CONF_ERROR; } target = ngx_pcalloc(cf->pool, sizeof(*target)); if (target == NULL) { return NGX_CONF_ERROR; } *t = target; target->tag = &ngx_rtmp_relay_module; target->data = target; u = &target->url; u->default_port = 1935; u->uri_part = 1; u->url = value[1]; if (ngx_strncasecmp(u->url.data, (u_char *) "rtmp://", 7) == 0) { u->url.data += 7; u->url.len -= 7; } if (ngx_parse_url(cf->pool, u) != NGX_OK) { if (u->err) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s in url \"%V\"", u->err, &u->url); } return NGX_CONF_ERROR; } value += 2; for (i = 2; i < cf->args->nelts; ++i, ++value) { p = ngx_strlchr(value->data, value->data + value->len, '='); if (p == NULL) { return "key=value expected"; } if (p == value->data + value->len - 1) { continue; } n.data = value->data; n.len = p - value->data; v.data = p + 1; v.len = value->data + value->len - p - 1; #define NGX_RTMP_RELAY_STR_PAR(name, var) \ if (n.len == sizeof(#name) - 1 \ && ngx_strncasecmp(n.data, (u_char *)#name, n.len) == 0) \ { \ target->var = v; \ continue; \ } #define NGX_RTMP_RELAY_NUM_PAR(name, var) \ if (n.len == sizeof(#name) - 1 \ && ngx_strncasecmp(n.data, (u_char *)#name, n.len) == 0) \ { \ target->var = ngx_atoi(v.data, v.len); \ continue; \ } NGX_RTMP_RELAY_STR_PAR(app, app); NGX_RTMP_RELAY_STR_PAR(name, name); NGX_RTMP_RELAY_STR_PAR(tcUrl, tc_url); NGX_RTMP_RELAY_STR_PAR(pageUrl, page_url); NGX_RTMP_RELAY_STR_PAR(swfUrl, swf_url); NGX_RTMP_RELAY_STR_PAR(flashVer, flash_ver); NGX_RTMP_RELAY_STR_PAR(playPath, play_path); NGX_RTMP_RELAY_NUM_PAR(live, live); NGX_RTMP_RELAY_NUM_PAR(start, start); NGX_RTMP_RELAY_NUM_PAR(stop, stop); #undef NGX_RTMP_RELAY_STR_PAR #undef NGX_RTMP_RELAY_NUM_PAR return "unsuppored parameter"; } return NGX_CONF_OK; }
static char * ngx_rtmp_relay_push_pull(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_str_t *value, v, n; ngx_rtmp_relay_app_conf_t *racf; ngx_rtmp_relay_target_t *target, **t; void *addrs; ngx_url_t *u; ngx_uint_t i; ngx_int_t is_pull, is_static; ngx_event_t **ee, *e; ngx_rtmp_relay_static_t *rs; u_char *p; value = cf->args->elts; racf = ngx_rtmp_conf_get_module_app_conf(cf, ngx_rtmp_relay_module); is_pull = (value[0].data[3] == 'l'); is_static = 0; target = ngx_pcalloc(cf->pool, sizeof(*target)); if (target == NULL) { return NGX_CONF_ERROR; } target->tag = &ngx_rtmp_relay_module; target->data = target; u = &target->url; u->default_port = 1935; u->uri_part = 1; u->url = value[1]; if (ngx_strncasecmp(u->url.data, (u_char *) "rtmp://", 7) == 0) { u->url.data += 7; u->url.len -= 7; } if (ngx_parse_url(cf->pool, u) != NGX_OK) { if (u->err) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s in url \"%V\"", u->err, &u->url); } return NGX_CONF_ERROR; } value += 2; for (i = 2; i < cf->args->nelts; ++i, ++value) { p = ngx_strlchr(value->data, value->data + value->len, '='); if (p == NULL) { n = *value; ngx_str_set(&v, "1"); } else { n.data = value->data; n.len = p - value->data; v.data = p + 1; v.len = value->data + value->len - p - 1; } #define NGX_RTMP_RELAY_STR_PAR(name, var) \ if (n.len == sizeof(name) - 1 \ && ngx_strncasecmp(n.data, (u_char *) name, n.len) == 0) \ { \ target->var = v; \ continue; \ } #define NGX_RTMP_RELAY_NUM_PAR(name, var) \ if (n.len == sizeof(name) - 1 \ && ngx_strncasecmp(n.data, (u_char *) name, n.len) == 0) \ { \ target->var = ngx_atoi(v.data, v.len); \ continue; \ } NGX_RTMP_RELAY_STR_PAR("app", app); NGX_RTMP_RELAY_STR_PAR("name", name); NGX_RTMP_RELAY_STR_PAR("tcUrl", tc_url); NGX_RTMP_RELAY_STR_PAR("pageUrl", page_url); NGX_RTMP_RELAY_STR_PAR("swfUrl", swf_url); NGX_RTMP_RELAY_STR_PAR("flashVer", flash_ver); NGX_RTMP_RELAY_STR_PAR("playPath", play_path); NGX_RTMP_RELAY_NUM_PAR("live", live); NGX_RTMP_RELAY_NUM_PAR("start", start); NGX_RTMP_RELAY_NUM_PAR("stop", stop); #undef NGX_RTMP_RELAY_STR_PAR #undef NGX_RTMP_RELAY_NUM_PAR if (n.len == sizeof("static") - 1 && ngx_strncasecmp(n.data, (u_char *) "static", n.len) == 0 && ngx_atoi(v.data, v.len)) { is_static = 1; continue; } return "unsuppored parameter"; } if (is_static) { if (!is_pull) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "static push is not allowed"); return NGX_CONF_ERROR; } if (target->name.len == 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "stream name missing in static pull " "declaration"); return NGX_CONF_ERROR; } t = racf->static_pulls.elts; for (i = 0; i < racf->static_pulls.nelts; i++) { if (t[i]->name.len == target->name.len && ngx_strncmp(t[i]->name.data, target->name.data, target->name.len) == 0) { addrs = ngx_palloc(cf->pool, (u->naddrs + t[i]->url.naddrs) * sizeof(ngx_addr_t)); if (addrs == NULL) { return NGX_CONF_ERROR; } ngx_memcpy(addrs, t[i]->url.addrs, t[i]->url.naddrs * sizeof(ngx_addr_t)); ngx_memcpy((char *)addrs + t[i]->url.naddrs * sizeof(ngx_addr_t), u->addrs, u->naddrs * sizeof(ngx_addr_t)); t[i]->url.naddrs += u->naddrs; t[i]->url.addrs = addrs; return NGX_CONF_OK; } } ee = ngx_array_push(&racf->static_events); if (ee == NULL) { return NGX_CONF_ERROR; } e = ngx_pcalloc(cf->pool, sizeof(ngx_event_t)); if (e == NULL) { return NGX_CONF_ERROR; } *ee = e; rs = ngx_pcalloc(cf->pool, sizeof(ngx_rtmp_relay_static_t)); if (rs == NULL) { return NGX_CONF_ERROR; } rs->target = target; e->data = rs; e->log = &cf->cycle->new_log; e->handler = ngx_rtmp_relay_static_pull_reconnect; t = ngx_array_push(&racf->static_pulls); } else if (is_pull) { t = ngx_array_push(&racf->pulls); } else { t = ngx_array_push(&racf->pushes); } if (t == NULL) { return NGX_CONF_ERROR; } *t = target; return NGX_CONF_OK; }
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; ngx_str_t *value; ngx_uint_t n; value = cf->args->elts; name = &value[0]; url = &value[1]; add = 0; u = ngx_pcalloc(cf->pool, sizeof(ngx_url_t)); if (u == NULL) { return NGX_CONF_ERROR; } if (ngx_strncasecmp(url->data, (u_char *) "http://", 7) == 0) { add = 7; } u->url.len = url->len - add; u->url.data = url->data + add; u->default_port = 80; u->uri_part = 1; if (ngx_parse_url(cf->pool, u) != NGX_OK) { if (u->err) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s in url \"%V\"", u->err, &u->url); } return NGX_CONF_ERROR; } nacf = ngx_rtmp_conf_get_module_app_conf(cf, ngx_rtmp_notify_module); n = 0; switch (name->len) { case sizeof("on_done") - 1: /* and on_play */ if (name->data[3] == 'd') { n = NGX_RTMP_NOTIFY_DONE; } else { n = NGX_RTMP_NOTIFY_PLAY; } break; case sizeof("on_publish") - 1: n = NGX_RTMP_NOTIFY_PUBLISH; break; case sizeof("on_play_done") - 1: n = NGX_RTMP_NOTIFY_PLAY_DONE; break; case sizeof("on_record_done") - 1: n = NGX_RTMP_NOTIFY_RECORD_DONE; break; case sizeof("on_publish_done") - 1: n = NGX_RTMP_NOTIFY_PUBLISH_DONE; break; } nacf->url[n] = u; return NGX_CONF_OK; }
static char * ngx_rtmp_record_recorder(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { char *rv, *rvm; ngx_int_t i; ngx_str_t *value; ngx_conf_t save; ngx_rtmp_module_t *module; ngx_rtmp_record_app_conf_t *racf, *rracf; ngx_rtmp_record_node_t **prc, *rc; ngx_rtmp_conf_ctx_t *ctx, *pctx; racf = ngx_rtmp_conf_get_module_app_conf(cf, ngx_rtmp_record_module); ctx = ngx_pcalloc(cf->pool, sizeof(ngx_rtmp_conf_ctx_t)); if (ctx == NULL) { return NGX_CONF_ERROR; } pctx = cf->ctx; ctx->main_conf = pctx->main_conf; ctx->srv_conf = pctx->srv_conf; ctx->app_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_rtmp_max_module); if (ctx->app_conf == NULL) { return NGX_CONF_ERROR; } for (i = 0; ngx_modules[i]; i++) { if (ngx_modules[i]->type != NGX_RTMP_MODULE) { continue; } module = ngx_modules[i]->ctx; if (module->create_app_conf) { ctx->app_conf[ngx_modules[i]->ctx_index] = module->create_app_conf(cf); if (ctx->app_conf[ngx_modules[i]->ctx_index] == NULL) { return NGX_CONF_ERROR; } } } prc = ngx_array_push(&racf->nodes); if (prc == NULL) { return NGX_CONF_ERROR; } rracf = ctx->app_conf[ngx_rtmp_record_module.ctx_index]; rc = &rracf->def; value = cf->args->elts; rc->id = value[1]; *prc = rc; save = *cf; cf->ctx = ctx; cf->cmd_type = NGX_RTMP_REC_CONF; rv = ngx_conf_parse(cf, NULL); rvm = ngx_rtmp_record_merge_app_conf(cf, racf, rracf); if (rvm != NGX_CONF_OK) { return rvm; } *cf= save; return rv; }