Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- obs = obslua
- source_names = {
- left = "",
- left_bg = "",
- right = "",
- right_bg = "",
- both = "",
- both_bg = ""
- }
- hotkey_ids = {
- obs.OBS_INVALID_HOTKEY_ID,
- obs.OBS_INVALID_HOTKEY_ID,
- obs.OBS_INVALID_HOTKEY_ID
- }
- hotkey_pressed = ""
- attempts = 0
- animate_props = {
- vid = {},
- bg = {}
- }
- play_reverse = false
- dir = ""
- ----------------------------------------------------------
- function try_play()
- local replay_buffer = obs.obs_frontend_get_replay_buffer_output()
- if replay_buffer == nil then
- obs.remove_current_callback()
- return
- end
- -- Call the procedure of the replay buffer named "get_last_replay" to
- -- get the last replay created by the replay buffer
- local cd = obs.calldata_create()
- local ph = obs.obs_output_get_proc_handler(replay_buffer)
- obs.proc_handler_call(ph, "get_last_replay", cd)
- local path = obs.calldata_string(cd, "path")
- obs.calldata_destroy(cd)
- obs.obs_output_release(replay_buffer)
- -- If the path is valid and the source exists, update it with the
- -- replay file to play back the replay. Otherwise, stop attempting to
- -- replay after 10 seconds
- if path == nil then
- attempts = attempts + 1
- if attempts >= 10 then
- obs.remove_current_callback()
- end
- elseif hotkey_pressed == "" then
- obs.remove_current_callback()
- else
- local name_v = source_names[hotkey_pressed]
- local source_v = obs.obs_get_source_by_name(name_v)
- local name_i = source_names[hotkey_pressed .. "_bg"]
- local source_i = obs.obs_get_source_by_name(name_i)
- hotkey_pressed = ""
- if source_v ~= nil and source_i ~= nil then
- local settings = obs.obs_data_create()
- obs.obs_data_set_string(settings, "local_file", path)
- obs.obs_data_set_bool(settings, "is_local_file", true)
- obs.obs_data_set_bool(settings, "close_when_inactive", true)
- obs.obs_data_set_bool(settings, "restart_on_activate", false)
- -- updating will automatically cause the source to
- -- refresh if the source is currently active, otherwise
- -- the source will play whenever its scene is activated
- obs.obs_source_update(source_v, settings)
- transition_setup(name_v, name_i)
- obs.obs_data_release(settings)
- obs.obs_source_release(source_v)
- obs.obs_source_release(source_i)
- else
- obs.script_log(obs.LOG_WARNING, "You need to set your sources in the properties window!")
- end
- obs.remove_current_callback()
- end
- end
- function transition_setup(name_v, name_i)
- local scene = obs.obs_scene_from_source(obs.obs_frontend_get_current_scene())
- local scene_item_v = obs.obs_scene_find_source(scene, name_v)
- local transform_v = obs.obs_transform_info()
- local scene_item_i = obs.obs_scene_find_source(scene, name_i)
- local transform_i = obs.obs_transform_info()
- obs.obs_sceneitem_get_info(scene_item_v, transform_v)
- obs.obs_sceneitem_get_info(scene_item_i, transform_i)
- dir = "up"
- if name_v == source_names.left then
- dir = "right"
- elseif name_v == source_names.right then
- dir = "left"
- end
- start_slides(scene_item_v, scene_item_i, transform_v, transform_i)
- obs.timer_add(end_slides, 8000)
- obs.obs_scene_release(scene)
- -- obs.obs_sceneitem_release(scene_item_v)
- -- obs.obs_sceneitem_release(scene_item_i)
- end
- function start_slides(scene_item_v, scene_item_i, transform_v, transform_i)
- local pos_v = transform_v.pos
- local bounds_v = transform_v.bounds
- local pos_i = transform_i.pos
- local bounds_i = transform_i.bounds
- animate_props.vid = {
- item = scene_item_v,
- pos = pos_v,
- bounds = bounds_v
- }
- animate_props.bg = {
- item = scene_item_i,
- pos = pos_i,
- bounds = bounds_i
- }
- play_reverse = false
- if dir == "up" then
- pos_v.y = 1080 + bounds_v.y
- pos_i.y = 1080 + bounds_i.y
- obs.timer_add(slide_up, 10)
- elseif dir == "right" then
- pos_v.x = -bounds_v.x
- pos_i.x = -bounds_i.x
- obs.timer_add(slide_right, 10)
- elseif dir == "left" then
- pos_v.x = 1920 + bounds_v.x
- pos_i.x = 1920 + bounds_i.x
- obs.timer_add(slide_left, 10)
- end
- obs.obs_sceneitem_set_pos(scene_item_v, pos_v)
- obs.obs_sceneitem_set_pos(scene_item_i, pos_i)
- end
- function end_slides()
- play_reverse = true
- if dir == "up" then
- obs.timer_add(slide_up, 10)
- elseif dir == "right" then
- obs.timer_add(slide_right, 10)
- elseif dir == "left" then
- obs.timer_add(slide_left, 10)
- end
- obs.remove_current_callback()
- end
- -- Weird rounding bullshit leads to the odd numbers below
- function slide_up()
- local remove_callback = false
- for _, props in pairs(animate_props) do
- local dist = props.bounds.y
- local tick = dist/20
- if not play_reverse then
- if props.pos.y <= 1081 or remove_callback then
- props.pos.y = 1080
- obs.obs_sceneitem_set_pos(props.item, props.pos)
- remove_callback = true
- else
- props.pos.y = props.pos.y - tick
- obs.obs_sceneitem_set_pos(props.item, props.pos)
- end
- else
- if props.pos.y >= (1079 + props.bounds.y) or remove_callback then
- props.pos.y = 1080 + props.bounds.y
- obs.obs_sceneitem_set_pos(props.item, props.pos)
- remove_callback = true
- else
- props.pos.y = props.pos.y + tick
- obs.obs_sceneitem_set_pos(props.item, props.pos)
- end
- end
- end
- if remove_callback then
- obs.remove_current_callback()
- end
- end
- function slide_right()
- local remove_callback = false
- for _,props in pairs(animate_props) do
- local dist = props.bounds.x
- local tick = dist/20
- if not play_reverse then
- if props.pos.x >= -1 or remove_callback then
- props.pos.x = 0
- obs.obs_sceneitem_set_pos(props.item, props.pos)
- remove_callback = true
- else
- props.pos.x = props.pos.x + tick
- obs.obs_sceneitem_set_pos(props.item, props.pos)
- end
- else
- if props.pos.x <= -(props.bounds.x - 1) or remove_callback then
- props.pos.x = -props.bounds.x
- obs.obs_sceneitem_set_pos(props.item, props.pos)
- remove_callback = true
- else
- props.pos.x = props.pos.x - tick
- obs.obs_sceneitem_set_pos(props.item, props.pos)
- end
- end
- end
- if remove_callback then
- obs.remove_current_callback()
- end
- end
- function slide_left()
- local remove_callback = false
- for _, props in pairs(animate_props) do
- local dist = props.bounds.x
- local tick = dist/20
- if not play_reverse then
- if props.pos.x <= 1921 or remove_callback then
- props.pos.x = 1920
- obs.obs_sceneitem_set_pos(props.item, props.pos)
- remove_callback = true
- else
- props.pos.x = props.pos.x - tick
- obs.obs_sceneitem_set_pos(props.item, props.pos)
- end
- else
- if props.pos.x >= 1919 + props.bounds.x or remove_callback then
- props.pos.x = 1920 + props.bounds.x
- obs.obs_sceneitem_set_pos(props.item, props.pos)
- remove_callback = true
- else
- props.pos.x = props.pos.x + tick
- obs.obs_sceneitem_set_pos(props.item, props.pos)
- end
- end
- end
- if remove_callback then
- obs.remove_current_callback()
- end
- end
- -- The "Instant Replay" hotkey callbacks
- function instant_replay_left(pressed)
- if not pressed then
- return
- end
- instant_replay("left")
- end
- function instant_replay_right(pressed)
- if not pressed then
- return
- end
- instant_replay("right")
- end
- function instant_replay_both(pressed)
- if not pressed then
- return
- end
- instant_replay("both")
- end
- function instant_replay(pressed)
- hotkey_pressed = pressed
- local replay_buffer = obs.obs_frontend_get_replay_buffer_output()
- if replay_buffer ~= nil then
- -- Call the procedure of the replay buffer named "get_last_replay" to
- -- get the last replay created by the replay buffer
- local ph = obs.obs_output_get_proc_handler(replay_buffer)
- obs.proc_handler_call(ph, "save", nil)
- -- Set a 1-second timer to attempt playback every 1 second
- -- until the replay is available
- if obs.obs_output_active(replay_buffer) then
- attempts = 0
- obs.timer_add(try_play, 1000)
- else
- obs.script_log(obs.LOG_WARNING, "Tried to save an instant replay, but the replay buffer is not active!")
- end
- obs.obs_output_release(replay_buffer)
- else
- obs.script_log(obs.LOG_WARNING, "Tried to save an instant replay, but found no active replay buffer!")
- end
- end
- ----------------------------------------------------------
- -- A function named script_update will be called when settings are changed
- function script_update(settings)
- source_names.left = obs.obs_data_get_string(settings, "v_source_left")
- source_names.right = obs.obs_data_get_string(settings, "v_source_right")
- source_names.both = obs.obs_data_get_string(settings, "v_source_both")
- source_names.left_bg = obs.obs_data_get_string(settings, "i_source_left")
- source_names.right_bg = obs.obs_data_get_string(settings, "i_source_right")
- source_names.both_bg = obs.obs_data_get_string(settings, "i_source_both")
- end
- -- A function named script_description returns the description shown to
- -- the user
- function script_description()
- return "VVVVHow to use this script:\n\n Step 1: Load this script (hey, you did that already!)\n Step 2: Go to File -> Settings -> Hotkeys and add hotkeys for the 3 Instant Replay fields (I recommend F1-F3)\n Step 3: Whenever you want to make a replay, press the hotkey corresponding to the runner (or runners) you want to showcase\n\nThat's it!\n\n\n-- Made by JHobz. Contact on Discord with questions/bug reports."
- 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()
- -- Find replay sources
- local lvs = obs.obs_properties_add_list(props, "v_source_left", "Left Replay Source", obs.OBS_COMBO_TYPE_EDITABLE, obs.OBS_COMBO_FORMAT_STRING)
- local rvs = obs.obs_properties_add_list(props, "v_source_right", "Right Replay Source", obs.OBS_COMBO_TYPE_EDITABLE, obs.OBS_COMBO_FORMAT_STRING)
- local bvs = obs.obs_properties_add_list(props, "v_source_both", "Both Replay Source", obs.OBS_COMBO_TYPE_EDITABLE, obs.OBS_COMBO_FORMAT_STRING)
- local lis = obs.obs_properties_add_list(props, "i_source_left", "Left Replay Background", obs.OBS_COMBO_TYPE_EDITABLE, obs.OBS_COMBO_FORMAT_STRING)
- local ris = obs.obs_properties_add_list(props, "i_source_right", "Right Replay Background", obs.OBS_COMBO_TYPE_EDITABLE, obs.OBS_COMBO_FORMAT_STRING)
- local bis = obs.obs_properties_add_list(props, "i_source_both", "Both Replay Background", 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 name = obs.obs_source_get_name(source)
- if string.match(name, "^REPLAY") then
- obs.obs_property_list_add_string(lvs, name, name)
- obs.obs_property_list_add_string(rvs, name, name)
- obs.obs_property_list_add_string(bvs, name, name)
- end
- elseif source_id == "image_source" then
- local name = obs.obs_source_get_name(source)
- if string.match(name, "Replay BG") then
- obs.obs_property_list_add_string(lis, name, name)
- obs.obs_property_list_add_string(ris, name, name)
- obs.obs_property_list_add_string(bis, name, name)
- end
- 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)
- -- Register hotkeys
- hotkey_ids[1] = obs.obs_hotkey_register_frontend("instant_replay_left.trigger", "Instant Replay (Left)", instant_replay_left)
- local hotkey_save_array1 = obs.obs_data_get_array(settings, "instant_replay_left.trigger")
- obs.obs_hotkey_load(hotkey_ids[1], hotkey_save_array1)
- obs.obs_data_array_release(hotkey_save_array1)
- hotkey_ids[2] = obs.obs_hotkey_register_frontend("instant_replay_right.trigger", "Instant Replay (Right)", instant_replay_right)
- local hotkey_save_array2 = obs.obs_data_get_array(settings, "instant_replay_right.trigger")
- obs.obs_hotkey_load(hotkey_ids[2], hotkey_save_array2)
- obs.obs_data_array_release(hotkey_save_array2)
- hotkey_ids[3] = obs.obs_hotkey_register_frontend("instant_replay_both.trigger", "Instant Replay (Both)", instant_replay_both)
- local hotkey_save_array3 = obs.obs_data_get_array(settings, "instant_replay_both.trigger")
- obs.obs_hotkey_load(hotkey_ids[3], hotkey_save_array3)
- obs.obs_data_array_release(hotkey_save_array3)
- 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_array1 = obs.obs_hotkey_save(hotkey_ids[1])
- obs.obs_data_set_array(settings, "instant_replay_left.trigger", hotkey_save_array1)
- obs.obs_data_array_release(hotkey_save_array1)
- local hotkey_save_array2 = obs.obs_hotkey_save(hotkey_ids[2])
- obs.obs_data_set_array(settings, "instant_replay_right.trigger", hotkey_save_array2)
- obs.obs_data_array_release(hotkey_save_array2)
- local hotkey_save_array3 = obs.obs_hotkey_save(hotkey_ids[3])
- obs.obs_data_set_array(settings, "instant_replay_both.trigger", hotkey_save_array3)
- obs.obs_data_array_release(hotkey_save_array3)
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement