L&Mproducer
New Member
I've written a script (which works miraculously) to automatically move a Source to the top of the display order whenever its visibility is changed from Hidden to Visible. This allows my streamer to use their Stream Deck to "stack" sources in the order they like in real-time.
In the script_properties() function, I ask the user to select a "target" scene that limits this behaviour to only that scene, which contains only these 'stackable' Sources. I then Downstream Keyer to always have that Scene showing, even though the active Scene is our main one with camera, logo, other digital assets etc. This all works great.
To wire up the event, I connect a handler to the "source_show" signal
Again, no problems here. However, its inside my "sourceShow_signal" function where my novice-level LUA scripting becomes evident and I am requesting your help. Algorithmically, what I want to do is:
This seems like an easy optimization for somebody who understands those object types better than I do. It seems to me like this should be a couple lines of code instead of what I'm doing -- which, to be clear, DOES work, but it keeps me up at night :)
Any help would be appreciated, here's the handler function:
In the script_properties() function, I ask the user to select a "target" scene that limits this behaviour to only that scene, which contains only these 'stackable' Sources. I then Downstream Keyer to always have that Scene showing, even though the active Scene is our main one with camera, logo, other digital assets etc. This all works great.
Lua:
function script_properties()
local props = obs.obs_properties_create()
local p = obs.obs_properties_add_list(props, "TargetScene", "Source Layerer Scene", obs.OBS_COMBO_TYPE_EDITABLE, obs.OBS_COMBO_FORMAT_STRING)
local scenes = obs.obs_frontend_get_scenes()
if scenes ~= nil then
for _, eachScene in ipairs(scenes) do
local SceneName = obs.obs_source_get_name(eachScene)
obs.obs_property_list_add_string(p, SceneName, SceneName)
end
end
obs.source_list_release()
return props
end
To wire up the event, I connect a handler to the "source_show" signal
Lua:
function script_load(settings)
-- attach a handler to the source-show signal (the "sourceShow_signal" function)
local sh = obs.obs_get_signal_handler()
obs.signal_handler_connect(sh, "source_show", sourceShow_signal)
end
Again, no problems here. However, its inside my "sourceShow_signal" function where my novice-level LUA scripting becomes evident and I am requesting your help. Algorithmically, what I want to do is:
- Determine whether the shown Source is in our TargetScene or not
- If it is, set its order to OBS_ORDER_MOVE_TOP within the scene
This seems like an easy optimization for somebody who understands those object types better than I do. It seems to me like this should be a couple lines of code instead of what I'm doing -- which, to be clear, DOES work, but it keeps me up at night :)
Any help would be appreciated, here's the handler function:
Lua:
function sourceShow_signal(cd)
-- Which OBS source was just shown
local ShownSource = obs.calldata_source(cd, "source")
-- make sure we've got an actual object here
if ShownSource ~= nil then
-- first we need to make sure that the OBS source that was shown is in our target scene
-- Couldn't figure out how to get the scene that contains the OBS source directly so we brute force it and search for it
-- get all scenes
local scenes = obs.obs_frontend_get_scenes()
-- as long as we have a collection of scenes
if scenes ~= nil then
-- .. let's loop through all scenes. These scenes are "source" objects not scene objects (yet)
for _, scenesource in ipairs(scenes) do
-- get the name of the scene currently being looped through
local scenename = obs.obs_source_get_name(scenesource)
-- if it's the same scene name as the one we're targetting
if scenename==TargetScene then
-- convert the scenes "source" object to a scene object
local scene = obs.obs_scene_from_source(scenesource)
-- get all the scene items (OBS sources) in that scene
local sceneitems = obs.obs_scene_enum_items(scene)
-- loop through those scene items
for i, sceneitem in ipairs(sceneitems) do
-- convert the sceneitem to a source object
local source = obs.obs_sceneitem_get_source(sceneitem)
-- get the name of the source object
local sourcename = obs.obs_source_get_name(source)
-- lastly, get the name of whatever source was just displayed
local ShownSourceName = obs.obs_source_get_name(ShownSource)
-- compare the two
if sourcename == ShownSourceName then
-- pop that source to the top of the order
obs.obs_sceneitem_set_order(sceneitem,obs.OBS_ORDER_MOVE_TOP)
end
end
end
obs.sceneitem_list_release(sceneitems)
end
obs.source_list_release(scenes)
end
end
end