obs = obslua -- Version 1.0 output_file = "" -- Path of the file to be copied (e.g., replay buffer file) destination_dir = "" -- Path where the file should be copied hotkey_id = obs.OBS_INVALID_HOTKEY_ID -- Initialize hotkey ID save_highlights = false source1_name = "" source1_folder = "" source2_name = "" source2_folder = "" source3_name = "" source3_folder = "" source4_name = "" source4_folder = "" -- Description for the script function script_description() return "Instant Replay Highlight manager. Copies Instant Replay files into specific folders with the current date and time in the filename." end -- This function runs when the script is loaded function script_load(settings) -- Register hotkey to copy the file hotkey_id = obs.obs_hotkey_register_frontend("copy_replay_clip_hotkey", "Copy Instant Replay file", copy_replay_file) -- Load saved hotkey settings local hotkey_save_array = obs.obs_data_get_array(settings, "copy_replay_clip_hotkey") obs.obs_hotkey_load(hotkey_id, hotkey_save_array) obs.obs_data_array_release(hotkey_save_array) end -- Function to copy the specified file to the destination directory function copy_replay_file(pressed) if not pressed then return end -- Copy new replay clip into Highligh folder wait_and_copy_replay(1000) end -- Call this function to trigger a delay of `milliseconds` function wait_and_copy_replay(milliseconds) obs.timer_add(delayed_function, milliseconds) -- Timer takes milliseconds end -- Helper function to extract the filename from a file path function get_filename_from_path(path) return path:match("^.+/(.+)$") end -- Function to generate a timestamp string in the format YYYYMMDD_HHMMSS function get_current_timestamp() local date = os.date("*t") return string.format("%04d%02d%02d_%02d%02d%02d", date.year, date.month, date.day, date.hour, date.min, date.sec) end -- Function that executes after the delay function delayed_function() obs.script_log(obs.LOG_INFO, "This message appears after the delay!") -- Ensure output_file is set if output_file == "" then obs.script_log(obs.LOG_ERROR, "Please specify the file to copy.") obs.timer_remove(delayed_function) -- Remove the timer after it's done return end -- Construct the destination file path with the current date and time local timestamp = get_current_timestamp() local filename = get_filename_from_path(output_file) local file_extension = filename:match("^.+(%..+)$") -- Extract file extension local base_filename = filename:match("^(.-)%..+$") -- Extract base filename without extension -- Check if the sources are visible and copy if check_source_visibility(source1_name) then local destination_file1 = source1_folder .. "/" .. base_filename .. "_" .. timestamp .. file_extension local success1 = copy_file(output_file, destination_file1) end if check_source_visibility(source2_name) then local destination_file2 = source2_folder .. "/" .. base_filename .. "_" .. timestamp .. file_extension local success2 = copy_file(output_file, destination_file2) end if check_source_visibility(source3_name) then local destination_file3 = source3_folder .. "/" .. base_filename .. "_" .. timestamp .. file_extension local success3 = copy_file(output_file, destination_file3) end if check_source_visibility(source4_name) then local destination_file4 = source4_folder .. "/" .. base_filename .. "_" .. timestamp .. file_extension local success4 = copy_file(output_file, destination_file4) end if save_highlights then if destination_dir == "" then obs.script_log(obs.LOG_ERROR, "Please specify the destination directory.") obs.timer_remove(delayed_function) -- Remove the timer after it's done return end local destination_file = destination_dir .. "/" .. base_filename .. "_" .. timestamp .. file_extension local success = copy_file(output_file, destination_file) if success then obs.script_log(obs.LOG_INFO, "Replay clip file copied successfully to " .. destination_file) else obs.script_log(obs.LOG_ERROR, "Failed to copy file.") end end obs.timer_remove(delayed_function) -- Remove the timer after it's done end -- Function to copy a file function copy_file(source, destination) local input = io.open(source, "rb") if not input then return false end local output = io.open(destination, "wb") if not output then return false end local content = input:read("*all") output:write(content) input:close() output:close() return true end -- Save settings (including hotkeys) function script_save(settings) -- Save hotkey settings local hotkey_save_array = obs.obs_hotkey_save(hotkey_id) obs.obs_data_set_array(settings, "copy_replay_clip_hotkey", hotkey_save_array) obs.obs_data_array_release(hotkey_save_array) -- Save file path and destination directory obs.obs_data_set_string(settings, "output_file", output_file) obs.obs_data_set_bool(settings, "save_highlights", save_highlights) obs.obs_data_set_string(settings, "destination_dir", destination_dir) obs.obs_data_set_string(settings, "source1_name", source1_name) obs.obs_data_set_string(settings, "source2_name", source2_name) obs.obs_data_set_string(settings, "source3_name", source3_name) obs.obs_data_set_string(settings, "source4_name", source4_name) obs.obs_data_set_string(settings, "source1_folder", source1_folder) obs.obs_data_set_string(settings, "source2_folder", source2_folder) obs.obs_data_set_string(settings, "source3_folder", source3_folder) obs.obs_data_set_string(settings, "source4_folder", source4_folder) end function script_update(settings) -- Update file path and destination directory from script settings output_file = obs.obs_data_get_string(settings, "output_file") save_highlights = obs.obs_data_get_bool(settings, "save_highlights") destination_dir = obs.obs_data_get_string(settings, "destination_dir") source1_name = obs.obs_data_get_string(settings, "source1_name") source2_name = obs.obs_data_get_string(settings, "source2_name") source3_name = obs.obs_data_get_string(settings, "source3_name") source4_name = obs.obs_data_get_string(settings, "source4_name") source1_folder = obs.obs_data_get_string(settings, "source1_folder") source2_folder = obs.obs_data_get_string(settings, "source2_folder") source3_folder = obs.obs_data_get_string(settings, "source3_folder") source4_folder = obs.obs_data_get_string(settings, "source4_folder") end -- Script properties UI for inputting file and destination directory function script_properties() local props = obs.obs_properties_create() -- Property to set the output file obs.obs_properties_add_path(props, "output_file", "Replay File", obs.OBS_PATH_FILE, "Video files (*.mp4; *.mkv; *.flv)", "") -- Property to set the destination directory for highlights obs.obs_properties_add_bool(props, "save_highlights", "Save to Highlights") obs.obs_properties_add_path(props, "destination_dir", "Highlights Folder", obs.OBS_PATH_DIRECTORY, "", "") -- Add properties (text inputs) for source names inside the group local source1 = obs.obs_properties_add_list( props, 'source1_name', 'Source 1', obs.OBS_COMBO_TYPE_EDITABLE, obs.OBS_COMBO_FORMAT_STRING) local sources1 = obs.obs_enum_sources() if sources1 then for _, source in ipairs(sources1) do local name = obs.obs_source_get_name(source) obs.obs_property_list_add_string(source1, name, name) end end obs.source_list_release(sources1) obs.obs_properties_add_path(props, "source1_folder", "Source 1 Folder", obs.OBS_PATH_DIRECTORY, "", "") local source2 = obs.obs_properties_add_list( props, 'source2_name', 'Source 2', obs.OBS_COMBO_TYPE_EDITABLE, obs.OBS_COMBO_FORMAT_STRING) local sources2 = obs.obs_enum_sources() if sources2 then for _, source in ipairs(sources2) do local name = obs.obs_source_get_name(source) obs.obs_property_list_add_string(source2, name, name) end end obs.source_list_release(sources2) obs.obs_properties_add_path(props, "source2_folder", "Source 2 Folder", obs.OBS_PATH_DIRECTORY, "", "") local source3 = obs.obs_properties_add_list( props, 'source3_name', 'Source 3', obs.OBS_COMBO_TYPE_EDITABLE, obs.OBS_COMBO_FORMAT_STRING) local sources3 = obs.obs_enum_sources() if sources3 then for _, source in ipairs(sources3) do local name = obs.obs_source_get_name(source) obs.obs_property_list_add_string(source3, name, name) end end obs.source_list_release(sources3) obs.obs_properties_add_path(props, "source3_folder", "Source 3 Folder", obs.OBS_PATH_DIRECTORY, "", "") local source4 = obs.obs_properties_add_list( props, 'source4_name', 'Source 4', obs.OBS_COMBO_TYPE_EDITABLE, obs.OBS_COMBO_FORMAT_STRING) local sources4 = obs.obs_enum_sources() if sources4 then for _, source in ipairs(sources4) do local name = obs.obs_source_get_name(source) obs.obs_property_list_add_string(source4, name, name) end end obs.source_list_release(sources4) obs.obs_properties_add_path(props, "source4_folder", "Source 4 Folder", obs.OBS_PATH_DIRECTORY, "", "") return props end -- checks if the given source is visible function check_source_visibility(source_name) if source_name == "" then return end -- Get the current scene local current_scene = obs.obs_frontend_get_current_scene() if current_scene then -- Get the scene object from the source local scene = obs.obs_scene_from_source(current_scene) if scene then -- Get all items (sources) in the scene local scene_items = obs.obs_scene_enum_items(scene) for _, scene_item in ipairs(scene_items) do -- Get the source from the scene item local source = obs.obs_sceneitem_get_source(scene_item) -- Get the source name and compare with the input source_name if source and obs.obs_source_get_name(source) == source_name then -- Check if the source is visible local is_visible = obs.obs_sceneitem_visible(scene_item) local visibility_status = is_visible and "visible" or "not visible" print("Source '" .. source_name .. "' is " .. visibility_status) -- Release scene items and the current scene obs.sceneitem_list_release(scene_items) obs.obs_source_release(current_scene) -- Corrected function return is_visible end end -- Release the scene items if the source was not found obs.sceneitem_list_release(scene_items) end -- Release the current scene obs.obs_source_release(current_scene) -- Corrected function end print("Source '" .. source_name .. "' not found in the current scene.") return false end