@@ -56,6 +56,8 @@ typedef struct {
5656 bool has_streaming_enabled ; // Whether streaming_enabled flag was provided
5757 bool non_dynamic_config_changed ; // Whether non-dynamic fields changed
5858 bool credentials_changed ; // Whether ONVIF credentials changed
59+ bool go2rtc_override_changed ; // Whether go2rtc_source_override changed
60+ bool sub_stream_changed ; // Whether sub_stream_url changed
5961} put_stream_task_t ;
6062
6163static void format_stream_capacity_error (char * buf , size_t buf_size ,
@@ -359,6 +361,34 @@ static void put_stream_worker(put_stream_task_t *task) {
359361 usleep (500000 ); // 500ms
360362 }
361363
364+ // If go2rtc_source_override changed, regenerate config and fully re-register.
365+ // The override is baked into go2rtc.yaml so a config regen + re-registration is needed.
366+ if (task -> go2rtc_override_changed ) {
367+ log_info ("go2rtc source override changed for stream %s, re-registering with go2rtc" , task -> config .name );
368+ go2rtc_api_remove_stream (task -> config .name );
369+ go2rtc_integration_register_stream (task -> config .name );
370+ usleep (500000 );
371+ }
372+
373+ // If sub-stream URL changed, register or unregister the {name}_sub stream
374+ if (task -> sub_stream_changed ) {
375+ char sub_name [MAX_STREAM_NAME + 8 ];
376+ snprintf (sub_name , sizeof (sub_name ), "%s_sub" , task -> config .name );
377+ // Always remove old sub-stream first
378+ go2rtc_api_remove_stream (sub_name );
379+ // Re-register if new sub-stream URL is set
380+ if (task -> config .sub_stream_url [0 ] != '\0' ) {
381+ log_info ("Registering updated sub-stream %s with go2rtc" , sub_name );
382+ go2rtc_stream_register (sub_name , task -> config .sub_stream_url ,
383+ task -> config .onvif_username [0 ] != '\0' ? task -> config .onvif_username : NULL ,
384+ task -> config .onvif_password [0 ] != '\0' ? task -> config .onvif_password : NULL ,
385+ false, task -> config .protocol , false);
386+ } else {
387+ log_info ("Sub-stream %s removed from go2rtc" , sub_name );
388+ }
389+ usleep (500000 );
390+ }
391+
362392 // Start stream if enabled (AFTER go2rtc has been updated)
363393 if (task -> config .enabled ) {
364394 log_info ("Starting stream %s after configuration update" , task -> config .name );
@@ -898,6 +928,8 @@ void handle_put_stream(const http_request_t *req, http_response_t *res) {
898928 // Update configuration with provided values
899929 bool config_changed = false;
900930 bool requires_restart = false; // Flag for changes that require stream restart
931+ bool go2rtc_override_changed = false; // Track go2rtc source override changes
932+ bool sub_stream_changed = false; // Track sub-stream URL changes
901933 bool has_record = false; // Track if record flag was provided
902934 bool has_streaming_enabled = false; // Track if streaming_enabled flag was provided
903935 bool non_dynamic_config_changed = false; // Track if non-dynamic fields changed
@@ -1292,13 +1324,15 @@ void handle_put_stream(const http_request_t *req, http_response_t *res) {
12921324 sizeof (config .go2rtc_source_override ), 0 );
12931325 config_changed = true;
12941326 requires_restart = true;
1327+ go2rtc_override_changed = true;
12951328 log_info ("go2rtc source override changed for stream %s" , config .name );
12961329 }
12971330 } else if (go2rtc_source_override_put && cJSON_IsNull (go2rtc_source_override_put )) {
12981331 if (config .go2rtc_source_override [0 ] != '\0' ) {
12991332 config .go2rtc_source_override [0 ] = '\0' ;
13001333 config_changed = true;
13011334 requires_restart = true;
1335+ go2rtc_override_changed = true;
13021336 log_info ("go2rtc source override cleared for stream %s" , config .name );
13031337 }
13041338 }
@@ -1312,13 +1346,15 @@ void handle_put_stream(const http_request_t *req, http_response_t *res) {
13121346 sizeof (config .sub_stream_url ), 0 );
13131347 config_changed = true;
13141348 requires_restart = true;
1349+ sub_stream_changed = true;
13151350 log_info ("Sub-stream URL changed for stream %s" , config .name );
13161351 }
13171352 } else if (sub_stream_url_put && cJSON_IsNull (sub_stream_url_put )) {
13181353 if (config .sub_stream_url [0 ] != '\0' ) {
13191354 config .sub_stream_url [0 ] = '\0' ;
13201355 config_changed = true;
13211356 requires_restart = true;
1357+ sub_stream_changed = true;
13221358 log_info ("Sub-stream URL cleared for stream %s" , config .name );
13231359 }
13241360 }
@@ -1573,6 +1609,8 @@ void handle_put_stream(const http_request_t *req, http_response_t *res) {
15731609 task -> has_streaming_enabled = has_streaming_enabled ;
15741610 task -> non_dynamic_config_changed = non_dynamic_config_changed ;
15751611 task -> credentials_changed = credentials_changed ;
1612+ task -> go2rtc_override_changed = go2rtc_override_changed ;
1613+ task -> sub_stream_changed = sub_stream_changed ;
15761614
15771615 log_info ("Detection settings before update - Model: %s, Threshold: %.2f, Interval: %d, Pre-buffer: %d, Post-buffer: %d" ,
15781616 config .detection_model , config .detection_threshold , config .detection_interval ,
0 commit comments