From 201bcda0514aa9726ed90eff6ad4180b0bb16fc3 Mon Sep 17 00:00:00 2001 From: tytan652 Date: Sat, 21 Aug 2021 08:51:21 +0200 Subject: [PATCH 1/6] libobs,docs: Add protocol in Outputs API --- docs/sphinx/reference-outputs.rst | 26 +++++++++++++++++++++++++- libobs/obs-internal.h | 2 ++ libobs/obs-module.c | 21 +++++++++++++++++++++ libobs/obs-output.c | 10 ++++++++++ libobs/obs-output.h | 3 +++ libobs/obs.c | 14 ++++++++++++++ libobs/obs.h | 4 ++++ 7 files changed, 79 insertions(+), 1 deletion(-) diff --git a/docs/sphinx/reference-outputs.rst b/docs/sphinx/reference-outputs.rst index 0cbe9f98865d2c..eb8b94c0b1e652 100644 --- a/docs/sphinx/reference-outputs.rst +++ b/docs/sphinx/reference-outputs.rst @@ -234,7 +234,15 @@ Output Definition Structure (obs_output_info) This variable specifies which codecs are supported by an encoded output, separated by semicolon. - (Optional, though recommended) + Required if **OBS_OUTPUT_SERVICE** flag is set, otherwise + recommended. + +.. member:: const char *obs_output_info.protocols + + This variable specifies which protocols are supported by an output, + separated by semicolon. + + Required only if **OBS_OUTPUT_SERVICE** flag is set. .. _output_signal_handler_reference: @@ -685,6 +693,22 @@ General Output Functions --------------------- +.. function:: const char *obs_output_get_protocols(const obs_output_t *output) + + :return: Supported protocols, separated by semicolon. Always NULL if the + output is not **OBS_OUTPUT_SERVICE**. + +--------------------- + +.. function:: bool obs_is_output_protocol_registered(const char *protocol) + + Check if one of the registered output use the given protocol. + + :return: A boolean showing if an output with the given + protocol is registered + +--------------------- + Functions used by outputs ------------------------- diff --git a/libobs/obs-internal.h b/libobs/obs-internal.h index f6a3835501998c..a67fb518cb8036 100644 --- a/libobs/obs-internal.h +++ b/libobs/obs-internal.h @@ -411,6 +411,8 @@ struct obs_core_data { obs_data_t *private_data; volatile bool valid; + + DARRAY(char *) protocols; }; /* user hotkeys */ diff --git a/libobs/obs-module.c b/libobs/obs-module.c index ff118814f75862..73c8228a57c1f2 100644 --- a/libobs/obs-module.c +++ b/libobs/obs-module.c @@ -836,6 +836,9 @@ void obs_register_output_s(const struct obs_output_info *info, size_t size) CHECK_REQUIRED_VAL_(info, start, obs_register_output); CHECK_REQUIRED_VAL_(info, stop, obs_register_output); + if (info->flags & OBS_OUTPUT_SERVICE) + CHECK_REQUIRED_VAL_(info, protocols, obs_register_output); + if (info->flags & OBS_OUTPUT_ENCODED) { CHECK_REQUIRED_VAL_(info, encoded_packet, obs_register_output); } else { @@ -856,6 +859,24 @@ void obs_register_output_s(const struct obs_output_info *info, size_t size) #undef CHECK_REQUIRED_VAL_ REGISTER_OBS_DEF(size, obs_output_info, obs->output_types, info); + + if (info->flags & OBS_OUTPUT_SERVICE) { + char **protocols = strlist_split(info->protocols, ';', false); + for (char **protocol = protocols; *protocol; ++protocol) { + bool skip = false; + for (size_t i = 0; i < obs->data.protocols.num; i++) { + if (strcmp(*protocol, + obs->data.protocols.array[i]) == 0) + skip = true; + } + + if (skip) + continue; + char *new_prtcl = bstrdup(*protocol); + da_push_back(obs->data.protocols, &new_prtcl); + } + strlist_free(protocols); + } return; error: diff --git a/libobs/obs-output.c b/libobs/obs-output.c index 335b7655541dd1..148b31b4a13ece 100644 --- a/libobs/obs-output.c +++ b/libobs/obs-output.c @@ -2713,3 +2713,13 @@ const char *obs_output_get_supported_audio_codecs(const obs_output_t *output) ? output->info.encoded_audio_codecs : NULL; } + +const char *obs_output_get_protocols(const obs_output_t *output) +{ + if (!obs_output_valid(output, "obs_output_get_protocols")) + return NULL; + + return (output->info.flags & OBS_OUTPUT_SERVICE) + ? output->info.protocols + : NULL; +} diff --git a/libobs/obs-output.h b/libobs/obs-output.h index e57659fd9f5104..0469d39a174733 100644 --- a/libobs/obs-output.h +++ b/libobs/obs-output.h @@ -77,6 +77,9 @@ struct obs_output_info { /* raw audio callback for multi track outputs */ void (*raw_audio2)(void *data, size_t idx, struct audio_data *frames); + + /* required if OBS_OUTPUT_SERVICE */ + const char *protocols; }; EXPORT void obs_register_output_s(const struct obs_output_info *info, diff --git a/libobs/obs.c b/libobs/obs.c index cb17d5d8840832..3cd697a072defa 100644 --- a/libobs/obs.c +++ b/libobs/obs.c @@ -1078,6 +1078,10 @@ static void obs_free_data(void) da_free(data->draw_callbacks); da_free(data->tick_callbacks); obs_data_release(data->private_data); + + for (size_t i = 0; i < data->protocols.num; i++) + bfree(data->protocols.array[i]); + da_free(data->protocols); } static const char *obs_signals[] = { @@ -3452,3 +3456,13 @@ bool obs_weak_object_references_object(obs_weak_object_t *weak, { return weak && object && weak->object == object; } + +bool obs_is_output_protocol_registered(const char *protocol) +{ + for (size_t i = 0; i < obs->data.protocols.num; i++) { + if (strcmp(protocol, obs->data.protocols.array[i]) == 0) + return true; + } + + return false; +} diff --git a/libobs/obs.h b/libobs/obs.h index f5b84b7082fba7..f6e08e33a47568 100644 --- a/libobs/obs.h +++ b/libobs/obs.h @@ -2211,6 +2211,10 @@ obs_output_get_supported_video_codecs(const obs_output_t *output); EXPORT const char * obs_output_get_supported_audio_codecs(const obs_output_t *output); +EXPORT const char *obs_output_get_protocols(const obs_output_t *output); + +EXPORT bool obs_is_output_protocol_registered(const char *protocol); + /* ------------------------------------------------------------------------- */ /* Functions used by outputs */ From 855956f60ecdac1013fa28b7124f1bfb03935ab9 Mon Sep 17 00:00:00 2001 From: tytan652 Date: Sat, 21 Aug 2021 08:53:21 +0200 Subject: [PATCH 2/6] obs-outputs,obs-ffmpeg: Add protocol to service outputs --- plugins/obs-ffmpeg/obs-ffmpeg-hls-mux.c | 1 + plugins/obs-ffmpeg/obs-ffmpeg-mpegts.c | 1 + plugins/obs-ffmpeg/obs-ffmpeg-mux.c | 1 + plugins/obs-outputs/ftl-stream.c | 1 + plugins/obs-outputs/rtmp-stream.c | 5 +++++ 5 files changed, 9 insertions(+) diff --git a/plugins/obs-ffmpeg/obs-ffmpeg-hls-mux.c b/plugins/obs-ffmpeg/obs-ffmpeg-hls-mux.c index 017ecba76aef5f..d8546bf26014ce 100644 --- a/plugins/obs-ffmpeg/obs-ffmpeg-hls-mux.c +++ b/plugins/obs-ffmpeg/obs-ffmpeg-hls-mux.c @@ -331,6 +331,7 @@ struct obs_output_info ffmpeg_hls_muxer = { .id = "ffmpeg_hls_muxer", .flags = OBS_OUTPUT_AV | OBS_OUTPUT_ENCODED | OBS_OUTPUT_MULTI_TRACK | OBS_OUTPUT_SERVICE, + .protocols = "HLS", #ifdef ENABLE_HEVC .encoded_video_codecs = "h264;hevc", #else diff --git a/plugins/obs-ffmpeg/obs-ffmpeg-mpegts.c b/plugins/obs-ffmpeg/obs-ffmpeg-mpegts.c index 5a20aae5132cfa..f9cc4ae7e38b5d 100644 --- a/plugins/obs-ffmpeg/obs-ffmpeg-mpegts.c +++ b/plugins/obs-ffmpeg/obs-ffmpeg-mpegts.c @@ -1289,6 +1289,7 @@ struct obs_output_info ffmpeg_mpegts_muxer = { .id = "ffmpeg_mpegts_muxer", .flags = OBS_OUTPUT_AV | OBS_OUTPUT_ENCODED | OBS_OUTPUT_MULTI_TRACK | OBS_OUTPUT_SERVICE, + .protocols = "SRT;RIST", #ifdef ENABLE_HEVC .encoded_video_codecs = "h264;hevc;av1", #else diff --git a/plugins/obs-ffmpeg/obs-ffmpeg-mux.c b/plugins/obs-ffmpeg/obs-ffmpeg-mux.c index a605e9af352fc3..d4156b5153e283 100644 --- a/plugins/obs-ffmpeg/obs-ffmpeg-mux.c +++ b/plugins/obs-ffmpeg/obs-ffmpeg-mux.c @@ -944,6 +944,7 @@ struct obs_output_info ffmpeg_mpegts_muxer = { .id = "ffmpeg_mpegts_muxer", .flags = OBS_OUTPUT_AV | OBS_OUTPUT_ENCODED | OBS_OUTPUT_MULTI_TRACK | OBS_OUTPUT_SERVICE, + .protocols = "SRT;RIST", .encoded_video_codecs = "h264;av1", .encoded_audio_codecs = "aac", .get_name = ffmpeg_mpegts_mux_getname, diff --git a/plugins/obs-outputs/ftl-stream.c b/plugins/obs-outputs/ftl-stream.c index a0556d2a5d36d6..ef305420fc57c2 100644 --- a/plugins/obs-outputs/ftl-stream.c +++ b/plugins/obs-outputs/ftl-stream.c @@ -1159,6 +1159,7 @@ static int _ftl_error_to_obs_error(int status) struct obs_output_info ftl_output_info = { .id = "ftl_output", .flags = OBS_OUTPUT_AV | OBS_OUTPUT_ENCODED | OBS_OUTPUT_SERVICE, + .protocols = "FTL", .encoded_video_codecs = "h264", .encoded_audio_codecs = "opus", .get_name = ftl_stream_getname, diff --git a/plugins/obs-outputs/rtmp-stream.c b/plugins/obs-outputs/rtmp-stream.c index f186c36161280e..6058d4f7fdf65b 100644 --- a/plugins/obs-outputs/rtmp-stream.c +++ b/plugins/obs-outputs/rtmp-stream.c @@ -1642,6 +1642,11 @@ struct obs_output_info rtmp_output_info = { .id = "rtmp_output", .flags = OBS_OUTPUT_AV | OBS_OUTPUT_ENCODED | OBS_OUTPUT_SERVICE | OBS_OUTPUT_MULTI_TRACK, +#ifdef NO_CRYPTO + .protocols = "RTMP", +#else + .protocols = "RTMP;RTMPS", +#endif .encoded_video_codecs = "h264", .encoded_audio_codecs = "aac", .get_name = rtmp_stream_getname, From 513c6bc4896ff97e0981125b6d8c9837bae712f5 Mon Sep 17 00:00:00 2001 From: tytan652 Date: Mon, 25 Apr 2022 12:54:48 +0200 Subject: [PATCH 3/6] rtmp-services: Add protocols to services JSON If the server URL is not an RTMP(S) URL, the protocol field becomes required. The output field becomes required on non-RTMP(S) services to keep backward compatibility. Also skip service if the protocol is not available. --- plugins/rtmp-services/data/package.json | 4 +- .../data/schema/service-schema-v4.json | 24 +++++++++++ plugins/rtmp-services/data/services.json | 5 +++ plugins/rtmp-services/rtmp-common.c | 43 +++++++++++++++++++ 4 files changed, 74 insertions(+), 2 deletions(-) diff --git a/plugins/rtmp-services/data/package.json b/plugins/rtmp-services/data/package.json index 89e6d4f31d1c14..a9c3e5f824ebab 100644 --- a/plugins/rtmp-services/data/package.json +++ b/plugins/rtmp-services/data/package.json @@ -1,11 +1,11 @@ { "$schema": "schema/package-schema.json", "url": "https://obsproject.com/obs2_update/rtmp-services/v4", - "version": 220, + "version": 221, "files": [ { "name": "services.json", - "version": 220 + "version": 221 } ] } diff --git a/plugins/rtmp-services/data/schema/service-schema-v4.json b/plugins/rtmp-services/data/schema/service-schema-v4.json index 61f3c0cf2d37e9..e5afe45851ea15 100644 --- a/plugins/rtmp-services/data/schema/service-schema-v4.json +++ b/plugins/rtmp-services/data/schema/service-schema-v4.json @@ -16,6 +16,18 @@ "description": "Name of the streaming service. Will be displayed in the Service dropdown.", "minLength": 1 }, + "protocol" : { + "type": "string", + "description": "Protocol used by the service. If missing the service is considered using RTMP or RTMPS.", + "enum": [ + "RTMP", + "RTMPS", + "HLS", + "FTL", + "SRT", + "RIST" + ] + }, "common": { "type": "boolean", "description": "Whether or not the service is shown in the list before it is expanded to all services by the user.", @@ -200,6 +212,18 @@ "required": [ "name", "servers" + ], + "allOf": [ + { + "$comment": "Require protocol field if not an RTMP(S) URL", + "if": { "not": { "properties": { "servers": { "items": { "properties": { "url": { "format": "uri", "pattern": "^rtmps?://" } } } } } } }, + "then": { "required": ["protocol"] } + }, + { + "$comment": "Require recommended output field if protocol field is not RTMP(S)", + "if": { "required": ["protocol"], "properties": { "protocol": { "pattern": "^(HLS|SRT|RIST|FTL)$" } } }, + "then": { "properties": { "recommended": { "required": ["output"] } } } + } ] }, "additionalItems": true diff --git a/plugins/rtmp-services/data/services.json b/plugins/rtmp-services/data/services.json index c9f8391ddd722e..e0fb4e5a489849 100644 --- a/plugins/rtmp-services/data/services.json +++ b/plugins/rtmp-services/data/services.json @@ -204,6 +204,7 @@ "common": false, "more_info_link": "https://developers.google.com/youtube/v3/live/guides/ingestion-protocol-comparison", "stream_key_link": "https://www.youtube.com/live_dashboard", + "protocol": "HLS", "supported video codecs": [ "h264", "hevc" @@ -1445,6 +1446,7 @@ { "name": "YouNow", "common": false, + "protocol": "FTL", "supported audio codecs": [ "opus" ], @@ -1687,6 +1689,7 @@ }, { "name": "SHOWROOM", + "protocol": "RTMP", "servers": [ { "name": "Default", @@ -1821,6 +1824,7 @@ { "name": "Glimesh", "stream_key_link": "https://glimesh.tv/users/settings/stream", + "protocol": "FTL", "supported audio codecs": [ "opus" ], @@ -2024,6 +2028,7 @@ }, { "name": "Dacast", + "protocol": "RTMP", "servers": [ { "name": "Default", diff --git a/plugins/rtmp-services/rtmp-common.c b/plugins/rtmp-services/rtmp-common.c index 1aa20ec6758772..778d06d499a062 100644 --- a/plugins/rtmp-services/rtmp-common.c +++ b/plugins/rtmp-services/rtmp-common.c @@ -208,6 +208,35 @@ static inline bool get_bool_val(json_t *service, const char *key) return json_is_true(bool_val); } +#define RTMP_PREFIX "rtmp://" +#define RTMPS_PREFIX "rtmps://" + +static bool is_protocol_available(json_t *service) +{ + const char *protocol = get_string_val(service, "protocol"); + if (protocol) + return obs_is_output_protocol_registered(protocol); + + /* Test RTMP and RTMPS if no protocol found */ + json_t *servers; + size_t index; + json_t *server; + const char *url; + bool ret = false; + + servers = json_object_get(service, "servers"); + json_array_foreach (servers, index, server) { + url = get_string_val(server, "url"); + + if (strncmp(url, RTMP_PREFIX, strlen(RTMP_PREFIX)) == 0) + ret |= obs_is_output_protocol_registered("RTMP"); + else if (strncmp(url, RTMPS_PREFIX, strlen(RTMPS_PREFIX)) == 0) + ret |= obs_is_output_protocol_registered("RTMPS"); + } + + return ret; +} + static void add_service(obs_property_t *list, json_t *service, bool show_all, const char *cur_service) { @@ -258,6 +287,9 @@ static void add_services(obs_property_t *list, json_t *root, bool show_all, } json_array_foreach (root, index, service) { + /* Skip service with non-available protocol */ + if (!is_protocol_available(service)) + continue; add_service(list, service, show_all, cur_service); } @@ -399,11 +431,13 @@ static void fill_servers(obs_property_t *servers_prop, json_t *service, return; } + /* Assumption: Twitch should be RTMP only, so no RTMPS check */ if (strcmp(name, "Twitch") == 0) { if (fill_twitch_servers(servers_prop)) return; } + /* Assumption: Nimo TV should be RTMP only, so no RTMPS check in the ingest */ if (strcmp(name, "Nimo TV") == 0) { obs_property_list_add_string( servers_prop, obs_module_text("Server.Auto"), "auto"); @@ -416,6 +450,11 @@ static void fill_servers(obs_property_t *servers_prop, json_t *service, if (!server_name || !url) continue; + /* Skip RTMPS server if protocol not registered */ + if ((!obs_is_output_protocol_registered("RTMPS")) && + (strncmp(url, "rtmps://", 8) == 0)) + continue; + obs_property_list_add_string(servers_prop, server_name, url); } } @@ -449,6 +488,10 @@ static inline json_t *find_service(json_t *root, const char *name, *p_new_name = NULL; json_array_foreach (root, index, service) { + /* skip service with non-available protocol */ + if (!is_protocol_available(service)) + continue; + const char *cur_name = get_string_val(service, "name"); if (strcmp(name, cur_name) == 0) From 813b3b2763a9942a54b14ab4050d9d96bd0d62ea Mon Sep 17 00:00:00 2001 From: tytan652 Date: Mon, 5 Sep 2022 14:00:08 +0200 Subject: [PATCH 4/6] libobs,docs: Add protocol to Services API --- docs/sphinx/reference-services.rst | 10 ++++++++++ libobs/obs-module.c | 1 + libobs/obs-service.c | 8 ++++++++ libobs/obs-service.h | 2 ++ libobs/obs.h | 3 +++ 5 files changed, 24 insertions(+) diff --git a/docs/sphinx/reference-services.rst b/docs/sphinx/reference-services.rst index 85a0c876235c0e..7c6a89dfe379b1 100644 --- a/docs/sphinx/reference-services.rst +++ b/docs/sphinx/reference-services.rst @@ -148,6 +148,10 @@ Service Definition Structure the data manually (typically best to use strlist_split to generate this) +.. member:: const char *(*obs_service_info.get_protocol)(void *data) + + :return: The protocol used by the service + General Service Functions ------------------------- @@ -305,6 +309,12 @@ General Service Functions for the service, terminated with a *NULL* pointer. Does not need to be freed +--------------------- + +.. function:: const char *obs_service_get_protocol(const obs_service_t *service) + + :return: Protocol currently used for this service + .. --------------------------------------------------------------------------- .. _libobs/obs-service.h: https://github.com/obsproject/obs-studio/blob/master/libobs/obs-service.h diff --git a/libobs/obs-module.c b/libobs/obs-module.c index 73c8228a57c1f2..cd7841b6c1960d 100644 --- a/libobs/obs-module.c +++ b/libobs/obs-module.c @@ -928,6 +928,7 @@ void obs_register_service_s(const struct obs_service_info *info, size_t size) CHECK_REQUIRED_VAL_(info, get_name, obs_register_service); CHECK_REQUIRED_VAL_(info, create, obs_register_service); CHECK_REQUIRED_VAL_(info, destroy, obs_register_service); + CHECK_REQUIRED_VAL_(info, get_protocol, obs_register_service); #undef CHECK_REQUIRED_VAL_ REGISTER_OBS_DEF(size, obs_service_info, obs->service_types, info); diff --git a/libobs/obs-service.c b/libobs/obs-service.c index a2cd0140c6d1da..607844f30016e8 100644 --- a/libobs/obs-service.c +++ b/libobs/obs-service.c @@ -477,3 +477,11 @@ obs_service_get_supported_video_codecs(const obs_service_t *service) service->context.data); return NULL; } + +const char *obs_service_get_protocol(const obs_service_t *service) +{ + if (!obs_service_valid(service, "obs_service_get_protocol")) + return NULL; + + return service->info.get_protocol(service->context.data); +} diff --git a/libobs/obs-service.h b/libobs/obs-service.h index f025260ff1b70f..e02ed822e7776f 100644 --- a/libobs/obs-service.h +++ b/libobs/obs-service.h @@ -88,6 +88,8 @@ struct obs_service_info { int *audio_bitrate); const char **(*get_supported_video_codecs)(void *data); + + const char *(*get_protocol)(void *data); }; EXPORT void obs_register_service_s(const struct obs_service_info *info, diff --git a/libobs/obs.h b/libobs/obs.h index f6e08e33a47568..f646f4b21dc12b 100644 --- a/libobs/obs.h +++ b/libobs/obs.h @@ -2539,6 +2539,9 @@ obs_service_get_supported_video_codecs(const obs_service_t *service); * date. */ EXPORT const char *obs_service_get_output_type(const obs_service_t *service); +/** Returns the protocol for this service context */ +EXPORT const char *obs_service_get_protocol(const obs_service_t *service); + /* ------------------------------------------------------------------------- */ /* Source frame allocation functions */ EXPORT void obs_source_frame_init(struct obs_source_frame *frame, From 56411eda8e96c2c35043dbfa151a3eafe7a6780b Mon Sep 17 00:00:00 2001 From: tytan652 Date: Mon, 5 Sep 2022 14:58:27 +0200 Subject: [PATCH 5/6] libobs,docs: Add protocol enumeration functions --- docs/sphinx/reference-outputs.rst | 18 ++++++++++++++++++ libobs/obs-output.c | 28 ++++++++++++++++++++++++++++ libobs/obs.c | 9 +++++++++ libobs/obs.h | 6 ++++++ 4 files changed, 61 insertions(+) diff --git a/docs/sphinx/reference-outputs.rst b/docs/sphinx/reference-outputs.rst index eb8b94c0b1e652..e7c85a7e8d7ef3 100644 --- a/docs/sphinx/reference-outputs.rst +++ b/docs/sphinx/reference-outputs.rst @@ -709,6 +709,24 @@ General Output Functions --------------------- +.. function:: bool obs_enum_output_protocols(size_t idx, char **protocol) + + Enumerates all registered protocol. + +--------------------- + +.. function:: void obs_enum_output_types_with_protocol(const char *protocol, void *data, bool (*enum_cb)(void *data, const char *id)) + + Enumerates through a callback all available output types for the given protocol. + + :param protocol: Protocol of the outputs to enumerate + :param data: Data passed to the callback + :param enum_cb: Callback used when a matching output is found, the id + of the output is passed to the callback + :return: When all outputs are enumerated or if the callback return *false* + +--------------------- + Functions used by outputs ------------------------- diff --git a/libobs/obs-output.c b/libobs/obs-output.c index 148b31b4a13ece..c9543e4e8f035b 100644 --- a/libobs/obs-output.c +++ b/libobs/obs-output.c @@ -2723,3 +2723,31 @@ const char *obs_output_get_protocols(const obs_output_t *output) ? output->info.protocols : NULL; } + +void obs_enum_output_types_with_protocol(const char *protocol, void *data, + bool (*enum_cb)(void *data, + const char *id)) +{ + if (!obs_is_output_protocol_registered(protocol)) + return; + + size_t protocol_len = strlen(protocol); + for (size_t i = 0; i < obs->output_types.num; i++) { + if (!(obs->output_types.array[i].flags & OBS_OUTPUT_SERVICE)) + continue; + + const char *substr = obs->output_types.array[i].protocols; + while (substr && substr[0] != '\0') { + const char *next = strchr(substr, ';'); + size_t len = next ? (size_t)(next - substr) + : strlen(substr); + if (protocol_len == len && + strncmp(substr, protocol, len) == 0) { + if (!enum_cb(data, + obs->output_types.array[i].id)) + return; + } + substr = next ? next + 1 : NULL; + } + } +} diff --git a/libobs/obs.c b/libobs/obs.c index 3cd697a072defa..73e281eaa83733 100644 --- a/libobs/obs.c +++ b/libobs/obs.c @@ -3466,3 +3466,12 @@ bool obs_is_output_protocol_registered(const char *protocol) return false; } + +bool obs_enum_output_protocols(size_t idx, char **protocol) +{ + if (idx >= obs->data.protocols.num) + return false; + + *protocol = obs->data.protocols.array[idx]; + return true; +} diff --git a/libobs/obs.h b/libobs/obs.h index f646f4b21dc12b..5f82929c362230 100644 --- a/libobs/obs.h +++ b/libobs/obs.h @@ -2215,6 +2215,12 @@ EXPORT const char *obs_output_get_protocols(const obs_output_t *output); EXPORT bool obs_is_output_protocol_registered(const char *protocol); +EXPORT bool obs_enum_output_protocols(size_t idx, char **protocol); + +EXPORT void obs_enum_output_types_with_protocol( + const char *protocol, void *data, + bool (*enum_cb)(void *data, const char *id)); + /* ------------------------------------------------------------------------- */ /* Functions used by outputs */ From fa58a38b24efef88a6baf67c41d280a9e8b29575 Mon Sep 17 00:00:00 2001 From: tytan652 Date: Mon, 5 Sep 2022 15:19:32 +0200 Subject: [PATCH 6/6] rtmp-services: Add protocol getter to services --- plugins/rtmp-services/rtmp-common.c | 36 +++++++++++++++++++++++++++++ plugins/rtmp-services/rtmp-custom.c | 25 ++++++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/plugins/rtmp-services/rtmp-common.c b/plugins/rtmp-services/rtmp-common.c index 778d06d499a062..984053ffb790ec 100644 --- a/plugins/rtmp-services/rtmp-common.c +++ b/plugins/rtmp-services/rtmp-common.c @@ -13,6 +13,7 @@ struct rtmp_common { char *service; + char *protocol; char *server; char *key; @@ -118,11 +119,13 @@ static void rtmp_common_update(void *data, obs_data_t *settings) bfree(service->supported_resolutions); bfree(service->video_codecs); bfree(service->service); + bfree(service->protocol); bfree(service->server); bfree(service->output); bfree(service->key); service->service = bstrdup(obs_data_get_string(settings, "service")); + service->protocol = bstrdup(obs_data_get_string(settings, "protocol")); service->server = bstrdup(obs_data_get_string(settings, "server")); service->key = bstrdup(obs_data_get_string(settings, "key")); service->supports_additional_audio_track = false; @@ -166,6 +169,7 @@ static void rtmp_common_destroy(void *data) bfree(service->supported_resolutions); bfree(service->video_codecs); bfree(service->service); + bfree(service->protocol); bfree(service->server); bfree(service->output); bfree(service->key); @@ -478,6 +482,29 @@ static void fill_stream_key_link(json_t *service, obs_data_t *settings) stream_key_link); } +static void update_protocol(json_t *service, obs_data_t *settings) +{ + const char *protocol = get_string_val(service, "protocol"); + if (protocol) { + obs_data_set_string(settings, "protocol", protocol); + return; + } + + json_t *servers = json_object_get(service, "servers"); + if (!json_is_array(servers)) + return; + + json_t *server = json_array_get(servers, 0); + const char *url = get_string_val(server, "url"); + + if (strncmp(url, RTMPS_PREFIX, strlen(RTMPS_PREFIX)) == 0) { + obs_data_set_string(settings, "protocol", "RTMPS"); + return; + } + + obs_data_set_string(settings, "protocol", "RTMP"); +} + static inline json_t *find_service(json_t *root, const char *name, const char **p_new_name) { @@ -546,6 +573,7 @@ static bool service_selected(obs_properties_t *props, obs_property_t *p, fill_servers(obs_properties_get(props, "server"), service, name); fill_more_info_link(service, settings); fill_stream_key_link(service, settings); + update_protocol(service, settings); return true; } @@ -968,6 +996,13 @@ static const char *rtmp_common_password(void *data) return NULL; } +static const char *rtmp_common_get_protocol(void *data) +{ + struct rtmp_common *service = data; + + return service->protocol ? service->protocol : "RTMP"; +} + struct obs_service_info rtmp_common_service = { .id = "rtmp_common", .get_name = rtmp_common_getname, @@ -975,6 +1010,7 @@ struct obs_service_info rtmp_common_service = { .destroy = rtmp_common_destroy, .update = rtmp_common_update, .get_properties = rtmp_common_properties, + .get_protocol = rtmp_common_get_protocol, .get_url = rtmp_common_url, .get_key = rtmp_common_key, .get_username = rtmp_common_username, diff --git a/plugins/rtmp-services/rtmp-custom.c b/plugins/rtmp-services/rtmp-custom.c index 51276d6c8a45d0..53ef3d4bf6fd09 100644 --- a/plugins/rtmp-services/rtmp-custom.c +++ b/plugins/rtmp-services/rtmp-custom.c @@ -110,6 +110,30 @@ static const char *rtmp_custom_password(void *data) return service->password; } +#define RTMPS_PREFIX "rtmps://" +#define FTL_PREFIX "ftl://" +#define SRT_PREFIX "srt://" +#define RIST_PREFIX "rist://" + +static const char *rtmp_custom_get_protocol(void *data) +{ + struct rtmp_custom *service = data; + + if (strncmp(service->server, RTMPS_PREFIX, strlen(RTMPS_PREFIX)) == 0) + return "RTMPS"; + + if (strncmp(service->server, FTL_PREFIX, strlen(FTL_PREFIX)) == 0) + return "FTL"; + + if (strncmp(service->server, SRT_PREFIX, strlen(SRT_PREFIX)) == 0) + return "SRT"; + + if (strncmp(service->server, RIST_PREFIX, strlen(RIST_PREFIX)) == 0) + return "RIST"; + + return "RTMP"; +} + #define RTMP_PROTOCOL "rtmp" static void rtmp_custom_apply_settings(void *data, obs_data_t *video_settings, @@ -131,6 +155,7 @@ struct obs_service_info rtmp_custom_service = { .destroy = rtmp_custom_destroy, .update = rtmp_custom_update, .get_properties = rtmp_custom_properties, + .get_protocol = rtmp_custom_get_protocol, .get_url = rtmp_custom_url, .get_key = rtmp_custom_key, .get_username = rtmp_custom_username,