instant-replay.lua 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. obs = obslua
  2. source_name = ""
  3. hotkey_id = obs.OBS_INVALID_HOTKEY_ID
  4. attempts = 0
  5. last_replay = ""
  6. ----------------------------------------------------------
  7. function try_play()
  8. local replay_buffer = obs.obs_frontend_get_replay_buffer_output()
  9. if replay_buffer == nil then
  10. obs.remove_current_callback()
  11. return
  12. end
  13. -- Call the procedure of the replay buffer named "get_last_replay" to
  14. -- get the last replay created by the replay buffer
  15. local cd = obs.calldata_create()
  16. local ph = obs.obs_output_get_proc_handler(replay_buffer)
  17. obs.proc_handler_call(ph, "get_last_replay", cd)
  18. local path = obs.calldata_string(cd, "path")
  19. obs.calldata_destroy(cd)
  20. obs.obs_output_release(replay_buffer)
  21. if path == last_replay then
  22. path = nil
  23. end
  24. -- If the path is valid and the source exists, update it with the
  25. -- replay file to play back the replay. Otherwise, stop attempting to
  26. -- replay after 10 retries
  27. if path == nil then
  28. attempts = attempts + 1
  29. if attempts >= 10 then
  30. obs.remove_current_callback()
  31. end
  32. else
  33. last_replay = path
  34. local source = obs.obs_get_source_by_name(source_name)
  35. if source ~= nil then
  36. local settings = obs.obs_data_create()
  37. source_id = obs.obs_source_get_id(source)
  38. if source_id == "ffmpeg_source" then
  39. obs.obs_data_set_string(settings, "local_file", path)
  40. obs.obs_data_set_bool(settings, "is_local_file", true)
  41. -- updating will automatically cause the source to
  42. -- refresh if the source is currently active
  43. obs.obs_source_update(source, settings)
  44. elseif source_id == "vlc_source" then
  45. -- "playlist"
  46. array = obs.obs_data_array_create()
  47. item = obs.obs_data_create()
  48. obs.obs_data_set_string(item, "value", path)
  49. obs.obs_data_array_push_back(array, item)
  50. obs.obs_data_set_array(settings, "playlist", array)
  51. -- updating will automatically cause the source to
  52. -- refresh if the source is currently active
  53. obs.obs_source_update(source, settings)
  54. obs.obs_data_release(item)
  55. obs.obs_data_array_release(array)
  56. end
  57. obs.obs_data_release(settings)
  58. obs.obs_source_release(source)
  59. end
  60. obs.remove_current_callback()
  61. end
  62. end
  63. -- The "Instant Replay" hotkey callback
  64. function instant_replay(pressed)
  65. if not pressed then
  66. return
  67. end
  68. local replay_buffer = obs.obs_frontend_get_replay_buffer_output()
  69. if replay_buffer ~= nil then
  70. -- Call the procedure of the replay buffer named "get_last_replay" to
  71. -- get the last replay created by the replay buffer
  72. local ph = obs.obs_output_get_proc_handler(replay_buffer)
  73. obs.proc_handler_call(ph, "save", nil)
  74. -- Set a 2-second timer to attempt playback every 1 second
  75. -- until the replay is available
  76. if obs.obs_output_active(replay_buffer) then
  77. attempts = 0
  78. obs.timer_add(try_play, 2000)
  79. else
  80. obs.script_log(obs.LOG_WARNING, "Tried to save an instant replay, but the replay buffer is not active!")
  81. end
  82. obs.obs_output_release(replay_buffer)
  83. else
  84. obs.script_log(obs.LOG_WARNING, "Tried to save an instant replay, but found no active replay buffer!")
  85. end
  86. end
  87. ----------------------------------------------------------
  88. -- A function named script_update will be called when settings are changed
  89. function script_update(settings)
  90. source_name = obs.obs_data_get_string(settings, "source")
  91. end
  92. -- A function named script_description returns the description shown to
  93. -- the user
  94. function script_description()
  95. return "When the \"Instant Replay\" hotkey is triggered, saves a replay with the replay buffer, and then plays it in a media source as soon as the replay is ready. Requires an active replay buffer.\n\nMade by Lain and Exeldro"
  96. end
  97. -- A function named script_properties defines the properties that the user
  98. -- can change for the entire script module itself
  99. function script_properties()
  100. props = obs.obs_properties_create()
  101. local p = obs.obs_properties_add_list(props, "source", "Media Source", obs.OBS_COMBO_TYPE_EDITABLE, obs.OBS_COMBO_FORMAT_STRING)
  102. local sources = obs.obs_enum_sources()
  103. if sources ~= nil then
  104. for _, source in ipairs(sources) do
  105. source_id = obs.obs_source_get_id(source)
  106. if source_id == "ffmpeg_source" then
  107. local name = obs.obs_source_get_name(source)
  108. obs.obs_property_list_add_string(p, name, name)
  109. elseif source_id == "vlc_source" then
  110. local name = obs.obs_source_get_name(source)
  111. obs.obs_property_list_add_string(p, name, name)
  112. else
  113. -- obs.script_log(obs.LOG_INFO, source_id)
  114. end
  115. end
  116. end
  117. obs.source_list_release(sources)
  118. return props
  119. end
  120. -- A function named script_load will be called on startup
  121. function script_load(settings)
  122. hotkey_id = obs.obs_hotkey_register_frontend("instant_replay.trigger", "Instant Replay", instant_replay)
  123. local hotkey_save_array = obs.obs_data_get_array(settings, "instant_replay.trigger")
  124. obs.obs_hotkey_load(hotkey_id, hotkey_save_array)
  125. obs.obs_data_array_release(hotkey_save_array)
  126. end
  127. -- A function named script_save will be called when the script is saved
  128. --
  129. -- NOTE: This function is usually used for saving extra data (such as in this
  130. -- case, a hotkey's save data). Settings set via the properties are saved
  131. -- automatically.
  132. function script_save(settings)
  133. local hotkey_save_array = obs.obs_hotkey_save(hotkey_id)
  134. obs.obs_data_set_array(settings, "instant_replay.trigger", hotkey_save_array)
  135. obs.obs_data_array_release(hotkey_save_array)
  136. end