Skip to content

Instantly share code, notes, and snippets.

@tsukasa
Created May 21, 2022 19:05
Show Gist options
  • Save tsukasa/cf35413aaca4216e45383e74ff7cf475 to your computer and use it in GitHub Desktop.
Save tsukasa/cf35413aaca4216e45383e74ff7cf475 to your computer and use it in GitHub Desktop.
OBS Lua script that checks the contents of a file and sets a media source's local_source if the content changed.
-- -------------------------------------------------------------
-- Load Video File from Text
--
-- Loads media from the contents of a given input text file.
-- Intended to be used with the StreamDeck.
-- -------------------------------------------------------------
obs = obslua
p_TimerId = 0
p_VideoFile = nil
p_CurrentSceneName = nil
p_CurrentVideoFile = nil
p_LockOut = false
p_VideoFileList = nil
p_SourceName = nil
p_SceneName = nil
p_Enabled = true
p_Interval = 100
--- ------------------------------------------------------------
--- Script Metadata
--- ------------------------------------------------------------
function script_description()
return [[Reads the path of a video file from a selected text file and updates a selected media source using the new video file path. It reads the text file for changes at preditermined intervals.]]
end
function script_load()
end
function script_unload()
end
--- ------------------------------------------------------------
--- Primary Script Functions
--- ------------------------------------------------------------
function init()
-- increase the timer id - old timers will be cancelled
p_TimerId = p_TimerId + 1
-- only proceed if there is a text file selected
if not p_VideoFileList
or not p_SourceName
or not p_SceneName
or not p_Enabled then
return nil
end
-- start the timer to check the text file
local id = p_TimerId
obs.timer_add(function() check_txt_file(id) end, p_Interval)
end
function file_exists(filename)
local f = io.open(filename, "rb")
if f then
f:close()
end
return f ~= nil
end
function read_txt_file(filename)
filename = filename or ''
local line
local videoFile
if not file_exists(filename) then
return
end
for line in io.lines(filename) do
if line ~= "" then
videoFile = line
if p_CurrentVideoFile == videoFile then
print("Video file has not changed")
return
else
p_CurrentVideoFile = videoFile
set_media_source_file(videoFile)
return
end
end
end
end
function set_media_source_file(filename)
local source = obs.obs_get_source_by_name(p_SourceName)
if source ~= nil then
local settings = obs.obs_data_create()
obs.obs_data_set_string(settings, "local_file", filename)
obs.obs_source_update(source, settings)
obs.obs_data_release(settings)
end
obs.obs_source_release(source)
print("Updated local_file for source \"" .. p_SourceName .. "\" to \"" .. filename .. "\"")
end
function get_current_scene_name()
local currentScene = obs.obs_frontend_get_current_scene()
local currentSceneName = obs.obs_source_get_name(currentScene)
obs.obs_source_release(currentScene)
p_LockOut = p_CurrentSceneName == currentSceneName
p_CurrentSceneName = currentSceneName
return currentSceneName
end
function check_txt_file(timerId)
if timerId < p_TimerId then
obs.remove_current_callback()
return
end
if p_Enabled then
if get_current_scene_name() == p_SceneName then
if not p_LockOut then
read_txt_file(p_VideoFileList)
end
end
end
end
--- -------------------------------------------------------------------------
--- Script Properties
--- -------------------------------------------------------------------------
function script_defaults(s)
obs.obs_data_set_default_bool(s, "p_Enable", false)
obs.obs_data_set_default_int(s, "p_Interval", 100)
end
function script_update(s)
p_VideoFileList = obs.obs_data_get_string(s, "p_VideoFileList")
p_SourceName = obs.obs_data_get_string(s, "p_TargetSource")
p_SceneName = obs.obs_data_get_string(s, "p_SceneToCheck")
p_Interval = obs.obs_data_get_int(s, "p_Interval")
p_Enabled = obs.obs_data_get_bool(s, "p_Enable")
init()
end
function script_properties()
local p = obs.obs_properties_create()
--- Enable checkbox
obs.obs_properties_add_bool(p, "p_Enable", "Enable script")
--- Interval input
obs.obs_properties_add_int(p, "p_Interval", "Interval (ms)", 50, 20000, 10)
--- Video File List input
obs.obs_properties_add_path(p, "p_VideoFileList", "Video File List",
obs.OBS_PATH_FILE,
"Video File List (*.txt)",
nil
)
--- Target Scene
local s = obs.obs_properties_add_list(p, "p_SceneToCheck", "Scene", obs.OBS_COMBO_TYPE_EDITABLE, obs.OBS_COMBO_FORMAT_STRING)
local scenes = obs.obs_frontend_get_scenes()
if scenes ~= nil then
for _, scene in ipairs(scenes) do
scene_id = obs.obs_source_get_id(scene)
local sceneName = obs.obs_source_get_name(scene)
obs.obs_property_list_add_string(s, sceneName, sceneName)
end
end
--- Target Media Source
local t = obs.obs_properties_add_list(p, "p_TargetSource", "Media Source", obs.OBS_COMBO_TYPE_EDITABLE, obs.OBS_COMBO_FORMAT_STRING)
local sources = obs.obs_enum_sources()
if sources ~= nil then
for _, source in ipairs(sources) do
source_id = obs.obs_source_get_id(source)
if source_id == "ffmpeg_source" then
local sourceName = obs.obs_source_get_name(source)
obs.obs_property_list_add_string(t, sourceName, sourceName)
end
end
end
obs.source_list_release(sources)
return p
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment