KGeetings
New Member
Hello, I want to first state that I am still fairly new to programming in Lua, and am definitely looking for help and suggestions for my code. So I have taken the Instant Replay script made by Jim and Exeldro, and have attempted to modify it. What I want to be able to do is use the multiple source record plugin (which if you're unfamiliar with allows you to have replay buffers on individual sources instead of whatever is live in your program scene). I have two sources that I want to record with Source Record, where each of these gets saved to their own folder. Whenever I click a hotkey to save those replays, I also want to have my script go and look for the most recent file in each directory, and set each file to a specific source. I think I've got the basics figured out, but I'm running into a few issues:
- The first issue is that whenever I restart OBS, my directories (and media sources) don't seem to be saved.
- The second issue is that that my script seems to be running before the replays are saved, so I always get the second to latest file, instead of the latest one.
- The third issue, and possible the most important, is that my sources don't seem to actually be updating to the a new file, and I'm not entirely sure why.
Lua:
obs = obslua
source_name0 = ""
source_name1 = ""
hotkey_id = obs.OBS_INVALID_HOTKEY_ID
attempts = 0
last_replay0 = ""
last_replay1 = ""
directory0 = ""
directory1 = ""
----------------------------------------------------------
--modify lua script to get latest replay from a directory and set that as source0
--also grab the latest replay from a different directory and set that as source1
local function get_last_file_name(directory)
print("directory: " .. directory)
local files = {}
local p = io.popen('dir "'..directory..'" /b')
for file in p:lines() do
table.insert(files, file)
end
table.sort(files)
local dir_file_name = directory.."\\"..files[#files]
return dir_file_name
end
function try_play()
print("called try_play")
--add a wait time here to allow the replay to finish saving
--os.execute("timeout /t 5")
local path0 = get_last_file_name(directory0)
local path1 = get_last_file_name(directory1)
print("path0 in try_play: "..path0)
print("path1 in try_play: "..path1)
-- If the path0 is valid and the source exists, update it with the replay file to play back the replay.
-- Otherwise, stop attempting to replay after 10 retries
last_replay0 = path0
local source0 = obs.obs_get_source_by_name(source_name0)
print("source0 in try_play: "..source_name0)
if source0 ~= nil then
local settings = obs.obs_data_create()
source_id = obs.obs_source_get_id(source0)
if source_id == "ffmpeg_source" then
obs.obs_data_set_string(settings, "local_file", path0)
obs.obs_data_set_bool(settings, "is_local_file", true)
-- updating will automatically cause the source to
-- refresh if the source is currently active
obs.obs_source_update(source0, settings)
print("updated source0")
elseif source_id == "vlc_source" then
-- "playlist"
array = obs.obs_data_array_create()
item = obs.obs_data_create()
obs.obs_data_set_string(item, "value", path0)
obs.obs_data_array_push_back(array, item)
obs.obs_data_set_array(settings, "playlist", array)
-- updating will automatically cause the source to
-- refresh if the source is currently active
obs.obs_source_update(source0, settings)
obs.obs_data_release(item)
obs.obs_data_array_release(array)
end
obs.obs_data_release(settings)
obs.obs_source_release(source0)
end
last_replay1 = path1
local source1 = obs.obs_get_source_by_name(source_name1)
print("source1 in try_play: "..source_name1)
if source1 ~= nil then
local settings = obs.obs_data_create()
source_id = obs.obs_source_get_id(source1)
if source_id == "ffmpeg_source" then
obs.obs_data_set_string(settings, "local_file", path1)
obs.obs_data_set_bool(settings, "is_local_file", true)
-- updating will automatically cause the source to
-- refresh if the source is currently active
obs.obs_source_update(source1, settings)
print("updated source1")
elseif source_id == "vlc_source" then
-- "playlist"
array = obs.obs_data_array_create()
item = obs.obs_data_create()
obs.obs_data_set_string(item, "value", path1)
obs.obs_data_array_push_back(array, item)
obs.obs_data_set_array(settings, "playlist", array)
-- updating will automatically cause the source to
-- refresh if the source is currently active
obs.obs_source_update(source1, settings)
obs.obs_data_release(item)
obs.obs_data_array_release(array)
end
obs.obs_data_release(settings)
obs.obs_source_release(source1)
end
--obs.remove_current_callback()
end
-- The "Instant Replay" hotkey callback
function instant_replay(pressed)
if not pressed then
return
end
print("called try_play from hotkey")
try_play()
end
----------------------------------------------------------
-- A function named script_update will be called when settings are changed
function script_update(settings)
source_name0 = obs.obs_data_get_string(settings, "source0")
source_name1 = obs.obs_data_get_string(settings, "source1")
directory0 = obs.obs_data_get_string(settings, "directory0")
directory1 = obs.obs_data_get_string(settings, "directory1")
end
-- A function named script_description returns the description shown to the user
function script_description()
return "When the \"Instant Replay\" hotkey is triggered, grab the latest replay buffers from the directories and set them to the corresponding media sources.\n\nMade by KGeetings, modified from the work of Jim and Exeldro"
end
-- A function named script_properties defines the properties that the user
-- can change for the entire script module itself
function script_properties()
props = obs.obs_properties_create()
local p = obs.obs_properties_add_list(props, "source0", "Media Source 1", obs.OBS_COMBO_TYPE_EDITABLE, obs.OBS_COMBO_FORMAT_STRING)
local p1 = obs.obs_properties_add_list(props, "source1", "Media Source 2", obs.OBS_COMBO_TYPE_EDITABLE, obs.OBS_COMBO_FORMAT_STRING)
-- let the user define the directories to search for the last file
directory0 = obs.obs_properties_add_path(props, "directory0", "Directory 1", obs.OBS_PATH_DIRECTORY, nil, nil)
directory1 = obs.obs_properties_add_path(props, "directory1", "Directory 2", obs.OBS_PATH_DIRECTORY, nil, nil)
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 name = obs.obs_source_get_name(source)
obs.obs_property_list_add_string(p, name, name)
obs.obs_property_list_add_string(p1, name, name)
elseif source_id == "vlc_source" then
local name = obs.obs_source_get_name(source)
obs.obs_property_list_add_string(p, name, name)
obs.obs_property_list_add_string(p1, name, name)
else
-- obs.script_log(obs.LOG_INFO, source_id)
end
end
end
obs.source_list_release(sources)
return props
end
-- A function named script_load will be called on startup
function script_load(settings)
hotkey_id = obs.obs_hotkey_register_frontend("instant_replay.trigger", "Instant Replay Duo", instant_replay)
local hotkey_save_array = obs.obs_data_get_array(settings, "instant_replay.trigger")
obs.obs_hotkey_load(hotkey_id, hotkey_save_array)
obs.obs_data_array_release(hotkey_save_array)
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 hotkey_save_array = obs.obs_hotkey_save(hotkey_id)
obs.obs_data_set_array(settings, "instant_replay.trigger", hotkey_save_array)
obs.obs_data_array_release(hotkey_save_array)
end