mirror of
https://github.com/Palakis/obs-websocket.git
synced 2024-08-30 18:12:16 +00:00
code: reorder and refactor WSRequestHandlers
This commit is contained in:
@ -26,6 +26,7 @@ set(obs-websocket_SOURCES
|
|||||||
src/WSRequestHandler_ReplayBuffer.cpp
|
src/WSRequestHandler_ReplayBuffer.cpp
|
||||||
src/WSRequestHandler_SceneCollections.cpp
|
src/WSRequestHandler_SceneCollections.cpp
|
||||||
src/WSRequestHandler_Scenes.cpp
|
src/WSRequestHandler_Scenes.cpp
|
||||||
|
src/WSRequestHandler_SceneItems.cpp
|
||||||
src/WSRequestHandler_Sources.cpp
|
src/WSRequestHandler_Sources.cpp
|
||||||
src/WSRequestHandler_Streaming.cpp
|
src/WSRequestHandler_Streaming.cpp
|
||||||
src/WSRequestHandler_StudioMode.cpp
|
src/WSRequestHandler_StudioMode.cpp
|
||||||
|
@ -35,7 +35,7 @@ const char* qstring_data_copy(QString value) {
|
|||||||
return constStringData;
|
return constStringData;
|
||||||
}
|
}
|
||||||
|
|
||||||
obs_data_array_t* stringListToArray(char** strings, char* key) {
|
obs_data_array_t* Utils::StringListToArray(char** strings, char* key) {
|
||||||
if (!strings)
|
if (!strings)
|
||||||
return obs_data_array_create();
|
return obs_data_array_create();
|
||||||
|
|
||||||
@ -222,22 +222,6 @@ obs_data_t* Utils::GetSceneData(obs_source_t* source) {
|
|||||||
return sceneData;
|
return sceneData;
|
||||||
}
|
}
|
||||||
|
|
||||||
obs_data_array_t* Utils::GetSceneCollections() {
|
|
||||||
char** sceneCollections = obs_frontend_get_scene_collections();
|
|
||||||
obs_data_array_t* list = stringListToArray(sceneCollections, "sc-name");
|
|
||||||
|
|
||||||
bfree(sceneCollections);
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
obs_data_array_t* Utils::GetProfiles() {
|
|
||||||
char** profiles = obs_frontend_get_profiles();
|
|
||||||
obs_data_array_t* list = stringListToArray(profiles, "profile-name");
|
|
||||||
|
|
||||||
bfree(profiles);
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
QSpinBox* Utils::GetTransitionDurationControl() {
|
QSpinBox* Utils::GetTransitionDurationControl() {
|
||||||
QMainWindow* window = (QMainWindow*)obs_frontend_get_main_window();
|
QMainWindow* window = (QMainWindow*)obs_frontend_get_main_window();
|
||||||
return window->findChild<QSpinBox*>("transitionDuration");
|
return window->findChild<QSpinBox*>("transitionDuration");
|
||||||
@ -315,7 +299,7 @@ void Utils::TransitionToProgram() {
|
|||||||
transitionBtn->click();
|
transitionBtn->click();
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* Utils::OBSVersionString() {
|
QString Utils::OBSVersionString() {
|
||||||
uint32_t version = obs_get_version();
|
uint32_t version = obs_get_version();
|
||||||
|
|
||||||
uint8_t major, minor, patch;
|
uint8_t major, minor, patch;
|
||||||
@ -323,8 +307,8 @@ const char* Utils::OBSVersionString() {
|
|||||||
minor = (version >> 16) & 0xFF;
|
minor = (version >> 16) & 0xFF;
|
||||||
patch = version & 0xFF;
|
patch = version & 0xFF;
|
||||||
|
|
||||||
char* result = (char*)bmalloc(sizeof(char) * 12);
|
QString result = QString("%1.%2.%3")
|
||||||
sprintf(result, "%d.%d.%d", major, minor, patch);
|
.arg(major).arg(minor).arg(patch);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,7 @@ const char* qstring_data_copy(QString value);
|
|||||||
|
|
||||||
class Utils {
|
class Utils {
|
||||||
public:
|
public:
|
||||||
|
static obs_data_array_t* StringListToArray(char** strings, char* key);
|
||||||
static obs_data_array_t* GetSceneItems(obs_source_t* source);
|
static obs_data_array_t* GetSceneItems(obs_source_t* source);
|
||||||
static obs_data_t* GetSceneItemData(obs_sceneitem_t* item);
|
static obs_data_t* GetSceneItemData(obs_sceneitem_t* item);
|
||||||
static obs_sceneitem_t* GetSceneItemFromName(
|
static obs_sceneitem_t* GetSceneItemFromName(
|
||||||
@ -48,7 +49,6 @@ class Utils {
|
|||||||
static obs_data_array_t* GetScenes();
|
static obs_data_array_t* GetScenes();
|
||||||
static obs_data_t* GetSceneData(obs_source_t* source);
|
static obs_data_t* GetSceneData(obs_source_t* source);
|
||||||
|
|
||||||
static obs_data_array_t* GetSceneCollections();
|
|
||||||
static obs_data_array_t* GetProfiles();
|
static obs_data_array_t* GetProfiles();
|
||||||
|
|
||||||
static QSpinBox* GetTransitionDurationControl();
|
static QSpinBox* GetTransitionDurationControl();
|
||||||
@ -64,7 +64,7 @@ class Utils {
|
|||||||
|
|
||||||
static void TransitionToProgram();
|
static void TransitionToProgram();
|
||||||
|
|
||||||
static const char* OBSVersionString();
|
static QString OBSVersionString();
|
||||||
|
|
||||||
static QSystemTrayIcon* GetTrayIcon();
|
static QSystemTrayIcon* GetTrayIcon();
|
||||||
static void SysTrayNotify(
|
static void SysTrayNotify(
|
||||||
@ -73,6 +73,7 @@ class Utils {
|
|||||||
QString title = QString("obs-websocket"));
|
QString title = QString("obs-websocket"));
|
||||||
|
|
||||||
static QString FormatIPAddress(QHostAddress &addr);
|
static QString FormatIPAddress(QHostAddress &addr);
|
||||||
|
|
||||||
static const char* GetRecordingFolder();
|
static const char* GetRecordingFolder();
|
||||||
static bool SetRecordingFolder(const char* path);
|
static bool SetRecordingFolder(const char* path);
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
* @return {double} `version` OBSRemote compatible API version. Fixed to 1.1 for retrocompatibility.
|
* @return {double} `version` OBSRemote compatible API version. Fixed to 1.1 for retrocompatibility.
|
||||||
* @return {String} `obs-websocket-version` obs-websocket plugin version.
|
* @return {String} `obs-websocket-version` obs-websocket plugin version.
|
||||||
* @return {String} `obs-studio-version` OBS Studio program version.
|
* @return {String} `obs-studio-version` OBS Studio program version.
|
||||||
* @return {String|Array} `available-requests` List of available request types.
|
* @return {String} `available-requests` List of available request types, formatted as a comma-separated list string (e.g. : "Method1,Method2,Method3").
|
||||||
*
|
*
|
||||||
* @api requests
|
* @api requests
|
||||||
* @name GetVersion
|
* @name GetVersion
|
||||||
@ -109,6 +109,7 @@ void WSRequestHandler::HandleAuthenticate(WSRequestHandler* req) {
|
|||||||
* @api requests
|
* @api requests
|
||||||
* @name SetHeartbeat
|
* @name SetHeartbeat
|
||||||
* @category general
|
* @category general
|
||||||
|
* @since unreleased
|
||||||
*/
|
*/
|
||||||
void WSRequestHandler::HandleSetHeartbeat(WSRequestHandler* req) {
|
void WSRequestHandler::HandleSetHeartbeat(WSRequestHandler* req) {
|
||||||
if (!req->hasField("enable")) {
|
if (!req->hasField("enable")) {
|
||||||
|
@ -58,10 +58,13 @@ void WSRequestHandler::HandleGetCurrentProfile(WSRequestHandler* req) {
|
|||||||
* @since 4.0.0
|
* @since 4.0.0
|
||||||
*/
|
*/
|
||||||
void WSRequestHandler::HandleListProfiles(WSRequestHandler* req) {
|
void WSRequestHandler::HandleListProfiles(WSRequestHandler* req) {
|
||||||
OBSDataArrayAutoRelease profiles = Utils::GetProfiles();
|
char** profiles = obs_frontend_get_profiles();
|
||||||
|
OBSDataArrayAutoRelease list =
|
||||||
|
Utils::StringListToArray(profiles, "profile-name");
|
||||||
|
bfree(profiles);
|
||||||
|
|
||||||
OBSDataAutoRelease response = obs_data_create();
|
OBSDataAutoRelease response = obs_data_create();
|
||||||
obs_data_set_array(response, "profiles", profiles);
|
obs_data_set_array(response, "profiles", list);
|
||||||
|
|
||||||
req->SendOKResponse(response);
|
req->SendOKResponse(response);
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,7 @@ void WSRequestHandler::HandleStopReplayBuffer(WSRequestHandler* req) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save and flush the contents of the Replay Buffer to disk. This is
|
* Flush and save the contents of the Replay Buffer to disk. This is
|
||||||
* basically the same as triggering the "Save Replay Buffer" hotkey.
|
* basically the same as triggering the "Save Replay Buffer" hotkey.
|
||||||
* Will return an `error` if the Replay Buffer is not active.
|
* Will return an `error` if the Replay Buffer is not active.
|
||||||
*
|
*
|
||||||
|
@ -47,11 +47,25 @@ void WSRequestHandler::HandleGetCurrentSceneCollection(WSRequestHandler* req) {
|
|||||||
req->SendOKResponse(response);
|
req->SendOKResponse(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List available scene collections
|
||||||
|
*
|
||||||
|
* @return {Object|Array} `scene-collections` Scene collections list
|
||||||
|
* @return {String} `scene-collections.*.`
|
||||||
|
*
|
||||||
|
* @api requests
|
||||||
|
* @name ListSceneCollections
|
||||||
|
* @category scene collections
|
||||||
|
* @since 4.0.0
|
||||||
|
*/
|
||||||
void WSRequestHandler::HandleListSceneCollections(WSRequestHandler* req) {
|
void WSRequestHandler::HandleListSceneCollections(WSRequestHandler* req) {
|
||||||
OBSDataArrayAutoRelease sceneCollections = Utils::GetSceneCollections();
|
char** sceneCollections = obs_frontend_get_scene_collections();
|
||||||
|
OBSDataArrayAutoRelease list =
|
||||||
|
Utils::StringListToArray(sceneCollections, "sc-name");
|
||||||
|
bfree(sceneCollections);
|
||||||
|
|
||||||
OBSDataAutoRelease response = obs_data_create();
|
OBSDataAutoRelease response = obs_data_create();
|
||||||
obs_data_set_array(response, "scene-collections", sceneCollections);
|
obs_data_set_array(response, "scene-collections", list);
|
||||||
|
|
||||||
req->SendOKResponse(response);
|
req->SendOKResponse(response);
|
||||||
}
|
}
|
||||||
|
568
src/WSRequestHandler_SceneItems.cpp
Normal file
568
src/WSRequestHandler_SceneItems.cpp
Normal file
@ -0,0 +1,568 @@
|
|||||||
|
#include <QString>
|
||||||
|
#include "Utils.h"
|
||||||
|
|
||||||
|
#include "WSRequestHandler.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the scene specific properties of the specified source item.
|
||||||
|
*
|
||||||
|
* @param {String (optional)} `scene-name` the name of the scene that the source item belongs to. Defaults to the current scene.
|
||||||
|
* @param {String} `item` The name of the source.
|
||||||
|
*
|
||||||
|
* @return {String} `name` The name of the source.
|
||||||
|
* @return {int} `position.x` The x position of the source from the left.
|
||||||
|
* @return {int} `position.y` The y position of the source from the top.
|
||||||
|
* @return {int} `position.alignment` The point on the source that the item is manipulated from.
|
||||||
|
* @return {double} `rotation` The clockwise rotation of the item in degrees around the point of alignment.
|
||||||
|
* @return {double} `scale.x` The x-scale factor of the source.
|
||||||
|
* @return {double} `scale.y` The y-scale factor of the source.
|
||||||
|
* @return {int} `crop.top` The number of pixels cropped off the top of the source before scaling.
|
||||||
|
* @return {int} `crop.right` The number of pixels cropped off the right of the source before scaling.
|
||||||
|
* @return {int} `crop.bottom` The number of pixels cropped off the bottom of the source before scaling.
|
||||||
|
* @return {int} `crop.left` The number of pixels cropped off the left of the source before scaling.
|
||||||
|
* @return {bool} `visible` If the source is visible.
|
||||||
|
* @return {String} `bounds.type` Type of bounding box.
|
||||||
|
* @return {int} `bounds.alignment` Alignment of the bounding box.
|
||||||
|
* @return {double} `bounds.x` Width of the bounding box.
|
||||||
|
* @return {double} `bounds.y` Height of the bounding box.
|
||||||
|
*
|
||||||
|
* @api requests
|
||||||
|
* @name GetSceneItemProperties
|
||||||
|
* @category scene items
|
||||||
|
* @since unreleased
|
||||||
|
*/
|
||||||
|
void WSRequestHandler::HandleGetSceneItemProperties(WSRequestHandler* req) {
|
||||||
|
if (!req->hasField("item")) {
|
||||||
|
req->SendErrorResponse("missing request parameters");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString itemName = obs_data_get_string(req->data, "item");
|
||||||
|
if (itemName.isEmpty()) {
|
||||||
|
req->SendErrorResponse("invalid request parameters");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString sceneName = obs_data_get_string(req->data, "scene-name");
|
||||||
|
OBSSourceAutoRelease scene = Utils::GetSceneFromNameOrCurrent(sceneName);
|
||||||
|
if (!scene) {
|
||||||
|
req->SendErrorResponse("requested scene doesn't exist");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
OBSSceneItemAutoRelease sceneItem =
|
||||||
|
Utils::GetSceneItemFromName(scene, itemName);
|
||||||
|
if (!sceneItem) {
|
||||||
|
req->SendErrorResponse("specified scene item doesn't exist");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
OBSDataAutoRelease data = obs_data_create();
|
||||||
|
obs_data_set_string(data, "name", itemName.toUtf8());
|
||||||
|
|
||||||
|
OBSDataAutoRelease posData = obs_data_create();
|
||||||
|
vec2 pos;
|
||||||
|
obs_sceneitem_get_pos(sceneItem, &pos);
|
||||||
|
obs_data_set_double(posData, "x", pos.x);
|
||||||
|
obs_data_set_double(posData, "y", pos.y);
|
||||||
|
obs_data_set_int(posData, "alignment", obs_sceneitem_get_alignment(sceneItem));
|
||||||
|
obs_data_set_obj(data, "position", posData);
|
||||||
|
|
||||||
|
obs_data_set_double(data, "rotation", obs_sceneitem_get_rot(sceneItem));
|
||||||
|
|
||||||
|
OBSDataAutoRelease scaleData = obs_data_create();
|
||||||
|
vec2 scale;
|
||||||
|
obs_sceneitem_get_scale(sceneItem, &scale);
|
||||||
|
obs_data_set_double(scaleData, "x", scale.x);
|
||||||
|
obs_data_set_double(scaleData, "y", scale.y);
|
||||||
|
obs_data_set_obj(data, "scale", scaleData);
|
||||||
|
|
||||||
|
OBSDataAutoRelease cropData = obs_data_create();
|
||||||
|
obs_sceneitem_crop crop;
|
||||||
|
obs_sceneitem_get_crop(sceneItem, &crop);
|
||||||
|
obs_data_set_int(cropData, "left", crop.left);
|
||||||
|
obs_data_set_int(cropData, "top", crop.top);
|
||||||
|
obs_data_set_int(cropData, "right", crop.right);
|
||||||
|
obs_data_set_int(cropData, "bottom", crop.bottom);
|
||||||
|
obs_data_set_obj(data, "crop", cropData);
|
||||||
|
|
||||||
|
obs_data_set_bool(data, "visible", obs_sceneitem_visible(sceneItem));
|
||||||
|
|
||||||
|
OBSDataAutoRelease boundsData = obs_data_create();
|
||||||
|
obs_bounds_type boundsType = obs_sceneitem_get_bounds_type(sceneItem);
|
||||||
|
if (boundsType == OBS_BOUNDS_NONE) {
|
||||||
|
obs_data_set_string(boundsData, "type", "OBS_BOUNDS_NONE");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
switch (boundsType) {
|
||||||
|
case OBS_BOUNDS_STRETCH: {
|
||||||
|
obs_data_set_string(boundsData, "type", "OBS_BOUNDS_STRETCH");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case OBS_BOUNDS_SCALE_INNER: {
|
||||||
|
obs_data_set_string(boundsData, "type", "OBS_BOUNDS_SCALE_INNER");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case OBS_BOUNDS_SCALE_OUTER: {
|
||||||
|
obs_data_set_string(boundsData, "type", "OBS_BOUNDS_SCALE_OUTER");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case OBS_BOUNDS_SCALE_TO_WIDTH: {
|
||||||
|
obs_data_set_string(boundsData, "type", "OBS_BOUNDS_SCALE_TO_WIDTH");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case OBS_BOUNDS_SCALE_TO_HEIGHT: {
|
||||||
|
obs_data_set_string(boundsData, "type", "OBS_BOUNDS_SCALE_TO_HEIGHT");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case OBS_BOUNDS_MAX_ONLY: {
|
||||||
|
obs_data_set_string(boundsData, "type", "OBS_BOUNDS_MAX_ONLY");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
obs_data_set_int(boundsData, "alignment", obs_sceneitem_get_bounds_alignment(sceneItem));
|
||||||
|
vec2 bounds;
|
||||||
|
obs_sceneitem_get_bounds(sceneItem, &bounds);
|
||||||
|
obs_data_set_double(boundsData, "x", bounds.x);
|
||||||
|
obs_data_set_double(boundsData, "y", bounds.y);
|
||||||
|
}
|
||||||
|
obs_data_set_obj(data, "bounds", boundsData);
|
||||||
|
|
||||||
|
req->SendOKResponse(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the scene specific properties of a source. Unspecified properties will remain unchanged.
|
||||||
|
*
|
||||||
|
* @param {String (optional)} `scene-name` the name of the scene that the source item belongs to. Defaults to the current scene.
|
||||||
|
* @param {String} `item` The name of the source.
|
||||||
|
* @param {int} `position.x` The new x position of the source.
|
||||||
|
* @param {int} `position.y` The new y position of the source.
|
||||||
|
* @param {int} `position.alignment` The new alignment of the source.
|
||||||
|
* @param {double} `rotation` The new clockwise rotation of the item in degrees.
|
||||||
|
* @param {double} `scale.x` The new x scale of the item.
|
||||||
|
* @param {double} `scale.y` The new y scale of the item.
|
||||||
|
* @param {int} `crop.top` The new amount of pixels cropped off the top of the source before scaling.
|
||||||
|
* @param {int} `crop.bottom` The new amount of pixels cropped off the bottom of the source before scaling.
|
||||||
|
* @param {int} `crop.left` The new amount of pixels cropped off the left of the source before scaling.
|
||||||
|
* @param {int} `crop.right` The new amount of pixels cropped off the right of the source before scaling.
|
||||||
|
* @param {bool} `visible` The new visibility of the source. 'true' shows source, 'false' hides source.
|
||||||
|
* @param {String} `bounds.type` The new bounds type of the source.
|
||||||
|
* @param {int} `bounds.alignment` The new alignment of the bounding box. (0-2, 4-6, 8-10)
|
||||||
|
* @param {double} `bounds.x` The new width of the bounding box.
|
||||||
|
* @param {double} `bounds.y` The new height of the bounding box.
|
||||||
|
*
|
||||||
|
* @api requests
|
||||||
|
* @name SetSceneItemProperties
|
||||||
|
* @category scene items
|
||||||
|
* @since unreleased
|
||||||
|
*/
|
||||||
|
void WSRequestHandler::HandleSetSceneItemProperties(WSRequestHandler* req) {
|
||||||
|
if (!req->hasField("item")) {
|
||||||
|
req->SendErrorResponse("missing request parameters");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString itemName = obs_data_get_string(req->data, "item");
|
||||||
|
if (itemName.isEmpty()) {
|
||||||
|
req->SendErrorResponse("invalid request parameters");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString sceneName = obs_data_get_string(req->data, "scene-name");
|
||||||
|
OBSSourceAutoRelease scene = Utils::GetSceneFromNameOrCurrent(sceneName);
|
||||||
|
if (!scene) {
|
||||||
|
req->SendErrorResponse("requested scene doesn't exist");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
OBSSceneItemAutoRelease sceneItem =
|
||||||
|
Utils::GetSceneItemFromName(scene, itemName);
|
||||||
|
if (!sceneItem) {
|
||||||
|
req->SendErrorResponse("specified scene item doesn't exist");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool badRequest = false;
|
||||||
|
OBSDataAutoRelease errorMessage = obs_data_create();
|
||||||
|
|
||||||
|
if (req->hasField("position")) {
|
||||||
|
vec2 oldPosition;
|
||||||
|
OBSDataAutoRelease positionError = obs_data_create();
|
||||||
|
obs_sceneitem_get_pos(sceneItem, &oldPosition);
|
||||||
|
OBSDataAutoRelease reqPosition = obs_data_get_obj(req->data, "position");
|
||||||
|
vec2 newPosition = oldPosition;
|
||||||
|
if (obs_data_has_user_value(reqPosition, "x")) {
|
||||||
|
newPosition.x = obs_data_get_int(reqPosition, "x");
|
||||||
|
}
|
||||||
|
if (obs_data_has_user_value(reqPosition, "y")) {
|
||||||
|
newPosition.y = obs_data_get_int(reqPosition, "y");
|
||||||
|
}
|
||||||
|
if (obs_data_has_user_value(reqPosition, "alignment")) {
|
||||||
|
const uint32_t alignment = obs_data_get_int(reqPosition, "alignment");
|
||||||
|
if (Utils::IsValidAlignment(alignment)) {
|
||||||
|
obs_sceneitem_set_alignment(sceneItem, alignment);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
badRequest = true;
|
||||||
|
obs_data_set_string(positionError, "alignment", "invalid");
|
||||||
|
obs_data_set_obj(errorMessage, "position", positionError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
obs_sceneitem_set_pos(sceneItem, &newPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (req->hasField("rotation")) {
|
||||||
|
obs_sceneitem_set_rot(sceneItem, (float)obs_data_get_double(req->data, "rotation"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (req->hasField("scale")) {
|
||||||
|
vec2 oldScale;
|
||||||
|
obs_sceneitem_get_scale(sceneItem, &oldScale);
|
||||||
|
OBSDataAutoRelease reqScale = obs_data_get_obj(req->data, "scale");
|
||||||
|
vec2 newScale = oldScale;
|
||||||
|
if (obs_data_has_user_value(reqScale, "x")) {
|
||||||
|
newScale.x = obs_data_get_double(reqScale, "x");
|
||||||
|
}
|
||||||
|
if (obs_data_has_user_value(reqScale, "y")) {
|
||||||
|
newScale.y = obs_data_get_double(reqScale, "y");
|
||||||
|
}
|
||||||
|
obs_sceneitem_set_scale(sceneItem, &newScale);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (req->hasField("crop")) {
|
||||||
|
obs_sceneitem_crop oldCrop;
|
||||||
|
obs_sceneitem_get_crop(sceneItem, &oldCrop);
|
||||||
|
OBSDataAutoRelease reqCrop = obs_data_get_obj(req->data, "crop");
|
||||||
|
obs_sceneitem_crop newCrop = oldCrop;
|
||||||
|
if (obs_data_has_user_value(reqCrop, "top")) {
|
||||||
|
newCrop.top = obs_data_get_int(reqCrop, "top");
|
||||||
|
}
|
||||||
|
if (obs_data_has_user_value(reqCrop, "right")) {
|
||||||
|
newCrop.right = obs_data_get_int(reqCrop, "right");
|
||||||
|
}
|
||||||
|
if (obs_data_has_user_value(reqCrop, "bottom")) {
|
||||||
|
newCrop.bottom = obs_data_get_int(reqCrop, "bottom");
|
||||||
|
}
|
||||||
|
if (obs_data_has_user_value(reqCrop, "left")) {
|
||||||
|
newCrop.left = obs_data_get_int(reqCrop, "left");
|
||||||
|
}
|
||||||
|
obs_sceneitem_set_crop(sceneItem, &newCrop);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (req->hasField("visible")) {
|
||||||
|
obs_sceneitem_set_visible(sceneItem, obs_data_get_bool(req->data, "visible"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (req->hasField("bounds")) {
|
||||||
|
bool badBounds = false;
|
||||||
|
OBSDataAutoRelease boundsError = obs_data_create();
|
||||||
|
OBSDataAutoRelease reqBounds = obs_data_get_obj(req->data, "bounds");
|
||||||
|
if (obs_data_has_user_value(reqBounds, "type")) {
|
||||||
|
const char* newBoundsType = obs_data_get_string(reqBounds, "type");
|
||||||
|
if (newBoundsType == "OBS_BOUNDS_NONE") {
|
||||||
|
obs_sceneitem_set_bounds_type(sceneItem, OBS_BOUNDS_NONE);
|
||||||
|
}
|
||||||
|
else if (newBoundsType == "OBS_BOUNDS_STRETCH") {
|
||||||
|
obs_sceneitem_set_bounds_type(sceneItem, OBS_BOUNDS_STRETCH);
|
||||||
|
}
|
||||||
|
else if (newBoundsType == "OBS_BOUNDS_SCALE_INNER") {
|
||||||
|
obs_sceneitem_set_bounds_type(sceneItem, OBS_BOUNDS_SCALE_INNER);
|
||||||
|
}
|
||||||
|
else if (newBoundsType == "OBS_BOUNDS_SCALE_OUTER") {
|
||||||
|
obs_sceneitem_set_bounds_type(sceneItem, OBS_BOUNDS_SCALE_OUTER);
|
||||||
|
}
|
||||||
|
else if (newBoundsType == "OBS_BOUNDS_SCALE_TO_WIDTH") {
|
||||||
|
obs_sceneitem_set_bounds_type(sceneItem, OBS_BOUNDS_SCALE_TO_WIDTH);
|
||||||
|
}
|
||||||
|
else if (newBoundsType == "OBS_BOUNDS_SCALE_TO_HEIGHT") {
|
||||||
|
obs_sceneitem_set_bounds_type(sceneItem, OBS_BOUNDS_SCALE_TO_HEIGHT);
|
||||||
|
}
|
||||||
|
else if (newBoundsType == "OBS_BOUNDS_MAX_ONLY") {
|
||||||
|
obs_sceneitem_set_bounds_type(sceneItem, OBS_BOUNDS_MAX_ONLY);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
badRequest = badBounds = true;
|
||||||
|
obs_data_set_string(boundsError, "type", "invalid");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vec2 oldBounds;
|
||||||
|
obs_sceneitem_get_bounds(sceneItem, &oldBounds);
|
||||||
|
vec2 newBounds = oldBounds;
|
||||||
|
if (obs_data_has_user_value(reqBounds, "x")) {
|
||||||
|
newBounds.x = obs_data_get_double(reqBounds, "x");
|
||||||
|
}
|
||||||
|
if (obs_data_has_user_value(reqBounds, "y")) {
|
||||||
|
newBounds.y = obs_data_get_double(reqBounds, "y");
|
||||||
|
}
|
||||||
|
obs_sceneitem_set_bounds(sceneItem, &newBounds);
|
||||||
|
if (obs_data_has_user_value(reqBounds, "alignment")) {
|
||||||
|
const uint32_t bounds_alignment = obs_data_get_int(reqBounds, "alignment");
|
||||||
|
if (Utils::IsValidAlignment(bounds_alignment)) {
|
||||||
|
obs_sceneitem_set_bounds_alignment(sceneItem, bounds_alignment);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
badRequest = badBounds = true;
|
||||||
|
obs_data_set_string(boundsError, "alignment", "invalid");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (badBounds) {
|
||||||
|
obs_data_set_obj(errorMessage, "bounds", boundsError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (badRequest) {
|
||||||
|
req->SendErrorResponse(errorMessage);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
req->SendOKResponse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset a scene item.
|
||||||
|
*
|
||||||
|
* @param {String (optional)} `scene-name` Name of the scene the source belogns to. Defaults to the current scene.
|
||||||
|
* @param {String} `item` Name of the source item.
|
||||||
|
*
|
||||||
|
* @api requests
|
||||||
|
* @name ResetSceneItem
|
||||||
|
* @category scene items
|
||||||
|
* @since 4.2.0
|
||||||
|
*/
|
||||||
|
void WSRequestHandler::HandleResetSceneItem(WSRequestHandler* req) {
|
||||||
|
// TODO: remove this request, or refactor it to ResetSource
|
||||||
|
|
||||||
|
if (!req->hasField("item")) {
|
||||||
|
req->SendErrorResponse("missing request parameters");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* itemName = obs_data_get_string(req->data, "item");
|
||||||
|
if (!itemName) {
|
||||||
|
req->SendErrorResponse("invalid request parameters");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* sceneName = obs_data_get_string(req->data, "scene-name");
|
||||||
|
OBSSourceAutoRelease scene = Utils::GetSceneFromNameOrCurrent(sceneName);
|
||||||
|
if (!scene) {
|
||||||
|
req->SendErrorResponse("requested scene doesn't exist");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
OBSSceneItemAutoRelease sceneItem = Utils::GetSceneItemFromName(scene, itemName);
|
||||||
|
if (sceneItem) {
|
||||||
|
OBSSource sceneItemSource = obs_sceneitem_get_source(sceneItem);
|
||||||
|
|
||||||
|
OBSDataAutoRelease settings = obs_source_get_settings(sceneItemSource);
|
||||||
|
obs_source_update(sceneItemSource, settings);
|
||||||
|
|
||||||
|
req->SendOKResponse();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
req->SendErrorResponse("specified scene item doesn't exist");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show or hide a specified source item in a specified scene.
|
||||||
|
*
|
||||||
|
* @param {String} `source` Scene item name in the specified scene.
|
||||||
|
* @param {boolean} `render` true = shown ; false = hidden
|
||||||
|
* @param {String (optional)} `scene-name` Name of the scene where the source resides. Defaults to the currently active scene.
|
||||||
|
*
|
||||||
|
* @api requests
|
||||||
|
* @name SetSceneItemRender
|
||||||
|
* @category scene items
|
||||||
|
* @since 0.3
|
||||||
|
* @deprecated Since unreleased. Prefer the use of SetSceneItemProperties.
|
||||||
|
*/
|
||||||
|
void WSRequestHandler::HandleSetSceneItemRender(WSRequestHandler* req) {
|
||||||
|
if (!req->hasField("source") ||
|
||||||
|
!req->hasField("render"))
|
||||||
|
{
|
||||||
|
req->SendErrorResponse("missing request parameters");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* itemName = obs_data_get_string(req->data, "source");
|
||||||
|
bool isVisible = obs_data_get_bool(req->data, "render");
|
||||||
|
|
||||||
|
if (!itemName) {
|
||||||
|
req->SendErrorResponse("invalid request parameters");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* sceneName = obs_data_get_string(req->data, "scene-name");
|
||||||
|
OBSSourceAutoRelease scene = Utils::GetSceneFromNameOrCurrent(sceneName);
|
||||||
|
if (!scene) {
|
||||||
|
req->SendErrorResponse("requested scene doesn't exist");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
OBSSceneItemAutoRelease sceneItem =
|
||||||
|
Utils::GetSceneItemFromName(scene, itemName);
|
||||||
|
if (sceneItem) {
|
||||||
|
obs_sceneitem_set_visible(sceneItem, isVisible);
|
||||||
|
req->SendOKResponse();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
req->SendErrorResponse("specified scene item doesn't exist");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the coordinates of a specified source item.
|
||||||
|
*
|
||||||
|
* @param {String (optional)} `scene-name` The name of the scene that the source item belongs to. Defaults to the current scene.
|
||||||
|
* @param {String} `item` The name of the source item.
|
||||||
|
* @param {double} `x` X coordinate.
|
||||||
|
* @param {double} `y` Y coordinate.
|
||||||
|
|
||||||
|
*
|
||||||
|
* @api requests
|
||||||
|
* @name SetSceneItemPosition
|
||||||
|
* @category scene items
|
||||||
|
* @since 4.0.0
|
||||||
|
* @deprecated Since unreleased. Prefer the use of SetSceneItemProperties.
|
||||||
|
*/
|
||||||
|
void WSRequestHandler::HandleSetSceneItemPosition(WSRequestHandler* req) {
|
||||||
|
if (!req->hasField("item") ||
|
||||||
|
!req->hasField("x") || !req->hasField("y")) {
|
||||||
|
req->SendErrorResponse("missing request parameters");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString itemName = obs_data_get_string(req->data, "item");
|
||||||
|
if (itemName.isEmpty()) {
|
||||||
|
req->SendErrorResponse("invalid request parameters");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString sceneName = obs_data_get_string(req->data, "scene-name");
|
||||||
|
OBSSourceAutoRelease scene = Utils::GetSceneFromNameOrCurrent(sceneName);
|
||||||
|
if (!scene) {
|
||||||
|
req->SendErrorResponse("requested scene could not be found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
OBSSceneItem sceneItem = Utils::GetSceneItemFromName(scene, itemName);
|
||||||
|
if (sceneItem) {
|
||||||
|
vec2 item_position = { 0 };
|
||||||
|
item_position.x = obs_data_get_double(req->data, "x");
|
||||||
|
item_position.y = obs_data_get_double(req->data, "y");
|
||||||
|
obs_sceneitem_set_pos(sceneItem, &item_position);
|
||||||
|
|
||||||
|
req->SendOKResponse();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
req->SendErrorResponse("specified scene item doesn't exist");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the transform of the specified source item.
|
||||||
|
*
|
||||||
|
* @param {String (optional)} `scene-name` The name of the scene that the source item belongs to. Defaults to the current scene.
|
||||||
|
* @param {String} `item` The name of the source item.
|
||||||
|
* @param {double} `x-scale` Width scale factor.
|
||||||
|
* @param {double} `y-scale` Height scale factor.
|
||||||
|
* @param {double} `rotation` Source item rotation (in degrees).
|
||||||
|
*
|
||||||
|
* @api requests
|
||||||
|
* @name SetSceneItemTransform
|
||||||
|
* @category scene items
|
||||||
|
* @since 4.0.0
|
||||||
|
* @deprecated Since unreleased. Prefer the use of SetSceneItemProperties.
|
||||||
|
*/
|
||||||
|
void WSRequestHandler::HandleSetSceneItemTransform(WSRequestHandler* req) {
|
||||||
|
if (!req->hasField("item") ||
|
||||||
|
!req->hasField("x-scale") ||
|
||||||
|
!req->hasField("y-scale") ||
|
||||||
|
!req->hasField("rotation"))
|
||||||
|
{
|
||||||
|
req->SendErrorResponse("missing request parameters");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString itemName = obs_data_get_string(req->data, "item");
|
||||||
|
if (itemName.isEmpty()) {
|
||||||
|
req->SendErrorResponse("invalid request parameters");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString sceneName = obs_data_get_string(req->data, "scene-name");
|
||||||
|
OBSSourceAutoRelease scene = Utils::GetSceneFromNameOrCurrent(sceneName);
|
||||||
|
if (!scene) {
|
||||||
|
req->SendErrorResponse("requested scene doesn't exist");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 scale;
|
||||||
|
scale.x = obs_data_get_double(req->data, "x-scale");
|
||||||
|
scale.y = obs_data_get_double(req->data, "y-scale");
|
||||||
|
float rotation = obs_data_get_double(req->data, "rotation");
|
||||||
|
|
||||||
|
OBSSceneItemAutoRelease sceneItem = Utils::GetSceneItemFromName(scene, itemName);
|
||||||
|
if (sceneItem) {
|
||||||
|
obs_sceneitem_set_scale(sceneItem, &scale);
|
||||||
|
obs_sceneitem_set_rot(sceneItem, rotation);
|
||||||
|
req->SendOKResponse();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
req->SendErrorResponse("specified scene item doesn't exist");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the crop coordinates of the specified source item.
|
||||||
|
*
|
||||||
|
* @param {String (optional)} `scene-name` the name of the scene that the source item belongs to. Defaults to the current scene.
|
||||||
|
* @param {String} `item` The name of the source.
|
||||||
|
* @param {int} `top` Pixel position of the top of the source item.
|
||||||
|
* @param {int} `bottom` Pixel position of the bottom of the source item.
|
||||||
|
* @param {int} `left` Pixel position of the left of the source item.
|
||||||
|
* @param {int} `right` Pixel position of the right of the source item.
|
||||||
|
*
|
||||||
|
* @api requests
|
||||||
|
* @name SetSceneItemCrop
|
||||||
|
* @category scene items
|
||||||
|
* @since 4.1.0
|
||||||
|
* @deprecated Since unreleased. Prefer the use of SetSceneItemProperties.
|
||||||
|
*/
|
||||||
|
void WSRequestHandler::HandleSetSceneItemCrop(WSRequestHandler* req) {
|
||||||
|
if (!req->hasField("item")) {
|
||||||
|
req->SendErrorResponse("missing request parameters");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString itemName = obs_data_get_string(req->data, "item");
|
||||||
|
if (itemName.isEmpty()) {
|
||||||
|
req->SendErrorResponse("invalid request parameters");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString sceneName = obs_data_get_string(req->data, "scene-name");
|
||||||
|
OBSSourceAutoRelease scene = Utils::GetSceneFromNameOrCurrent(sceneName);
|
||||||
|
if (!scene) {
|
||||||
|
req->SendErrorResponse("requested scene doesn't exist");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
OBSSceneItemAutoRelease sceneItem = Utils::GetSceneItemFromName(scene, itemName);
|
||||||
|
if (sceneItem) {
|
||||||
|
struct obs_sceneitem_crop crop = { 0 };
|
||||||
|
crop.top = obs_data_get_int(req->data, "top");
|
||||||
|
crop.bottom = obs_data_get_int(req->data, "bottom");
|
||||||
|
crop.left = obs_data_get_int(req->data, "left");
|
||||||
|
crop.right = obs_data_get_int(req->data, "right");
|
||||||
|
|
||||||
|
obs_sceneitem_set_crop(sceneItem, &crop);
|
||||||
|
|
||||||
|
req->SendOKResponse();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
req->SendErrorResponse("specified scene item doesn't exist");
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user