Checkout the stream @ https://www.twitch.tv/codingzeal
Stream Recap
After getting familiar enough with Lua to be able to read code it was now time to take a look at OBS Plugins scripted in Lua. I spent sometime go through a couple of plugins and seeing how they interface with the OBS C methods.
Once I had a good enough idea of how an OBS plugin is made and the various methods I'll need to use, I started my work on doing the Video Gallery. Afterward, I start tackling the configuration menu so that a user can apply settings and select media sources.
Stream Standup
Any interesting tech things this week
- https://sorbet.org/ - Add type checking to Ruby application, kinda like what you do with TypeScript
- Great introduction article to React Hook starting from how components we first made when React was introduced. https://tylermcginnis.com/why-react-hooks
- Example Github Action for testing your Rails application with Postgres https://andycroll.com/ruby/github-actions-ci-for-rails-with-postgresql/
Notes
Lua
If you need a cheat sheet Lua
OBS Plugin Scripting
https://obsproject.com/docs/scripting.html
I have two ideas for possible OBS plugins.
Video Gallery Plugin - Right OBS has an image gallery plugin to you can cycle through different images. But you cant do this with videos.
Feature Ideas:
- Want to be able to select multiple video sources for display
-
Want to have a flag if you want it to loop
Maybe even have a loop limit
Add a timer to just cap how long its displayed
Stream Closed Captioner Plugin - It will take the text streamed from the Stream CC server and add it to the closed captioning audio channel thing
Lua Example Plugin Notes:
countdown.lua
- Great example of having a configurable plugin. Show how to display the property fields to user input. Handling timers and when a source activated or deactivated.
clock-source.lua
- This example showcases loading multiple image assets and positioning them in a source on each tick of the video render. Creates a brand new source to select and show.
instant-replay.lua
- In this example it is loading a video (from replay) into a media source for display. I think this example might be what I need in order to implement the video gallery idea I have.
To send log message:
obs.script_log(obs.LOG_DEBUG, "heyu")
Found an example of going through the editable list
here dmadison/OBS-ChatSpam
Shoutouts and Thanks
DoctorArgus, AntiPixelated, LilyHazel for hanging out
Future action items
- Continue working the Lua script for Video Gallery
- Finish trying to construct a Lua array from the video selected in the editable list
- Figure out how to get them to display in the selected media source
Current Code for Reference
Current Work in Progress Code 100% not finished so take it with a grain of salt
obs = obslua
source_name = ""
total_seconds = 0
cur_seconds = 0
activated = false
loop = true
videos = {}
last_video = ""
hotkey_id = obs.OBS_INVALID_HOTKEY_ID
filer_filter = "*.mp4 *.ts *.mov *.flv *.mkv *.avi *.gif *.webm"
-- Function to set the time text
function set_time_text()
if cur_seconds < 1 then
-- Do something to stop after end is reached
end
if media ~= last_video then
local source = obs.obs_get_source_by_name(source_name)
if source ~= nil then
local settings = obs.obs_data_create()
obs.obs_data_set_string(settings, "text", text)
obs.obs_source_update(source, settings)
obs.obs_data_release(settings)
obs.obs_source_release(source)
end
end
last_video = media
end
function timer_callback()
cur_seconds = cur_seconds - 1
if cur_seconds < 0 then
obs.remove_current_callback()
cur_seconds = 0
end
set_time_text()
end
function activate(activating)
if activated == activating then
return
end
activated = activating
if activating then
cur_seconds = total_seconds
set_time_text()
obs.timer_add(timer_callback, 1000)
else
obs.timer_remove(timer_callback)
end
end
-- Called when a source is activated/deactivated
function activate_signal(cd, activating)
local source = obs.calldata_source(cd, "source")
if source ~= nil then
local name = obs.obs_source_get_name(source)
if (name == source_name) then
activate(activating)
end
end
end
function source_activated(cd)
activate_signal(cd, true)
end
function source_deactivated(cd)
activate_signal(cd, false)
end
function reset(pressed)
if not pressed then
return
end
activate(false)
local source = obs.obs_get_source_by_name(source_name)
if source ~= nil then
local active = obs.obs_source_active(source)
obs.obs_source_release(source)
activate(active)
end
end
function reset_button_clicked(props, p)
reset(true)
return false
end
----------------------------------------------------------
-- A function named script_properties defines the properties that the user
-- can change for the entire script module itself
function script_properties()
local props = obs.obs_properties_create()
obs.obs_properties_add_int(props, "duration", "Duration (minutes)", 1, 100000, 1)
-- Crearte Dropdown Selector
local media_dropdown = obs.obs_properties_add_list(props, "source", "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" or source_id == "vlc_source" then
local name = obs.obs_source_get_name(source)
obs.obs_property_list_add_string(media_dropdown, name, name)
end
end
end
obs.source_list_release(sources)
obs.obs_properties_add_editable_list(props, "video_sources", "Videos for gallery", obs.OBS_EDITABLE_LIST_TYPE_FILES, filer_filter, script_path())
obs.obs_properties_add_bool(props, "loop_videos", "Loop Gallery")
-- obs.obs_properties_add_text(props, "stop_text", "Final Text", obs.OBS_TEXT_DEFAULT)
obs.obs_properties_add_button(props, "reset_button", "Reset", reset_button_clicked)
return props
end
-- A function named script_update will be called when settings are changed
function script_update(settings)
obs.script_log(obs.LOG_DEBUG, "Values Set")
activate(false)
-- total_seconds = obs.obs_data_get_int(settings, "duration") * 60
-- stop_text = obs.obs_data_get_string(settings, "stop_text")
source_name = obs.obs_data_get_string(settings, "source")
loop = obs.obs_data_get_bool(settings, "loop_videos")
-- Grab the video from what was set in the editable list
selected_videos = obs.obs_data_get_array(settings, "video_sources")
num_videos = obs.obs_data_array_count(selected_videos)
-- Loop through the array so that we construct a Lua version
for i = 1, num_videos do
video_obj = obs.obs_data_array_item(selected_videos, i)
videos[i] = obs.obs_data_get_string(video_obj, "value")
end
-- Dont forget to garbage collect
obs.obs_data_array_release(selected_videos)
reset(true)
end
-- A function named script_defaults will be called to set the default settings
function script_defaults(settings)
obs.obs_data_set_default_int(settings, "duration", 5)
obs.obs_data_set_default_bool(settings, "loop_videos", true)
-- obs.obs_data_set_default_string(settings, "stop_text", "Starting soon (tm)")
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)
end
-- A function named script_description returns the description shown to
-- the user
function script_description()
return "Create a video gallery and have full control how its displayed."
end
-- a function named script_load will be called on startup
function script_load(settings)
-- Connect hotkey and activation/deactivation signal callbacks
--
-- NOTE: These particular script callbacks do not necessarily have to
-- be disconnected, as callbacks will automatically destroy themselves
-- if the script is unloaded. So there's no real need to manually
-- disconnect callbacks that are intended to last until the script is
-- unloaded.
local sh = obs.obs_get_signal_handler()
obs.signal_handler_connect(sh, "source_activate", source_activated)
obs.signal_handler_connect(sh, "source_deactivate", source_deactivated)
end
Top comments (0)