obs = obslua gs = nil always_show = false hide_delay = 2000 active_source_name = nil timers = {} function script_properties() local props = obs.obs_properties_create() obs.obs_properties_add_editable_list(props, "sources", "Scenes and Groups", obs.OBS_EDITABLE_LIST_TYPE_STRINGS, nil, nil) obs.obs_properties_add_bool(props, "always_show", "Always show") obs.obs_properties_add_int(props, "hide_delay", "Hide Delay (ms)", 0, 10000, 100) return props end function script_description() return "Toggle between sources visible in a scene with filter-based audio fade effects" end function item_visible(calldata) local visible = obs.calldata_bool(calldata, "visible") if not visible and not always_show then return end local item = obs.calldata_sceneitem(calldata, "item") local source = obs.obs_sceneitem_get_source(item) local sourceName = obs.obs_source_get_name(source) print("Source visibility changed: " .. sourceName .. " Visible: " .. tostring(visible)) local scene = obs.obs_sceneitem_get_scene(item) local sceneitems = obs.obs_scene_enum_items(scene) if visible then active_source_name = sourceName activate_filter(source, "MV_FadeIN") for _, sceneitem in ipairs(sceneitems) do local itemsource = obs.obs_sceneitem_get_source(sceneitem) local isn = obs.obs_source_get_name(itemsource) if sourceName ~= isn then if obs.obs_sceneitem_visible(sceneitem) then activate_filter(itemsource, "MV_FadeOUT") if timers[isn] then obs.timer_remove(timers[isn]) end timers[isn] = function() if active_source_name ~= isn then obs.obs_sceneitem_set_visible(sceneitem, false) print("Hiding source: " .. isn) else print("Not hiding source: " .. isn .. " because active source is: " .. active_source_name) end obs.timer_remove(timers[isn]) timers[isn] = nil end obs.timer_add(timers[isn], hide_delay) end end end end obs.sceneitem_list_release(sceneitems) end function activate_filter(source, filter_name) local filter = obs.obs_source_get_filter_by_name(source, filter_name) if filter then obs.obs_source_set_enabled(filter, true) print("Activated filter: " .. filter_name .. " on source: " .. obs.obs_source_get_name(source)) obs.obs_source_release(filter) else print("Filter not found: " .. filter_name .. " on source: " .. obs.obs_source_get_name(source)) end end function script_update(settings) always_show = obs.obs_data_get_bool(settings, "always_show") hide_delay = obs.obs_data_get_int(settings, "hide_delay") local sourceNames = obs.obs_data_get_array(settings, "sources") local count = obs.obs_data_array_count(sourceNames) for i = 0, count - 1 do local item = obs.obs_data_array_item(sourceNames, i) local sourceName = obs.obs_data_get_string(item, "value") local source = obs.obs_get_source_by_name(sourceName) if source ~= nil then local sh = obs.obs_source_get_signal_handler(source) obs.signal_handler_disconnect(sh, "item_visible", item_visible) obs.signal_handler_connect(sh, "item_visible", item_visible) obs.obs_source_release(source) end obs.obs_data_release(item) end obs.obs_data_array_release(sourceNames) end function script_defaults(settings) obs.obs_data_set_default_int(settings, "hide_delay", 2000) end function script_save(settings) end function loaded(cd) if gs == nil then return end local source = obs.calldata_source(cd, "source") local sn = obs.obs_source_get_name(source) local sourceNames = obs.obs_data_get_array(gs, "sources") local count = obs.obs_data_array_count(sourceNames) for i = 0, count - 1 do local item = obs.obs_data_array_item(sourceNames, i) local sourceName = obs.obs_data_get_string(item, "value") if sn == sourceName then local sh = obs.obs_source_get_signal_handler(source) obs.signal_handler_disconnect(sh, "item_visible", item_visible) obs.signal_handler_connect(sh, "item_visible", item_visible) end obs.obs_data_release(item) end obs.obs_data_array_release(sourceNames) end function script_load(settings) gs = settings always_show = obs.obs_data_get_bool(settings, "always_show") hide_delay = obs.obs_data_get_int(settings, "hide_delay") local sh = obs.obs_get_signal_handler() obs.signal_handler_connect(sh, "source_load", loaded) end function script_unload() end