It was impossible to capture ShaderGlass windows and retain the OG sound source. This commit fixes that. First select the OG game source. Once the sync fires up, change your game source to point to ShaderGlass window
174 lines
6.7 KiB
Lua
174 lines
6.7 KiB
Lua
-- "load" OBS bindings
|
|
obs = obslua
|
|
|
|
-- total seconds elapsed since the script has started
|
|
total_seconds = 0
|
|
-- seconds elapsed in this cycle
|
|
cur_seconds = 0
|
|
-- names of the sources that are being synced up
|
|
master_source_name = ""
|
|
slave_source_name = ""
|
|
-- seconds between sync attempts
|
|
sync_delay = 5
|
|
activated = false
|
|
|
|
-- a hotkey to force synchronisation of a given pair
|
|
hotkey_id = obs.OBS_INVALID_HOTKEY_ID
|
|
|
|
|
|
function string.split(inputstr, sep)
|
|
if sep == nil then
|
|
sep = "%s"
|
|
end
|
|
local t={}
|
|
for str in string.gmatch(inputstr, "([^"..sep.."]+)") do
|
|
table.insert(t, str)
|
|
end
|
|
return t
|
|
end
|
|
|
|
function timer_callback()
|
|
cur_seconds = cur_seconds - 1
|
|
|
|
if cur_seconds < 0 then
|
|
--print("Source Synchronizer script cycle ended. Delay is " .. total_seconds .. '; Master source is "' .. master_source_name .. '"; Slave source is "' .. slave_source_name ..'".')
|
|
|
|
-- get both master and slave sources by names set up in the script dialog settings
|
|
local master_source = obs.obs_get_source_by_name(master_source_name)
|
|
local slave_source = obs.obs_get_source_by_name(slave_source_name)
|
|
|
|
-- if both were found, we can proceed
|
|
if master_source~= nil and slave_source~= nil then
|
|
-- obs.obs_get_source_properties always returns nill
|
|
-- and obs.obs_source_get_settings is unusable since property_next expects a fucking pointer, not the object itself.
|
|
-- Solution? According to the github, using FFI for an already embedded shit. Why, oh, why, mofos?!!
|
|
-- Oh, I know why! Because OBS devs don't give a fuck since 2020 :/
|
|
|
|
-- get settings of a master source
|
|
local master_props = obs.obs_source_get_settings(master_source)
|
|
-- get the "window" property which will tell what window the master source is captturing
|
|
local master_window = obs.obs_data_get_string(master_props, 'window')
|
|
-- yes, it uses windows in "game" capture mode (fuck clarity, I guess?)
|
|
|
|
-- get settings of a slave source
|
|
local slave_props = obs.obs_source_get_settings(slave_source)
|
|
-- also read the slave props, no need to update anything if there's no need to update anything ;)
|
|
local slave_window = obs.obs_data_get_string(slave_props, 'window')
|
|
|
|
--print("slave " .. (slave_window or "-").. "; master " .. (master_window) or "-")
|
|
print(string)
|
|
|
|
if (slave_window ~= master_window) and not string.match(master_window,"ShaderGlass.exe") then
|
|
-- copy/paste the window property from the master to the slave
|
|
obs.obs_data_set_string(slave_props, 'window', master_window)
|
|
-- the copied source won't update unless...
|
|
obs.obs_source_update(slave_source, slave_props)
|
|
--obs.obs_frontend_open_source_properties(slave_source_name)
|
|
end
|
|
|
|
-- release master and slave objects
|
|
obs.obs_source_release(master_source)
|
|
obs.obs_source_release(slave_source)
|
|
|
|
-- release the new temporary data object
|
|
obs.obs_data_release(new_slave_props)
|
|
end
|
|
|
|
-- reset loop timer to the default value, so the cycle can continue
|
|
cur_seconds = sync_delay
|
|
end
|
|
|
|
--set_time_text()
|
|
end
|
|
|
|
function activate(activating)
|
|
if activated == activating then
|
|
return
|
|
end
|
|
|
|
activated = activating
|
|
|
|
if activating then
|
|
cur_seconds = total_seconds
|
|
obs.timer_add(timer_callback, 1000)
|
|
else
|
|
obs.timer_remove(timer_callback)
|
|
end
|
|
end
|
|
|
|
|
|
----------------------------------------------------------
|
|
|
|
-- A function named script_properties defines the properties that the user
|
|
-- can change for the entire script module itself
|
|
function script_properties()
|
|
-- create properties dialogue
|
|
local props = obs.obs_properties_create()
|
|
-- add sync delay settings
|
|
obs.obs_properties_add_int(props, "sync_delay", "Sync cycle (seconds)", 1, 3600, 1)
|
|
-- add main source combobox
|
|
local master = obs.obs_properties_add_list(props, "master_source", "Master source", obs.OBS_COMBO_TYPE_EDITABLE, obs.OBS_COMBO_FORMAT_STRING)
|
|
-- add the source that will sync up with the main one
|
|
local slave = obs.obs_properties_add_list(props, "slave_source", "Slave source", obs.OBS_COMBO_TYPE_EDITABLE, obs.OBS_COMBO_FORMAT_STRING)
|
|
-- get all the sources
|
|
local sources = obs.obs_enum_sources()
|
|
if sources ~= nil then
|
|
for _, source in ipairs(sources) do
|
|
source_id = obs.obs_source_get_unversioned_id(source)
|
|
-- if the source is not a group, then ad it to both master and slave lists
|
|
if source_id ~= "group"
|
|
then
|
|
local name = obs.obs_source_get_name(source)
|
|
if source_id == "game_capture" then
|
|
obs.obs_property_list_add_string(master, name, name)
|
|
end
|
|
if source_id == "wasapi_process_output_capture" then
|
|
obs.obs_property_list_add_string(slave, name, name)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
-- they say it's important to release sources
|
|
obs.source_list_release(sources)
|
|
|
|
return props
|
|
end
|
|
|
|
-- A function named script_description returns the description shown to
|
|
-- the user
|
|
function script_description()
|
|
return "This script allows one to sync 2 sources'... well, sources.\n\nThe idea is to be able to change *one* source and have the rest of them sync up with that.\n\nThe easiest example to follow: one has a game capture source and an application audio output capture source. With this it's possible to change only the game source and the audio one will reflect the changes automatically after a set time interval.\n\nThere's no explicit limit on what types of sources to use, though. If only because I'm to lazy to check all the types of sources available on different platforms.\n\nMade by 4aiman"
|
|
end
|
|
|
|
-- A function named script_update will be called when settings are changed
|
|
function script_update(settings)
|
|
total_seconds = obs.obs_data_get_int(settings, "sync_delay")
|
|
master_source_name = obs.obs_data_get_string(settings, "master_source")
|
|
slave_source_name = obs.obs_data_get_string(settings, "slave_source")
|
|
print("Source Synchronizer script upadted. Delay has been set to " .. total_seconds .. '; Master source is now "' .. master_source_name .. '"; Slave source is now "' .. slave_source_name ..'".')
|
|
|
|
end
|
|
|
|
-- A function named script_defaults will be called to set the default settings
|
|
function script_defaults(settings)
|
|
obs.obs_data_set_default_int(settings, "sync_delay", sync_delay)
|
|
end
|
|
|
|
-- A function named script_save will be called when the script is saved
|
|
--
|
|
-- NOTE: This function is usually used for saving extra data (such as in this
|
|
-- case, a hotkey's save data). Settings set via the properties are saved
|
|
-- automatically.
|
|
function script_save(settings)
|
|
local force_sources_sync_hotkey = obs.obs_hotkey_save(hotkey_id)
|
|
obs.obs_data_set_array(settings, "force_sources_sync_hotkey", force_sources_sync_hotkey)
|
|
obs.obs_data_array_release(force_sources_sync_hotkey)
|
|
end
|
|
|
|
-- a function named script_load will be called on startup
|
|
function script_load(settings)
|
|
print("Source Synchronizer script loaded")
|
|
activate(true)
|
|
end
|
|
|
|
|