From 563936ea087e428406fc5cc30f8e8ea0879afe93 Mon Sep 17 00:00:00 2001 From: Palakis Date: Mon, 13 Nov 2017 15:01:41 +0100 Subject: [PATCH] requests: add GetSourceTypesList --- WSRequestHandler.cpp | 114 +++++++++++++++++++++++++++++++++++++++++-- WSRequestHandler.h | 1 + 2 files changed, 110 insertions(+), 5 deletions(-) diff --git a/WSRequestHandler.cpp b/WSRequestHandler.cpp index 1bf2042e..a6e3dc37 100644 --- a/WSRequestHandler.cpp +++ b/WSRequestHandler.cpp @@ -82,6 +82,7 @@ QHash WSRequestHandler::messageMap { { "GetSyncOffset", WSRequestHandler::HandleGetSyncOffset }, { "GetSpecialSources", WSRequestHandler::HandleGetSpecialSources }, { "GetSourcesList", WSRequestHandler::HandleGetSourcesList }, + { "GetSourceTypesList", WSRequestHandler::HandleGetSourceTypesList }, { "GetSourceSettings", WSRequestHandler::HandleGetSourceSettings }, { "SetSourceSettings", WSRequestHandler::HandleSetSourceSettings }, @@ -548,6 +549,8 @@ void WSRequestHandler::HandleStartStreaming(WSRequestHandler* req) { OBSService configuredService = obs_frontend_get_streaming_service(); OBSService newService = nullptr; + // TODO: fix service memory leak + if (req->hasField("stream")) { OBSDataAutoRelease streamData = obs_data_get_obj(req->data, "stream"); OBSDataAutoRelease newSettings = obs_data_get_obj(streamData, "settings"); @@ -2579,8 +2582,9 @@ void WSRequestHandler::HandleResetSceneItem(WSRequestHandler* req) { * List all sources available in the running OBS instance * * @return {Array of Objects} `sources` Array of sources as objects - * @return {String} `sources.*.name` Source name - * @return {String} `sources.*.type` Source type + * @return {String} `sources.*.name` Unique source name + * @return {String} `sources.*.typeId` Non-unique source internal type (a.k.a type id) + * @return {String} `sources.*.type` Source type. Value is one of the following: "input", "filter", "transition", "scene" or "unknown" * * @api requests * @name GetSourcesList @@ -2593,11 +2597,34 @@ void WSRequestHandler::HandleGetSourcesList(WSRequestHandler* req) { auto sourceEnumProc = [](void* privateData, obs_source_t* source) -> bool { obs_data_array_t* sourcesArray = (obs_data_array_t*)privateData; - OBSDataAutoRelease sourceSettings = obs_source_get_settings(source); - OBSDataAutoRelease sourceData = obs_data_create(); obs_data_set_string(sourceData, "name", obs_source_get_name(source)); - obs_data_set_string(sourceData, "type", obs_source_get_id(source)); + obs_data_set_string(sourceData, "typeId", obs_source_get_id(source)); + + QString typeString = ""; + enum obs_source_type sourceType = obs_source_get_type(source); + switch (sourceType) { + case OBS_SOURCE_TYPE_INPUT: + typeString = "input"; + break; + + case OBS_SOURCE_TYPE_FILTER: + typeString = "filter"; + break; + + case OBS_SOURCE_TYPE_TRANSITION: + typeString = "transition"; + break; + + case OBS_SOURCE_TYPE_SCENE: + typeString = "scene"; + break; + + default: + typeString = "unknown"; + break; + } + obs_data_set_string(sourceData, "type", typeString.toUtf8()); obs_data_array_push_back(sourcesArray, sourceData); return true; @@ -2609,6 +2636,83 @@ void WSRequestHandler::HandleGetSourcesList(WSRequestHandler* req) { req->SendOKResponse(response); } +/** +* Get a list of all available sources types +* +* @return {Array of Objects} `ids` Array of sources as objects +* @return {String} `ids.*.typeId` Non-unique internal source type ID +* @return {String} `ids.*.displayName` Display name of the source type +* @return {String} `ids.*.type` Type. Value is one of the following: "input", "filter", "transition" or "other" +* @return {Object} `ids.*.defaultSettings` Default settings of this source type +* @return {Object} `ids.*.caps` Source type capabilities +* @return {Boolean} `ids.*.caps.isAsync` True if source of this type provide frames asynchronously +* @return {Boolean} `ids.*.caps.hasVideo` True if sources of this type provide video +* @return {Boolean} `ids.*.caps.hasAudio` True if sources of this type provide audio +* @return {Boolean} `ids.*.caps.canInteract` True if interaction with this sources of this type is possible +* @return {Boolean} `ids.*.caps.isComposite` True if sources of this type composite one or more sub-sources +* @return {Boolean} `ids.*.caps.doNotDuplicate` True if sources of this type should not be fully duplicated +* @return {Boolean} `ids.*.caps.doNotSelfMonitor` True if sources of this type may cause a feedback loop if it's audio is monitored and shouldn't be +* +* @api requests +* @name GetSourcesList +* @category sources +* @since unreleased +*/ +void WSRequestHandler::HandleGetSourceTypesList(WSRequestHandler* req) { + OBSDataArrayAutoRelease idsArray = obs_data_array_create(); + + const char* id; + size_t idx = 0; + + QHash idTypes; + + idx = 0; + while (obs_enum_input_types(idx++, &id)) { + idTypes.insert(id, "input"); + } + + idx = 0; + while (obs_enum_filter_types(idx++, &id)) { + idTypes.insert(id, "filter"); + } + + idx = 0; + while (obs_enum_transition_types(idx++, &id)) { + idTypes.insert(id, "transition"); + } + + idx = 0; + while (obs_enum_source_types(idx++, &id)) { + OBSDataAutoRelease item = obs_data_create(); + + obs_data_set_string(item, "typeId", id); + obs_data_set_string(item, "displayName", obs_source_get_display_name(id)); + obs_data_set_string(item, "type", idTypes.value(id, "other").toUtf8()); + + uint32_t caps = obs_get_source_output_flags(id); + OBSDataAutoRelease capsData = obs_data_create(); + obs_data_set_bool(capsData, "isAsync", caps & OBS_SOURCE_ASYNC); + obs_data_set_bool(capsData, "hasVideo", caps & OBS_SOURCE_VIDEO); + obs_data_set_bool(capsData, "hasAudio", caps & OBS_SOURCE_AUDIO); + obs_data_set_bool(capsData, "canInteract", caps & OBS_SOURCE_INTERACTION); + obs_data_set_bool(capsData, "isComposite", caps & OBS_SOURCE_COMPOSITE); + obs_data_set_bool(capsData, "doNotDuplicate", caps & OBS_SOURCE_DO_NOT_DUPLICATE); + obs_data_set_bool(capsData, "doNotSelfMonitor", caps & OBS_SOURCE_DO_NOT_SELF_MONITOR); + obs_data_set_bool(capsData, "isDeprecated", caps & OBS_SOURCE_DEPRECATED); + + obs_data_set_obj(item, "caps", capsData); + + OBSDataAutoRelease defaultSettings = obs_get_source_defaults(id); + obs_data_set_obj(item, "defaultSettings", defaultSettings); + + obs_data_array_push_back(idsArray, item); + } + + OBSDataAutoRelease response = obs_data_create(); + obs_data_set_array(response, "types", idsArray); + req->SendOKResponse(response); +} + /** * Get settings of the specified source * diff --git a/WSRequestHandler.h b/WSRequestHandler.h index 9c8f52a0..c19a2e8f 100644 --- a/WSRequestHandler.h +++ b/WSRequestHandler.h @@ -99,6 +99,7 @@ class WSRequestHandler : public QObject { static void HandleGetSyncOffset(WSRequestHandler* req); static void HandleGetSpecialSources(WSRequestHandler* req); static void HandleGetSourcesList(WSRequestHandler* req); + static void HandleGetSourceTypesList(WSRequestHandler* req); static void HandleGetSourceSettings(WSRequestHandler* req); static void HandleSetSourceSettings(WSRequestHandler* req);