Skip to content

Commit da26baa

Browse files
author
DeemonRider
committed
add getSceneItemList, getSceneItemTransform & getBrowserInputSettings functions
1 parent 0e38358 commit da26baa

File tree

3 files changed

+227
-6
lines changed

3 files changed

+227
-6
lines changed

README.md

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,99 @@ window.obsstudio.getScenes(function (scenes) {
166166
})
167167
```
168168

169+
#### Get scene item list
170+
Permissions required: READ_USER
171+
```js
172+
/**
173+
* @typedef {Object} SceneItem
174+
* @property {number} id - unique scene item ID
175+
* @property {string} name - name of the source
176+
* @property {boolean} visible - whether the item is visible
177+
* @property {boolean} locked - whether the item is locked
178+
* @property {string} type - the source type
179+
*/
180+
181+
/**
182+
* @callback SceneItemListCallback
183+
* @param {SceneItem[]} sceneItems
184+
*/
185+
186+
/**
187+
* @param {SceneItemListCallback} cb - The callback that receives the list of scene items in the current scene.
188+
*/
189+
window.obsstudio.getSceneItemList(function(sceneItems) {
190+
console.log(sceneItems)
191+
})
192+
```
193+
194+
#### Get scene item transform
195+
Permissions required: READ_USER
196+
```js
197+
/**
198+
* @typedef {Object} Transform
199+
* @property {Object} position - position of the item
200+
* @property {number} position.x - x coordinate
201+
* @property {number} position.y - y coordinate
202+
* @property {number} rotation - rotation in degrees
203+
* @property {Object} scale - scale of the item
204+
* @property {number} scale.x - x scale factor
205+
* @property {number} scale.y - y scale factor
206+
* @property {number} alignment - alignment flags
207+
* @property {number} boundsType - bounds type
208+
* @property {number} boundsAlignment - bounds alignment
209+
* @property {Object} bounds - bounds of the item
210+
* @property {number} bounds.x - bounds width
211+
* @property {number} bounds.y - bounds height
212+
* @property {Object} crop - crop settings
213+
* @property {number} crop.left - left crop
214+
* @property {number} crop.top - top crop
215+
* @property {number} crop.right - right crop
216+
* @property {number} crop.bottom - bottom crop
217+
*/
218+
219+
/**
220+
* @callback TransformCallback
221+
* @param {Transform} transform
222+
*/
223+
224+
/**
225+
* @param {TransformCallback} cb - The callback that receives the transform data.
226+
* @param {string} sceneName - Name of the scene
227+
* @param {number} sceneItemId - ID of the scene item
228+
*/
229+
window.obsstudio.getSceneItemTransform(function(transform) {
230+
console.log(transform)
231+
}, "SceneName", 123)
232+
```
233+
234+
#### Get browser input settings
235+
Permissions required: READ_USER
236+
```js
237+
/**
238+
* @typedef {Object} BrowserInputSettings
239+
* @property {string} inputKind - always "browser_source"
240+
* @property {Object} inputSettings - browser source settings
241+
* @property {number} inputSettings.height - height of the browser source
242+
* @property {boolean} inputSettings.shutdown - shutdown setting
243+
* @property {string} inputSettings.url - URL of the browser source
244+
* @property {number} inputSettings.webpage_control_level - control level
245+
* @property {number} inputSettings.width - width of the browser source
246+
*/
247+
248+
/**
249+
* @callback BrowserInputSettingsCallback
250+
* @param {BrowserInputSettings} settings
251+
*/
252+
253+
/**
254+
* @param {BrowserInputSettingsCallback} cb - The callback that receives the browser input settings.
255+
* @param {string} inputName - Name of the browser source
256+
*/
257+
window.obsstudio.getBrowserInputSettings(function(settings) {
258+
console.log(settings)
259+
}, "BrowserSourceName")
260+
```
261+
169262
#### Get transitions
170263
Permissions required: READ_USER
171264
```js

browser-app.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -99,12 +99,13 @@ void BrowserApp::OnBeforeCommandLineProcessing(const CefString &, CefRefPtr<CefC
9999
#endif
100100
}
101101

102-
std::vector<std::string> exposedFunctions = {"getControlLevel", "getCurrentScene", "getStatus",
103-
"startRecording", "stopRecording", "startStreaming",
104-
"stopStreaming", "pauseRecording", "unpauseRecording",
105-
"startReplayBuffer", "stopReplayBuffer", "saveReplayBuffer",
106-
"startVirtualcam", "stopVirtualcam", "getScenes",
107-
"setCurrentScene", "getTransitions", "getCurrentTransition",
102+
std::vector<std::string> exposedFunctions = {"getControlLevel", "getCurrentScene", "getStatus",
103+
"startRecording", "stopRecording", "startStreaming",
104+
"stopStreaming", "pauseRecording", "unpauseRecording",
105+
"startReplayBuffer", "stopReplayBuffer", "saveReplayBuffer",
106+
"startVirtualcam", "stopVirtualcam", "getScenes",
107+
"setCurrentScene", "getSceneItemList", "getBrowserInputSettings",
108+
"getSceneItemTransform", "getTransitions", "getCurrentTransition",
108109
"setCurrentTransition"};
109110

110111
void BrowserApp::OnContextCreated(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame>, CefRefPtr<CefV8Context> context)

browser-client.cpp

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,32 @@
3636
#include "drm-format.hpp"
3737
#endif
3838

39+
struct scene_item_enum_data {
40+
std::vector<nlohmann::json> *items;
41+
};
42+
43+
static bool enum_scene_items(obs_scene_t *scene, obs_sceneitem_t *item, void *param)
44+
{
45+
scene_item_enum_data *data = static_cast<scene_item_enum_data *>(param);
46+
47+
obs_source_t *source = obs_sceneitem_get_source(item);
48+
if (!source)
49+
return true;
50+
51+
const char *source_name = obs_source_get_name(source);
52+
if (!source_name)
53+
return true;
54+
55+
nlohmann::json item_json = {{"id", obs_sceneitem_get_id(item)},
56+
{"name", source_name},
57+
{"visible", obs_sceneitem_visible(item)},
58+
{"locked", obs_sceneitem_locked(item)},
59+
{"type", obs_source_get_type(source)}};
60+
61+
data->items->push_back(item_json);
62+
return true;
63+
}
64+
3965
inline bool BrowserClient::valid() const
4066
{
4167
return !!bs && !bs->destroying;
@@ -244,6 +270,107 @@ bool BrowserClient::OnProcessMessageReceived(CefRefPtr<CefBrowser> browser, CefR
244270
json = {{"name", name},
245271
{"width", obs_source_get_width(current_scene)},
246272
{"height", obs_source_get_height(current_scene)}};
273+
} else if (name == "getSceneItemList") {
274+
OBSSourceAutoRelease current_scene = obs_frontend_get_current_scene();
275+
276+
if (!current_scene)
277+
return false;
278+
279+
// Convert source to scene object for enumeration
280+
obs_scene_t *scene = obs_scene_from_source(current_scene);
281+
if (!scene)
282+
return false;
283+
284+
std::vector<nlohmann::json> scene_items;
285+
scene_item_enum_data data = {&scene_items};
286+
287+
// Enumerate all items in the scene and collect their data
288+
obs_scene_enum_items(scene, enum_scene_items, &data);
289+
290+
json = scene_items;
291+
} else if (name == "getBrowserInputSettings") {
292+
const std::string input_name = input_args->GetString(1).ToString();
293+
294+
// Retrieve the source by name from OBS
295+
// Lookup by ID not needed. When a user duplicates a source with reference the settings are the same.
296+
OBSSourceAutoRelease source = obs_get_source_by_name(input_name.c_str());
297+
if (!source) {
298+
return false;
299+
}
300+
301+
// Validate that the source is actually a browser source
302+
const char *source_id = obs_source_get_id(source);
303+
if (!source_id || strcmp(source_id, "browser_source") != 0) {
304+
return false;
305+
}
306+
307+
// Get the source settings data
308+
obs_data_t *settings = obs_source_get_settings(source);
309+
if (!settings) {
310+
return false;
311+
}
312+
313+
// Extract browser source specific settings from the data
314+
const char *url = obs_data_get_string(settings, "url");
315+
int width = (int)obs_data_get_int(settings, "width");
316+
int height = (int)obs_data_get_int(settings, "height");
317+
bool shutdown = obs_data_get_bool(settings, "shutdown");
318+
int webpage_control_level = (int)obs_data_get_int(settings, "webpage_control_level");
319+
320+
json = {{"inputKind", "browser_source"},
321+
{"inputSettings",
322+
{{"height", height},
323+
{"shutdown", shutdown},
324+
{"url", url ? url : ""},
325+
{"webpage_control_level", webpage_control_level},
326+
{"width", width}}}};
327+
328+
// Release allocated memory
329+
obs_data_release(settings);
330+
} else if (name == "getSceneItemTransform") {
331+
const std::string scene_name = input_args->GetString(1).ToString();
332+
int64_t scene_item_id = input_args->GetInt(2);
333+
334+
OBSSourceAutoRelease source = obs_get_source_by_name(scene_name.c_str());
335+
if (!source) {
336+
return false;
337+
}
338+
339+
// Verify that the source is actually a scene
340+
if (!obs_source_is_scene(source)) {
341+
return false;
342+
}
343+
344+
// Convert source to scene object for item lookup
345+
obs_scene_t *scene = obs_scene_from_source(source);
346+
if (!scene) {
347+
return false;
348+
}
349+
350+
// Find the specific scene item by its unique ID
351+
obs_sceneitem_t *item = obs_scene_find_sceneitem_by_id(scene, scene_item_id);
352+
if (!item) {
353+
return false;
354+
}
355+
356+
// Retrieve transform and crop information from the scene item
357+
struct obs_transform_info transform;
358+
struct obs_sceneitem_crop crop;
359+
obs_sceneitem_get_info2(item, &transform);
360+
obs_sceneitem_get_crop(item, &crop);
361+
362+
json = {{"position", {{"x", transform.pos.x}, {"y", transform.pos.y}}},
363+
{"rotation", transform.rot},
364+
{"scale", {{"x", transform.scale.x}, {"y", transform.scale.y}}},
365+
{"alignment", transform.alignment},
366+
{"boundsType", transform.bounds_type},
367+
{"boundsAlignment", transform.bounds_alignment},
368+
{"bounds", {{"x", transform.bounds.x}, {"y", transform.bounds.y}}},
369+
{"crop",
370+
{{"left", crop.left},
371+
{"top", crop.top},
372+
{"right", crop.right},
373+
{"bottom", crop.bottom}}}};
247374
} else if (name == "getTransitions") {
248375
struct obs_frontend_source_list list = {};
249376
obs_frontend_get_transitions(&list);

0 commit comments

Comments
 (0)