@@ -94,6 +94,13 @@ static ngx_command_t ngx_rtmp_live_commands[] = {
94
94
offsetof(ngx_rtmp_live_app_conf_t , play_restart ),
95
95
NULL },
96
96
97
+ { ngx_string ("idle_streams" ),
98
+ NGX_RTMP_MAIN_CONF |NGX_RTMP_SRV_CONF |NGX_RTMP_APP_CONF |NGX_CONF_TAKE1 ,
99
+ ngx_conf_set_flag_slot ,
100
+ NGX_RTMP_APP_CONF_OFFSET ,
101
+ offsetof(ngx_rtmp_live_app_conf_t , idle_streams ),
102
+ NULL },
103
+
97
104
{ ngx_string ("drop_idle_publisher" ),
98
105
NGX_RTMP_MAIN_CONF |NGX_RTMP_SRV_CONF |NGX_RTMP_APP_CONF |NGX_CONF_TAKE1 ,
99
106
ngx_rtmp_live_set_msec_slot ,
@@ -153,6 +160,7 @@ ngx_rtmp_live_create_app_conf(ngx_conf_t *cf)
153
160
lacf -> wait_video = NGX_CONF_UNSET ;
154
161
lacf -> publish_notify = NGX_CONF_UNSET ;
155
162
lacf -> play_restart = NGX_CONF_UNSET ;
163
+ lacf -> idle_streams = NGX_CONF_UNSET ;
156
164
157
165
return lacf ;
158
166
}
@@ -174,6 +182,7 @@ ngx_rtmp_live_merge_app_conf(ngx_conf_t *cf, void *parent, void *child)
174
182
ngx_conf_merge_value (conf -> wait_video , prev -> wait_video , 0 );
175
183
ngx_conf_merge_value (conf -> publish_notify , prev -> publish_notify , 0 );
176
184
ngx_conf_merge_value (conf -> play_restart , prev -> play_restart , 0 );
185
+ ngx_conf_merge_value (conf -> idle_streams , prev -> idle_streams , 1 );
177
186
178
187
conf -> pool = ngx_create_pool (4096 , & cf -> cycle -> new_log );
179
188
if (conf -> pool == NULL ) {
@@ -505,8 +514,19 @@ ngx_rtmp_live_join(ngx_rtmp_session_t *s, u_char *name, unsigned publisher)
505
514
ngx_log_debug1 (NGX_LOG_DEBUG_RTMP , s -> connection -> log , 0 ,
506
515
"live: join '%s'" , name );
507
516
508
- stream = ngx_rtmp_live_get_stream (s , name , 1 );
509
- if (stream == NULL ) {
517
+ stream = ngx_rtmp_live_get_stream (s , name , publisher || lacf -> idle_streams );
518
+
519
+ if (stream == NULL ||
520
+ !(publisher || (* stream )-> publishing || lacf -> idle_streams ))
521
+ {
522
+ ngx_log_error (NGX_LOG_ERR , s -> connection -> log , 0 ,
523
+ "live: stream not found" );
524
+
525
+ ngx_rtmp_send_status (s , "NetStream.Play.StreamNotFound" , "error" ,
526
+ "No such stream" );
527
+
528
+ ngx_rtmp_finalize_session (s );
529
+
510
530
return ;
511
531
}
512
532
@@ -546,7 +566,8 @@ ngx_rtmp_live_join(ngx_rtmp_session_t *s, u_char *name, unsigned publisher)
546
566
static ngx_int_t
547
567
ngx_rtmp_live_close_stream (ngx_rtmp_session_t * s , ngx_rtmp_close_stream_t * v )
548
568
{
549
- ngx_rtmp_live_ctx_t * ctx , * * cctx ;
569
+ ngx_rtmp_session_t * ss ;
570
+ ngx_rtmp_live_ctx_t * ctx , * * cctx , * pctx ;
550
571
ngx_rtmp_live_stream_t * * stream ;
551
572
ngx_rtmp_live_app_conf_t * lacf ;
552
573
@@ -589,6 +610,17 @@ ngx_rtmp_live_close_stream(ngx_rtmp_session_t *s, ngx_rtmp_close_stream_t *v)
589
610
"status" , "Stop publishing" );
590
611
}
591
612
613
+ if (!lacf -> idle_streams ) {
614
+ for (pctx = ctx -> stream -> ctx ; pctx ; pctx = pctx -> next ) {
615
+ if (pctx -> publishing == 0 ) {
616
+ ss = pctx -> session ;
617
+ ngx_log_debug0 (NGX_LOG_DEBUG_RTMP , ss -> connection -> log , 0 ,
618
+ "live: no publisher" );
619
+ ngx_rtmp_finalize_session (ss );
620
+ }
621
+ }
622
+ }
623
+
592
624
if (ctx -> stream -> ctx ) {
593
625
ctx -> stream = NULL ;
594
626
goto next ;
0 commit comments