Resource icon

OBS Lua auto-hide media when finished playing

I am using a media-hide.lua file to auto hide media sources after they finished playing. I can not understand why OBS still does not offer that, even with version 31. There is a "Close file when inactive" option, but that doesnt hide the source after an mp3 or mp4 played.

This lua can do the trick. I pushed it through gemini to fix a crash bug in OBS 31, and the crash bug seems to be fixed.

I can not find the original creator in this forum under the search term, so credits not going to me, I just want to help those who searching for a solution on that.


Lua:
obs = obslua
gs = nil

local function disconnect_all_callbacks()
    local sources = obs.obs_enum_sources()
    if sources then
        for _, source in ipairs(sources) do
            local sh = obs.obs_source_get_signal_handler(source)
            if sh then
                obs.signal_handler_disconnect(sh, "media_ended", media_ended)
            end
        end
        obs.source_list_release(sources)
    end
   
    local sh = obs.obs_get_signal_handler()
    if sh then
        obs.signal_handler_disconnect(sh, "source_create", source_create)
    end
end

function source_enable(source, enable)
    local sourcename = obs.obs_source_get_name(source)
    local scenes = obs.obs_frontend_get_scenes()
    if scenes then
        for _, scenesource in ipairs(scenes) do
            local scene = obs.obs_scene_from_source(scenesource)
            if scene then
                local sceneitems = obs.obs_scene_enum_items(scene)
                if sceneitems then
                    for _, sceneitem in ipairs(sceneitems) do
                        local itemSource = obs.obs_sceneitem_get_source(sceneitem)
                        if itemSource then
                            local group = obs.obs_group_from_source(itemSource)
                            if group then
                                local groupitems = obs.obs_scene_enum_items(group)
                                if groupitems then
                                    for _, groupitem in ipairs(groupitems) do
                                        local subItemSource = obs.obs_sceneitem_get_source(groupitem)
                                        if subItemSource and sourcename == obs.obs_source_get_name(subItemSource) then
                                            obs.obs_sceneitem_set_visible(groupitem, enable)
                                        end
                                    end
                                    obs.sceneitem_list_release(groupitems)
                                end
                            else
                                if sourcename == obs.obs_source_get_name(itemSource) then
                                    obs.obs_sceneitem_set_visible(sceneitem, enable)
                                end
                            end
                        end
                    end
                    obs.sceneitem_list_release(sceneitems)
                end
            end
        end
        obs.source_list_release(scenes)
    end
end

function script_properties()
    local props = obs.obs_properties_create()
    obs.obs_properties_add_bool(props, "exclude", "Exclude")
    obs.obs_properties_add_editable_list(props, "sources", "Sources", obs.OBS_EDITABLE_LIST_TYPE_STRINGS, nil, nil)
    return props
end

function script_description()
    return "Hide media sources when ended"
end

function media_ended(cd)
    local source = obs.calldata_source(cd, "source")
    if source then
        source_enable(source, false)
    end
end

function update_source_media_ended(source, sourceNames, exclude)
    local sh = obs.obs_source_get_signal_handler(source)
    obs.signal_handler_disconnect(sh, "media_ended", media_ended)
    local sn = obs.obs_source_get_name(source)
    local found = false
    local count = obs.obs_data_array_count(sourceNames)
    for i = 0, count - 1 do
        local item = obs.obs_data_array_item(sourceNames, i)
        if obs.obs_data_get_string(item, "value") == sn then
            found = true
            break
        end
    end
    if (found and not exclude) or (not found and exclude) then
        obs.signal_handler_connect(sh, "media_ended", media_ended)
    end
end

function script_update(settings)
    gs = settings
    local exclude = obs.obs_data_get_bool(settings, "exclude")
    local sourceNames = obs.obs_data_get_array(settings, "sources")
    local sources = obs.obs_enum_sources()
    if sources then
        for _, source in ipairs(sources) do
            update_source_media_ended(source, sourceNames, exclude)
        end
        obs.source_list_release(sources)
    end
end

function script_defaults(settings)
    -- This function is fine as is
end

function source_create(cd)
    if not gs then return end
    local source = obs.calldata_source(cd, "source")
    local exclude = obs.obs_data_get_bool(gs, "exclude")
    local sourceNames = obs.obs_data_get_array(gs, "sources")
    if source and sourceNames then
        update_source_media_ended(source, sourceNames, exclude)
    end
end

function script_load(settings)
    gs = settings
    local sh = obs.obs_get_signal_handler()
    obs.signal_handler_connect(sh, "source_create", source_create)
end

function script_unload()
    disconnect_all_callbacks()
end
Author
BobbyJones
Views
28
First release
Last update
Rating
0.00 star(s) 0 ratings
Top