diff --git a/PROTOCOL.md b/PROTOCOL.md index d02534f5..647895f1 100644 --- a/PROTOCOL.md +++ b/PROTOCOL.md @@ -86,6 +86,10 @@ The protocol in general is based on the OBS Remote protocol created by Bill Hami - ["GetCurrentScene"](#getcurrentscene) - ["GetSceneList"](#getscenelist) - ["GetSpecialSources"](#getspecialsources) + - ["GetTextGDIPlusProperties"](#gettextgdiplusproperties) + - ["SetTextGDIPlusProperties"](#settextgdiplusproperties) + - ["GetBrowserSourceProperties"](#getbrowsersourceproperties) + - ["SetBrowserSourceProperties"](#setbrowsersourceproperties) - ["SetVolume"](#setvolume) - ["GetVolume"](#getvolume) - ["SetMute"](#setmute) @@ -771,3 +775,124 @@ __Response__ : OK with the additional fields : - **"profiles"** (array of objects) : names of available profiles --- + +#### "GetTextGDIPlusProperties" +Gets current properties for Text GDI Plus source. + +__Request fields__ : +- **"source"** (string) : name of the source in the currently active scene. +- **"scene-name"** (string; optional) : name of the scene the source belongs to. defaults to current scene. + +__Response__ : OK if source exists in the current scene with these additional fields when fields are set, error otherwise. +- **"align"** (string) : "left","center","right" : text alignment +- **"bk_color"** (integer) : background color +- **"bk_opacity"** (integer) : background opacity range 0 to 100 +- **"chatlog"** (bool) : chat log +- **"chatlog_lines"** (integer) : chat log lines +- **"color"** (integer) : text color +- **"extents"** (bool) : extents +- **"extents_wrap"** (bool) : extents wrap +- **"extents_cx"** (integer) : extents cx +- **"extents_cy"** (integer) : extents cy +- **"file"** (string) : file path name +- **"read_from_file"** (bool) : read text from file specified +- **"font"** (object) : holds font data for face, flags, size and style +-- Example: "font": {"face": "Arial","flags": 0,"size": 150,"style": ""} +- **"face"** (string) : font face i.e. Arial +- **"flags"** (integer) : font text style flag i.e. Bold 1, Italic 2, Bold Italic 3, Underline 5, Strikeout 8 +- **"size"** (integer) : font text size +- **"style"** (string) : font style (unknown function) +- **"gradient"** (bool) : gradient +- **"gradient_color"** (integer) : gradient color +- **"gradient_dir"** (float) : gradient direction +- **"gradient_opacity"** (integer) : gradient opacity range 0 to 100 +- **"outline"** (bool) : outline +- **"outline_color"** (integer) : outline color +- **"outline_size"** (integer) : outline size +- **"outline_opacity"** (integer) : outline opacity range 0 to 100 +- **"text"** (string) : text to be displayed +- **"valign"** (string) : "top","center","bottom" : text vertical alignment +- **"vertical"** (bool) : vertical text +- **"render"** (bool) : visibility of the scene item + +--- + +#### "SetTextGDIPlusProperties" +Sets current properties for Text GDI Plus source. + +__Request fields__ : +- **"source"** (string) : name of the source in the currently active scene. +- **"scene-name"** (string; optional) : name of the scene the source belongs to. defaults to current scene. +- **"align"** (string; optional) : "left","center","right" : text alignment +- **"bk_color"** (integer; optional) : background color +- **"bk_opacity"** (integer; optional) : background opacity range 0 to 100 +- **"chatlog"** (bool; optional) : chat log +- **"chatlog_lines"** (integer; optional) : chat log lines +- **"color"** (integer; optional) : text color +- **"extents"** (bool; optional) : extents +- **"extents_wrap"** (bool; optional) : extents wrap +- **"extents_cx"** (integer; optional) : extents cx +- **"extents_cy"** (integer; optional) : extents cy +- **"file"** (string; optional) : file path name +- **"read_from_file"** (bool; optional) : read text from file specified +- **"font"** (object; optional) : holds font data for face, flags, size and style +-- Example: "font":{"face": "Arial","flags": 0,"size": 150,"style": ""} +- **"face"** (string; optional) : font face i.e. Arial +-- Example: "font":{"face": "Arial"} +- **"flags"** (integer; optional) : font text style flag i.e. Bold 1, Italic 2, Bold Italic 3, Underline 5, Strikeout 8 +- **"size"** (integer; optional) : font text size +-- Example: "font": {"size":125} +- **"style"** (string; optional) : font style (unknown function) +- **"gradient"** (bool; optional) : gradient +- **"gradient_color"** (integer; optional) : gradient color +- **"gradient_dir"** (float; optional) : gradient direction +- **"gradient_opacity"** (integer; optional) : gradient opacity range 0 to 100 +- **"outline"** (bool; optional) : outline +- **"outline_color"** (integer; optional) : outline color +- **"outline_size"** (integer; optional) : outline size +- **"outline_opacity"** (integer; optional) : outline opacity range 0 to 100 +- **"text"** (string; optional) : text to be displayed +- **"valign"** (string; optional) : "top","center","bottom" : text vertical alignment +- **"vertical"** (bool; optional) : vertical text +- **"render"** (bool; optional) : visibility of the scene item + +__Response__ : OK if source exists in the current scene, error otherwise. + +--- + +#### "GetBrowserSourceProperties" +Gets current properties for Browser Source. + +__Request fields__ : +- **"source"** (string) : name of the source in the currently active scene. +- **"scene-name"** (string; optional) : name of the scene the source belongs to. defaults to current scene. + +__Response__ : OK if source exists in the current scene with these additional fields when fields are set, error otherwise. + +- **"is_local_file"** (bool) : use local file +- **"url"** (string) : url or file path +- **"css"** (string) : cascading style sheet code +- **"width"** (integer) : width +- **"height"** (integer) : height +- **"fps"** (integer) : frames per second +- **"shutdown"** (bool) : shutdown when sorce is not visible +- **"render"** (bool; optional) : visibility of the scene item + +--- + +#### "SetBrowserSourceProperties" +Sets current properties for Browser Source. + +__Request fields__ : +- **"source"** (string) : name of the source in the currently active scene. +- **"scene-name"** (string; optional) : name of the scene the source belongs to. defaults to current scene. +- **"is_local_file"** (bool; optional) : use local file +- **"url"** (string; optional) : url or file path +- **"css"** (string; optional) : cascading style sheet code +- **"width"** (integer; optional) : width +- **"height"** (integer; optional) : height +- **"fps"** (integer; optional) : frames per second +- **"shutdown"** (bool; optional) : shutdown when sorce is not visible +- **"render"** (bool; optional) : visibility of the scene item + +--- \ No newline at end of file diff --git a/WSRequestHandler.cpp b/WSRequestHandler.cpp index 87cdbfa0..94c67f26 100644 --- a/WSRequestHandler.cpp +++ b/WSRequestHandler.cpp @@ -90,7 +90,10 @@ WSRequestHandler::WSRequestHandler(QWebSocket* client) : messageMap["ToggleStudioMode"] = WSRequestHandler::HandleToggleStudioMode; messageMap["SetTextGDIPlusProperties"] = WSRequestHandler::HandleSetTextGDIPlusProperties; - messageMap["GetTextGDIPlusProperties"] = WSRequestHandler::HandleGetTextGDIPlusProperties; + messageMap["GetTextGDIPlusProperties"] = WSRequestHandler::HandleGetTextGDIPlusProperties; + messageMap["GetBrowserSourceProperties"] = WSRequestHandler::HandleGetBrowserSourceProperties; + messageMap["SetBrowserSourceProperties"] = WSRequestHandler::HandleSetBrowserSourceProperties; + authNotRequired.insert("GetVersion"); authNotRequired.insert("GetAuthRequired"); authNotRequired.insert("Authenticate"); @@ -1144,7 +1147,6 @@ void WSRequestHandler::HandleGetTextGDIPlusProperties(WSRequestHandler* req) } obs_source_release(scene); - } void WSRequestHandler::HandleSetTextGDIPlusProperties(WSRequestHandler* req) @@ -1366,13 +1368,163 @@ void WSRequestHandler::HandleSetTextGDIPlusProperties(WSRequestHandler* req) { req->SendErrorResponse("not text gdi plus source"); } - } else { req->SendErrorResponse("specified scene item doesn't exist"); } - + obs_source_release(scene); +} -} \ No newline at end of file +void WSRequestHandler::HandleGetBrowserSourceProperties(WSRequestHandler* req) +{ + const char* itemName = obs_data_get_string(req->data, "source"); + if (!itemName) + { + req->SendErrorResponse("invalid request parameters"); + return; + } + + const char* sceneName = obs_data_get_string(req->data, "scene-name"); + obs_source_t* scene = Utils::GetSceneFromNameOrCurrent(sceneName); + if (!scene) { + req->SendErrorResponse("requested scene doesn't exist"); + return; + } + + obs_sceneitem_t* sceneItem = Utils::GetSceneItemFromName(scene, itemName); + if (sceneItem) + { + obs_source_t* sceneItemSource = obs_sceneitem_get_source(sceneItem); + const char* sceneItemSourceId = obs_source_get_id(sceneItemSource); + + if (strcmp(sceneItemSourceId, "browser_source") == 0) + { + obs_data_t* response = obs_source_get_settings(sceneItemSource); + obs_data_set_string(response, "source", itemName); + obs_data_set_string(response, "scene-name", sceneName); + obs_data_set_bool(response, "render", + obs_sceneitem_visible(sceneItem)); + + req->SendOKResponse(response); + + obs_data_release(response); + obs_sceneitem_release(sceneItem); + } + else + { + req->SendErrorResponse("not browser source"); + } + } + else + { + req->SendErrorResponse("specified scene item doesn't exist"); + } + obs_source_release(scene); +} + +void WSRequestHandler::HandleSetBrowserSourceProperties(WSRequestHandler* req) +{ + if (!req->hasField("source")) + { + req->SendErrorResponse("missing request parameters"); + return; + } + + const char* itemName = obs_data_get_string(req->data, "source"); + if (!itemName) + { + req->SendErrorResponse("invalid request parameters"); + return; + } + + const char* sceneName = obs_data_get_string(req->data, "scene-name"); + obs_source_t* scene = Utils::GetSceneFromNameOrCurrent(sceneName); + if (!scene) { + req->SendErrorResponse("requested scene doesn't exist"); + return; + } + + obs_sceneitem_t* sceneItem = Utils::GetSceneItemFromName(scene, itemName); + if (sceneItem) + { + obs_source_t* sceneItemSource = obs_sceneitem_get_source(sceneItem); + const char* sceneItemSourceId = obs_source_get_id(sceneItemSource); + + if (strcmp(sceneItemSourceId, "browser_source") == 0) + { + obs_data_t* settings = obs_source_get_settings(sceneItemSource); + + if (req->hasField("restart_when_active")) + { + obs_data_set_bool(settings, "restart_when_active", + obs_data_get_bool(req->data, "restart_when_active")); + } + + if (req->hasField("shutdown")) + { + obs_data_set_bool(settings, "shutdown", + obs_data_get_bool(req->data, "shutdown")); + } + + if (req->hasField("is_local_file")) + { + obs_data_set_bool(settings, "is_local_file", + obs_data_get_bool(req->data, "is_local_file")); + } + + if (req->hasField("url")) + { + obs_data_set_string(settings, "url", + obs_data_get_string(req->data, "url")); + } + + if (req->hasField("css")) + { + obs_data_set_string(settings, "css", + obs_data_get_string(req->data, "css")); + } + + if (req->hasField("width")) + { + obs_data_set_int(settings, "width", + obs_data_get_int(req->data, "width")); + } + + if (req->hasField("height")) + { + obs_data_set_int(settings, "height", + obs_data_get_int(req->data, "height")); + } + + if (req->hasField("fps")) + { + obs_data_set_int(settings, "fps", + obs_data_get_int(req->data, "fps")); + } + + obs_source_update(sceneItemSource, settings); + + if (req->hasField("render")) + { + obs_sceneitem_set_visible(sceneItem, + obs_data_get_bool(req->data, "render")); + } + + req->SendOKResponse(); + + obs_data_release(settings); + obs_sceneitem_release(sceneItem); + } + else + { + req->SendErrorResponse("not browser source"); + } + } + else + { + req->SendErrorResponse("specified scene item doesn't exist"); + } + obs_source_release(scene); +} \ No newline at end of file diff --git a/WSRequestHandler.h b/WSRequestHandler.h index f0e307a9..578f471f 100644 --- a/WSRequestHandler.h +++ b/WSRequestHandler.h @@ -102,6 +102,8 @@ class WSRequestHandler : public QObject static void HandleSetTextGDIPlusProperties(WSRequestHandler* req); static void HandleGetTextGDIPlusProperties(WSRequestHandler* req); + static void HandleSetBrowserSourceProperties(WSRequestHandler* req); + static void HandleGetBrowserSourceProperties(WSRequestHandler* req); }; #endif // WSPROTOCOL_H