From 2ff2585ac7660693af55fd21bf322bb3903cbfd5 Mon Sep 17 00:00:00 2001 From: DeemonRider Date: Sat, 23 Aug 2025 15:47:14 +0200 Subject: [PATCH] Add getItemTransform function --- README.md | 39 +++++++++++++++++++++++++ browser-app.cpp | 14 ++++----- browser-client.cpp | 73 ++++++++++++++++++++++++++++++++++++++++++++++ browser-client.hpp | 6 ++++ 4 files changed, 125 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 3e1732802..87307bc9a 100644 --- a/README.md +++ b/README.md @@ -127,6 +127,45 @@ window.obsstudio.getStatus(function (status) { }) ``` +#### Get item transform +Permissions required: READ_OBS +```js +/** + * @typedef {Object} ItemTransform + * @property {Object} position - Position of the item + * @property {number} position.x - X coordinate + * @property {number} position.y - Y coordinate + * @property {Object} scale - Scale of the item + * @property {number} scale.x - X scale factor + * @property {number} scale.y - Y scale factor + * @property {number} rotation - Rotation in degrees + * @property {number} alignment - Alignment flags + * @property {number} boundsType - Bounds type (0 = None, 1 = Stretch, 2 = Scale inner, 3 = Scale outer, 4 = Scale to width, 5 = Scale to height, 6 = Scale to fit, 7 = Scale to fill) + * @property {number} boundsAlignment - Bounds alignment flags + * @property {Object} crop - Crop settings + * @property {number} crop.top - Top crop in pixels + * @property {number} crop.right - Right crop in pixels + * @property {number} crop.bottom - Bottom crop in pixels + * @property {number} crop.left - Left crop in pixels + * @property {number} sourceWidth - Width of the source + * @property {number} sourceHeight - Height of the source + * @property {number} sceneWidth - Width of the scene + * @property {number} sceneHeight - Height of the scene + */ + +/** + * @callback ItemTransformCallback + * @param {ItemTransform|null} transform - The transform information for the current browser source, or null if not found + */ + +/** + * @param {ItemTransformCallback} cb - The callback that receives the transform information for the current browser source. + */ +window.obsstudio.getItemTransform(function (transform) { + console.log(transform); +}) +``` + #### Get the current scene Permissions required: READ_USER ```js diff --git a/browser-app.cpp b/browser-app.cpp index 7a6c893a9..291b5745e 100644 --- a/browser-app.cpp +++ b/browser-app.cpp @@ -99,13 +99,13 @@ void BrowserApp::OnBeforeCommandLineProcessing(const CefString &, CefRefPtr exposedFunctions = {"getControlLevel", "getCurrentScene", "getStatus", - "startRecording", "stopRecording", "startStreaming", - "stopStreaming", "pauseRecording", "unpauseRecording", - "startReplayBuffer", "stopReplayBuffer", "saveReplayBuffer", - "startVirtualcam", "stopVirtualcam", "getScenes", - "setCurrentScene", "getTransitions", "getCurrentTransition", - "setCurrentTransition"}; +std::vector exposedFunctions = {"getControlLevel", "getCurrentScene", "getStatus", + "startRecording", "stopRecording", "startStreaming", + "stopStreaming", "pauseRecording", "unpauseRecording", + "startReplayBuffer", "stopReplayBuffer", "saveReplayBuffer", + "startVirtualcam", "stopVirtualcam", "getScenes", + "setCurrentScene", "getTransitions", "getCurrentTransition", + "setCurrentTransition", "getItemTransform"}; void BrowserApp::OnContextCreated(CefRefPtr browser, CefRefPtr, CefRefPtr context) { diff --git a/browser-client.cpp b/browser-client.cpp index 9b334b476..4bf65a408 100644 --- a/browser-client.cpp +++ b/browser-client.cpp @@ -266,6 +266,8 @@ bool BrowserClient::OnProcessMessageReceived(CefRefPtr browser, CefR {"recordingPaused", obs_frontend_recording_paused()}, {"replaybuffer", obs_frontend_replay_buffer_active()}, {"virtualcam", obs_frontend_virtualcam_active()}}; + } else if (name == "getItemTransform") { + json = GetItemTransformData(); } [[fallthrough]]; case ControlLevel::None: @@ -285,6 +287,77 @@ bool BrowserClient::OnProcessMessageReceived(CefRefPtr browser, CefR return true; } +nlohmann::json BrowserClient::GetItemTransformData() +{ + // Get the current scene + OBSSourceAutoRelease current_scene = obs_frontend_get_current_scene(); + if (!current_scene) { + return nullptr; + } + + // Find the scene item for this browser source + obs_scene_t *scene = obs_scene_from_source(current_scene); + if (!scene) { + return nullptr; + } + + // Find the scene item + obs_sceneitem_t *scene_item = FindSceneItem(scene); + if (!scene_item) { + return nullptr; + } + + // Get transform information + return BuildTransformJson(scene_item, current_scene); +} + +obs_sceneitem_t *BrowserClient::FindSceneItem(obs_scene_t *scene) +{ + // Find the scene item by source name + const char *source_name = obs_source_get_name(bs->source); + obs_sceneitem_t *scene_item = obs_scene_find_source(scene, source_name); + + return scene_item; +} + +nlohmann::json BrowserClient::BuildTransformJson(obs_sceneitem_t *scene_item, obs_source_t *current_scene) +{ + // Get basic transform information + vec2 pos; + vec2 scale; + float rot; + obs_sceneitem_get_pos(scene_item, &pos); + obs_sceneitem_get_scale(scene_item, &scale); + rot = obs_sceneitem_get_rot(scene_item); + + // Get alignment and bounds information + uint32_t alignment = obs_sceneitem_get_alignment(scene_item); + obs_bounds_type bounds_type = obs_sceneitem_get_bounds_type(scene_item); + uint32_t bounds_alignment = obs_sceneitem_get_bounds_alignment(scene_item); + + // Get crop information + obs_sceneitem_crop crop; + obs_sceneitem_get_crop(scene_item, &crop); + + // Get dimensions + uint32_t source_width = obs_source_get_width(bs->source); + uint32_t source_height = obs_source_get_height(bs->source); + uint32_t scene_width = obs_source_get_width(current_scene); + uint32_t scene_height = obs_source_get_height(current_scene); + + return {{"position", {{"x", pos.x}, {"y", pos.y}}}, + {"scale", {{"x", scale.x}, {"y", scale.y}}}, + {"rotation", rot}, + {"alignment", alignment}, + {"boundsType", bounds_type}, + {"boundsAlignment", bounds_alignment}, + {"crop", {{"top", crop.top}, {"right", crop.right}, {"bottom", crop.bottom}, {"left", crop.left}}}, + {"sourceWidth", source_width}, + {"sourceHeight", source_height}, + {"sceneWidth", scene_width}, + {"sceneHeight", scene_height}}; +} + void BrowserClient::GetViewRect(CefRefPtr, CefRect &rect) { if (!valid()) { diff --git a/browser-client.hpp b/browser-client.hpp index bf21fdf55..591ff9ab7 100644 --- a/browser-client.hpp +++ b/browser-client.hpp @@ -22,6 +22,7 @@ #include #include "cef-headers.hpp" #include "obs-browser-source.hpp" +#include struct BrowserSource; @@ -161,5 +162,10 @@ class BrowserClient : public CefClient, /* CefLoadHandler */ virtual void OnLoadEnd(CefRefPtr browser, CefRefPtr frame, int httpStatusCode) override; + /* Item Transform Helper Functions */ + nlohmann::json GetItemTransformData(); + obs_sceneitem_t *FindSceneItem(obs_scene_t *scene); + nlohmann::json BuildTransformJson(obs_sceneitem_t *scene_item, obs_source_t *current_scene); + IMPLEMENT_REFCOUNTING(BrowserClient); };