From 050a4e7586552003baff9dd920d28d51eaf8ab22 Mon Sep 17 00:00:00 2001 From: Roman Arutyunyan Date: Sat, 6 Apr 2013 17:51:42 +0400 Subject: [PATCH] implemented idle stream checker --- ngx_rtmp_live_module.c | 36 ++++++++++++++++++++++++++++-------- ngx_rtmp_live_module.h | 1 + 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/ngx_rtmp_live_module.c b/ngx_rtmp_live_module.c index 968672e..7e5d62e 100644 --- a/ngx_rtmp_live_module.c +++ b/ngx_rtmp_live_module.c @@ -98,6 +98,13 @@ static ngx_command_t ngx_rtmp_live_commands[] = { offsetof(ngx_rtmp_live_app_conf_t, play_restart), NULL }, + { ngx_string("idle_streams"), + NGX_RTMP_MAIN_CONF|NGX_RTMP_SRV_CONF|NGX_RTMP_APP_CONF|NGX_CONF_TAKE1, + ngx_conf_set_flag_slot, + NGX_RTMP_APP_CONF_OFFSET, + offsetof(ngx_rtmp_live_app_conf_t, idle_streams), + NULL }, + { ngx_string("drop_idle_publisher"), NGX_RTMP_MAIN_CONF|NGX_RTMP_SRV_CONF|NGX_RTMP_APP_CONF|NGX_CONF_TAKE1, ngx_rtmp_live_set_msec_slot, @@ -158,6 +165,7 @@ ngx_rtmp_live_create_app_conf(ngx_conf_t *cf) lacf->wait_video = NGX_CONF_UNSET; lacf->publish_notify = NGX_CONF_UNSET; lacf->play_restart = NGX_CONF_UNSET; + lacf->idle_streams = NGX_CONF_UNSET; return lacf; } @@ -180,6 +188,7 @@ ngx_rtmp_live_merge_app_conf(ngx_conf_t *cf, void *parent, void *child) ngx_conf_merge_value(conf->wait_video, prev->wait_video, 0); ngx_conf_merge_value(conf->publish_notify, prev->publish_notify, 0); ngx_conf_merge_value(conf->play_restart, prev->play_restart, 0); + ngx_conf_merge_value(conf->idle_streams, prev->idle_streams, 1); conf->pool = ngx_create_pool(4096, &cf->cycle->new_log); if (conf->pool == NULL) { @@ -511,7 +520,7 @@ ngx_rtmp_live_join(ngx_rtmp_session_t *s, u_char *name, unsigned publisher) ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0, "live: join '%s'", name); - stream = ngx_rtmp_live_get_stream(s, name, 1); + stream = ngx_rtmp_live_get_stream(s, name, publisher || lacf->idle_streams); if (stream == NULL) { return; } @@ -520,10 +529,6 @@ ngx_rtmp_live_join(ngx_rtmp_session_t *s, u_char *name, unsigned publisher) if ((*stream)->publishing) { ngx_log_error(NGX_LOG_ERR, s->connection->log, 0, "live: already publishing"); - - ngx_rtmp_send_status(s, "NetStream.Publish.BadName", "error", - "Already publishing"); - return; } @@ -552,7 +557,7 @@ ngx_rtmp_live_join(ngx_rtmp_session_t *s, u_char *name, unsigned publisher) static ngx_int_t ngx_rtmp_live_close_stream(ngx_rtmp_session_t *s, ngx_rtmp_close_stream_t *v) { - ngx_rtmp_live_ctx_t *ctx, **cctx; + ngx_rtmp_live_ctx_t *ctx, *lctx, **cctx; ngx_rtmp_live_stream_t **stream; ngx_rtmp_live_app_conf_t *lacf; @@ -586,6 +591,17 @@ ngx_rtmp_live_close_stream(ngx_rtmp_session_t *s, ngx_rtmp_close_stream_t *v) } } + if (!lacf->idle_streams && ctx->publishing) { + + for (lctx = ctx->stream->ctx; lctx; lctx = lctx->next) { + if (lctx == ctx) { + continue; + } + + ngx_rtmp_finalize_session(lctx->session); + } + } + if (ctx->publishing || ctx->stream->active) { ngx_rtmp_live_stop(s); } @@ -1018,7 +1034,9 @@ ngx_rtmp_live_publish(ngx_rtmp_session_t *s, ngx_rtmp_publish_t *v) ngx_rtmp_live_join(s, v->name, 1); ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_live_module); - if (ctx == NULL || !ctx->publishing) { + if (ctx == NULL || ctx->stream == NULL || !ctx->publishing) { + ngx_rtmp_send_status(s, "NetStream.Publish.BadName", "error", + "Cannot publish stream"); goto next; } @@ -1056,7 +1074,9 @@ ngx_rtmp_live_play(ngx_rtmp_session_t *s, ngx_rtmp_play_t *v) ngx_rtmp_live_join(s, v->name, 0); ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_live_module); - if (ctx == NULL) { + if (ctx == NULL || ctx->stream == NULL) { + ngx_rtmp_send_status(s, "NetStream.Play.StreamNotFound", "error", + "Live stream not found"); goto next; } diff --git a/ngx_rtmp_live_module.h b/ngx_rtmp_live_module.h index ec60716..12432a9 100644 --- a/ngx_rtmp_live_module.h +++ b/ngx_rtmp_live_module.h @@ -65,6 +65,7 @@ typedef struct { ngx_flag_t wait_video; ngx_flag_t publish_notify; ngx_flag_t play_restart; + ngx_flag_t idle_streams; ngx_msec_t buflen; ngx_pool_t *pool; ngx_rtmp_live_stream_t *free_streams;