From 4714a351d22b5850643cd6423927db84000eba9a Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 6 May 2026 20:31:45 +0000 Subject: [PATCH 1/2] Make stream key (path) optional, defaulting to empty broadcast MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Path field on the MoQ service was effectively required: if a user left it blank, obs_service_get_connect_info could return null, which the output then assigned to a std::string — undefined behaviour that manifested as a hang at start-of-stream. - Treat the key/path as optional and default to "" via get_defaults. - Null-guard the values returned by obs_data_get_string and obs_service_get_connect_info before assigning to std::string. - Relabel the property as "Path (optional)" in the UI. https://claude.ai/code/session_01AH2RwNCd5nPs8hNHYmMv97 --- src/moq-output.cpp | 7 +++++-- src/moq-service.cpp | 18 +++++++++++++++--- src/moq-service.h | 1 + 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/moq-output.cpp b/src/moq-output.cpp index 4594fc5..e08af33 100644 --- a/src/moq-output.cpp +++ b/src/moq-output.cpp @@ -46,14 +46,17 @@ bool MoQOutput::Start() return false; } - server_url = obs_service_get_connect_info(service, OBS_SERVICE_CONNECT_INFO_SERVER_URL); + const char *server_value = obs_service_get_connect_info(service, OBS_SERVICE_CONNECT_INFO_SERVER_URL); + server_url = server_value ? server_value : ""; if (server_url.empty()) { LOG_ERROR("Server URL is empty"); obs_output_signal_stop(output, OBS_OUTPUT_BAD_PATH); return false; } - path = obs_service_get_connect_info(service, OBS_SERVICE_CONNECT_INFO_STREAM_KEY); + // Path (broadcast name) is optional; an empty string publishes to the unnamed broadcast. + const char *path_value = obs_service_get_connect_info(service, OBS_SERVICE_CONNECT_INFO_STREAM_KEY); + path = path_value ? path_value : ""; bool found_encoder = false; for (uint32_t idx = 0; idx < MAX_OUTPUT_VIDEO_ENCODERS; idx++) { diff --git a/src/moq-service.cpp b/src/moq-service.cpp index 21e484c..8141a87 100644 --- a/src/moq-service.cpp +++ b/src/moq-service.cpp @@ -11,8 +11,17 @@ MoQService::MoQService(obs_data_t *settings, obs_service_t *) : server(), path() void MoQService::Update(obs_data_t *settings) { - server = obs_data_get_string(settings, "server"); - path = obs_data_get_string(settings, "key"); + const char *server_value = obs_data_get_string(settings, "server"); + const char *key_value = obs_data_get_string(settings, "key"); + + server = server_value ? server_value : ""; + path = key_value ? key_value : ""; +} + +void MoQService::Defaults(obs_data_t *settings) +{ + obs_data_set_default_string(settings, "server", ""); + obs_data_set_default_string(settings, "key", ""); } obs_properties_t *MoQService::Properties() @@ -22,7 +31,7 @@ obs_properties_t *MoQService::Properties() // Adds properties to be modified by the UI. // obs_property_t *obs_properties_add_text(obs_properties_t *props, const char *name, const char *desc, enum obs_text_type type) obs_properties_add_text(ppts, "server", "URL", OBS_TEXT_DEFAULT); - obs_properties_add_text(ppts, "key", "Path", OBS_TEXT_DEFAULT); + obs_properties_add_text(ppts, "key", "Path (optional)", OBS_TEXT_DEFAULT); return ppts; } @@ -84,6 +93,9 @@ void register_moq_service() info.get_properties = [](void *) -> obs_properties_t * { return MoQService::Properties(); }; + info.get_defaults = [](obs_data_t *settings) { + MoQService::Defaults(settings); + }; info.get_protocol = [](void *) -> const char * { return "MoQ"; }; diff --git a/src/moq-service.h b/src/moq-service.h index adc7175..15a0c6d 100644 --- a/src/moq-service.h +++ b/src/moq-service.h @@ -10,6 +10,7 @@ struct MoQService { MoQService(obs_data_t *settings, obs_service_t *service); void Update(obs_data_t *settings); + static void Defaults(obs_data_t *settings); static obs_properties_t *Properties(); static void ApplyEncoderSettings(obs_data_t *video_settings, obs_data_t *audio_settings); bool CanTryToConnect(); From 38f4a33f4936b431fe354f983a8c109bb8b429c9 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 7 May 2026 17:35:19 +0000 Subject: [PATCH 2/2] Simplify: drop redundant Defaults and Update null guards obs_data_get_string returns "" for missing keys, so the ternary fallbacks in Update and the empty-string defaults in Defaults were no-ops. Keep the genuine null guard around obs_service_get_connect_info in moq-output.cpp where it matters. https://claude.ai/code/session_01AH2RwNCd5nPs8hNHYmMv97 --- src/moq-service.cpp | 16 ++-------------- src/moq-service.h | 1 - 2 files changed, 2 insertions(+), 15 deletions(-) diff --git a/src/moq-service.cpp b/src/moq-service.cpp index 8141a87..69aa36e 100644 --- a/src/moq-service.cpp +++ b/src/moq-service.cpp @@ -11,17 +11,8 @@ MoQService::MoQService(obs_data_t *settings, obs_service_t *) : server(), path() void MoQService::Update(obs_data_t *settings) { - const char *server_value = obs_data_get_string(settings, "server"); - const char *key_value = obs_data_get_string(settings, "key"); - - server = server_value ? server_value : ""; - path = key_value ? key_value : ""; -} - -void MoQService::Defaults(obs_data_t *settings) -{ - obs_data_set_default_string(settings, "server", ""); - obs_data_set_default_string(settings, "key", ""); + server = obs_data_get_string(settings, "server"); + path = obs_data_get_string(settings, "key"); } obs_properties_t *MoQService::Properties() @@ -93,9 +84,6 @@ void register_moq_service() info.get_properties = [](void *) -> obs_properties_t * { return MoQService::Properties(); }; - info.get_defaults = [](obs_data_t *settings) { - MoQService::Defaults(settings); - }; info.get_protocol = [](void *) -> const char * { return "MoQ"; }; diff --git a/src/moq-service.h b/src/moq-service.h index 15a0c6d..adc7175 100644 --- a/src/moq-service.h +++ b/src/moq-service.h @@ -10,7 +10,6 @@ struct MoQService { MoQService(obs_data_t *settings, obs_service_t *service); void Update(obs_data_t *settings); - static void Defaults(obs_data_t *settings); static obs_properties_t *Properties(); static void ApplyEncoderSettings(obs_data_t *video_settings, obs_data_t *audio_settings); bool CanTryToConnect();