Added more settings to frame_updater and made it react to 16:9 ratio with showing/hiding frame source. Added JSON parser and an example on how to use it.
This commit is contained in:
parent
a848ba0494
commit
99653c68da
4 changed files with 1715 additions and 45 deletions
10
README.md
10
README.md
|
|
@ -12,9 +12,19 @@ Enjoy!
|
||||||
## [frame_updater.lua](https://github.com/4aiman/obs_scripts/blob/main/frame_updater.lua)
|
## [frame_updater.lua](https://github.com/4aiman/obs_scripts/blob/main/frame_updater.lua)
|
||||||
Checks the size of a game capture source and updates filepath of an image source to match that.<br>
|
Checks the size of a game capture source and updates filepath of an image source to match that.<br>
|
||||||
Right now only 2 resolutions are supported ad nothing is in the GUI apart from upadte interval and 2 sources: the game capture one and the frame/overlay one.<br>
|
Right now only 2 resolutions are supported ad nothing is in the GUI apart from upadte interval and 2 sources: the game capture one and the frame/overlay one.<br>
|
||||||
|
Be sure to select the folder with your frames.<br>
|
||||||
|
If you want to change your crop filter name, then load the script and *refresh it*. That's the only way to update the list in OBS properties after it's been created, since one can't update a list on properties update. (In reality refreshing recreates the properties object)<br>
|
||||||
Tinker with it to suit your needs.
|
Tinker with it to suit your needs.
|
||||||
|
|
||||||
## [death_counter.lua](https://github.com/4aiman/obs_scripts/blob/main/death_counter.lua)
|
## [death_counter.lua](https://github.com/4aiman/obs_scripts/blob/main/death_counter.lua)
|
||||||
Uses one of the text sources as a death counter.<br>
|
Uses one of the text sources as a death counter.<br>
|
||||||
Set up a hotkey and press it for the counter to go up.<br>
|
Set up a hotkey and press it for the counter to go up.<br>
|
||||||
Reset the counter in the script setting window.
|
Reset the counter in the script setting window.
|
||||||
|
|
||||||
|
## [obs_source_set_settings_fix.lua](https://github.com/4aiman/obs_scripts/blob/main/obs_source_set_settings_fix.lua)
|
||||||
|
A helper file that can help one iterate OBS source's properties (also works for filters, as those are treated as sources internally).<br>
|
||||||
|
Find details inside the file.
|
||||||
|
|
||||||
|
## [DEPS](https://github.com/4aiman/obs_scripts/blob/main/deps)
|
||||||
|
This folder contains all the Lua scripts that will help circumvent crappy desing of Lua bindings in OBS.<br>
|
||||||
|
|
||||||
|
|
|
||||||
1559
deps/JSON.lua
vendored
Normal file
1559
deps/JSON.lua
vendored
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -7,23 +7,28 @@ total_seconds = 0
|
||||||
cur_seconds = 0
|
cur_seconds = 0
|
||||||
-- names of the sources that are being synced up
|
-- names of the sources that are being synced up
|
||||||
master_source_name = ""
|
master_source_name = ""
|
||||||
|
padding_filter_name = "pad to frame"
|
||||||
slave_source_name = ""
|
slave_source_name = ""
|
||||||
|
-- actual sources
|
||||||
|
master_combobox = nil
|
||||||
|
slave_combobox = nil
|
||||||
|
master_filers_combobox = nil
|
||||||
|
global_props = nil
|
||||||
|
|
||||||
-- seconds between sync attempts
|
-- seconds between sync attempts
|
||||||
sync_delay = 5
|
sync_delay = 5
|
||||||
activated = false
|
activated = false
|
||||||
|
|
||||||
-- padding filter name
|
|
||||||
padding_filter_name = "pad to frame"
|
|
||||||
-- common path to all your frames
|
-- common path to all your frames
|
||||||
basic_fmames_path = "add yours"
|
base_fmames_path = ""
|
||||||
|
|
||||||
sizes_3_by_2 = {{width = 1440, height = 960}}
|
sizes_3_by_2 = {{width = 1440, height = 960}}
|
||||||
sizes_3_by_4 = {{width = 1280, height = 960}}
|
sizes_3_by_4 = {{width = 1280, height = 960}}
|
||||||
|
sizes_16_by_9 = {{width = 1920, height = 1080}}
|
||||||
|
|
||||||
-- a hotkey to force synchronisation of a given pair
|
-- a hotkey to force synchronisation of a given pair
|
||||||
hotkey_id = obs.OBS_INVALID_HOTKEY_ID
|
hotkey_id = obs.OBS_INVALID_HOTKEY_ID
|
||||||
|
|
||||||
|
|
||||||
function string.split(inputstr, sep)
|
function string.split(inputstr, sep)
|
||||||
if sep == nil then
|
if sep == nil then
|
||||||
sep = "%s"
|
sep = "%s"
|
||||||
|
|
@ -48,39 +53,70 @@ function timer_callback()
|
||||||
|
|
||||||
if master_source~= nil and slave_source~= nil then
|
if master_source~= nil and slave_source~= nil then
|
||||||
local master_filters = obs.obs_source_enum_filters(master_source)
|
local master_filters = obs.obs_source_enum_filters(master_source)
|
||||||
-- obs_source_get_filter_by_name
|
|
||||||
|
local master_height = obs.obs_source_get_height(master_source)
|
||||||
|
local master_width = obs.obs_source_get_width(master_source)
|
||||||
|
local padding_left = 0
|
||||||
|
local padding_top = 0
|
||||||
|
local actual_height = master_height
|
||||||
|
local actual_width = master_width
|
||||||
|
|
||||||
|
-- obs_source_get_filter_by_name
|
||||||
for idx, filter in pairs(master_filters) do
|
for idx, filter in pairs(master_filters) do
|
||||||
local filter_name = obs.obs_source_get_name(filter)
|
local filter_name = obs.obs_source_get_name(filter)
|
||||||
if filter_name == padding_filter_name then
|
if filter_name == padding_filter_name then
|
||||||
local filter_props = obs.obs_source_get_settings(filter)
|
-- check if the padding filter is enabled at all
|
||||||
local master_height = obs.obs_source_get_height(master_source)
|
if obs.obs_source_enabled(filter) == true then
|
||||||
local master_width = obs.obs_source_get_width(master_source)
|
-- if it is - modify actual size with regard to set padding
|
||||||
local padding_left = obs.obs_data_get_int(filter_props, 'left')
|
local filter_props = obs.obs_source_get_settings(filter)
|
||||||
local padding_top = obs.obs_data_get_int(filter_props, 'top')
|
padding_left = obs.obs_data_get_int(filter_props, 'left')
|
||||||
local actual_height = master_height + padding_top
|
padding_top = obs.obs_data_get_int(filter_props, 'top')
|
||||||
local actual_width = master_width + padding_left
|
actual_height = master_height + padding_top
|
||||||
|
actual_width = master_width + padding_left
|
||||||
|
else
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--print(master_width .. "x"..master_height ..'; '.. (padding_left or 0) .. ':' .. (padding_top or 0) .. '; ' .. actual_width .. 'x' .. actual_height)
|
||||||
|
|
||||||
if sizing_mode ~= true then
|
if sizing_mode ~= true then
|
||||||
for id, size in ipairs (sizes_3_by_2) do
|
for id, size in ipairs (sizes_3_by_2) do
|
||||||
if actual_width == size.width and actual_height == size.height then
|
if actual_width == size.width and actual_height == size.height then
|
||||||
--print("it's 3:2 ratio!")
|
--print("it's 3:2 ratio!")
|
||||||
sizing_mode = 'frame_3x2'
|
sizing_mode = 'frame_3x2'
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if sizing_mode ~= true then
|
||||||
|
for id, size in ipairs (sizes_3_by_4) do
|
||||||
|
if actual_width == size.width and actual_height == size.height then
|
||||||
|
--print("it's 4:3 ratio!")
|
||||||
|
sizing_mode = 'frame_4x3'
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if sizing_mode ~= true then
|
||||||
|
for id, size in ipairs (sizes_16_by_9) do
|
||||||
|
if actual_width == size.width and actual_height == size.height then
|
||||||
|
--print("it's 16:9 ratio!")
|
||||||
|
-- obs.obs_source_enabled doesn't want the second param, despite what's said in the docs
|
||||||
|
-- obs.obs_source_active is readonly as per documentation, but only returns false
|
||||||
|
-- obs.obs_source_set_hidden does nothing
|
||||||
|
-- obs.obs_source_dec_showing does nothing
|
||||||
|
-- obs.obs_source_dec_active does nothing
|
||||||
|
-- obs.obs_scene_from_source doesn't produce anything, making it impossible to work with any scene items despite being used is some people's code
|
||||||
|
obs.obs_source_set_enabled(slave_source, false)
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
if sizing_mode ~= true then
|
|
||||||
for id, size in ipairs (sizes_3_by_4) do
|
|
||||||
if actual_width == size.width and actual_height == size.height then
|
|
||||||
--print("it's 4:3 ratio!")
|
|
||||||
sizing_mode = 'frame_4x3'
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if sizing_mode ~= false then
|
if sizing_mode ~= false then
|
||||||
local slave_props = obs.obs_source_get_settings(slave_source)
|
local slave_props = obs.obs_source_get_settings(slave_source)
|
||||||
|
|
@ -93,12 +129,13 @@ function timer_callback()
|
||||||
if month >8 and month < 12 then season = 'autumn' end
|
if month >8 and month < 12 then season = 'autumn' end
|
||||||
if month >11 or month < 3 then season = 'winter' end
|
if month >11 or month < 3 then season = 'winter' end
|
||||||
|
|
||||||
local frame_path = basic_fmames_path .. sizing_mode .. '_' .. season .. ".png"
|
local frame_path = base_fmames_path .. sizing_mode .. '_' .. season .. ".png"
|
||||||
|
|
||||||
if image ~= frame_path then
|
if image ~= frame_path then
|
||||||
obs.obs_data_set_string(slave_props, 'file', frame_path)
|
obs.obs_data_set_string(slave_props, 'file', frame_path)
|
||||||
obs.obs_source_update(slave_source, slave_props)
|
obs.obs_source_update(slave_source, slave_props)
|
||||||
end
|
end
|
||||||
|
obs.obs_source_set_enabled(slave_source, true)
|
||||||
end
|
end
|
||||||
|
|
||||||
obs.obs_source_release(master_source)
|
obs.obs_source_release(master_source)
|
||||||
|
|
@ -134,13 +171,16 @@ end
|
||||||
-- can change for the entire script module itself
|
-- can change for the entire script module itself
|
||||||
function script_properties()
|
function script_properties()
|
||||||
-- create properties dialogue
|
-- create properties dialogue
|
||||||
local props = obs.obs_properties_create()
|
global_props = obs.obs_properties_create()
|
||||||
-- add sync delay settings
|
-- add sync delay settings
|
||||||
obs.obs_properties_add_int(props, "sync_delay", "Sync cycle (seconds)", 1, 3600, 1)
|
obs.obs_properties_add_int(global_props, "sync_delay", "Sync cycle (seconds)", 1, 3600, 1)
|
||||||
-- add main source combobox
|
-- add main source global_props
|
||||||
local master = obs.obs_properties_add_list(props, "master_source", "Game source", obs.OBS_COMBO_TYPE_EDITABLE, obs.OBS_COMBO_FORMAT_STRING)
|
master_combobox = obs.obs_properties_add_list(global_props, "master_source", "Game source", obs.OBS_COMBO_TYPE_EDITABLE, obs.OBS_COMBO_FORMAT_STRING)
|
||||||
|
-- add master filters list; a more convenient way to select the padding filter
|
||||||
|
master_filers_combobox = obs.obs_properties_add_list(global_props, "filter_source", "Pading filter", obs.OBS_COMBO_TYPE_EDITABLE, obs.OBS_COMBO_FORMAT_STRING )
|
||||||
-- add the source that will sync up with the main one
|
-- add the source that will sync up with the main one
|
||||||
local slave = obs.obs_properties_add_list(props, "slave_source", "Frame source", obs.OBS_COMBO_TYPE_EDITABLE, obs.OBS_COMBO_FORMAT_STRING)
|
slave_combobox = obs.obs_properties_add_list(global_props, "slave_source", "Frame source", obs.OBS_COMBO_TYPE_EDITABLE, obs.OBS_COMBO_FORMAT_STRING)
|
||||||
|
frame_path_edit = obs.obs_properties_add_path(global_props, "frame_path_edit", "Frame Folder", obs.OBS_PATH_DIRECTORY, nil ,nil)
|
||||||
-- get all the sources
|
-- get all the sources
|
||||||
local sources = obs.obs_enum_sources()
|
local sources = obs.obs_enum_sources()
|
||||||
if sources ~= nil then
|
if sources ~= nil then
|
||||||
|
|
@ -152,32 +192,48 @@ function script_properties()
|
||||||
then
|
then
|
||||||
local name = obs.obs_source_get_name(source)
|
local name = obs.obs_source_get_name(source)
|
||||||
if source_id == "game_capture" then
|
if source_id == "game_capture" then
|
||||||
obs.obs_property_list_add_string(master, name, name)
|
obs.obs_property_list_add_string(master_combobox, name, name)
|
||||||
end
|
end
|
||||||
if source_id == "image_source" then
|
if source_id == "image_source" then
|
||||||
obs.obs_property_list_add_string(slave, name, name)
|
obs.obs_property_list_add_string(slave_combobox, name, name)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
if master_source_name ~= '' then
|
||||||
|
local master_source = obs.obs_get_source_by_name(master_source_name)
|
||||||
|
if master_source~= nil and master_filers_combobox ~= nil then
|
||||||
|
local master_filters = obs.obs_source_enum_filters(master_source)
|
||||||
|
for idx, filter in pairs(master_filters) do
|
||||||
|
local filter_name = obs.obs_source_get_name(filter)
|
||||||
|
obs.obs_property_list_add_string(master_filers_combobox, filter_name, filter_name)
|
||||||
|
end
|
||||||
|
obs.obs_source_release(master_source)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- they say it's important to release sources
|
-- they say it's important to release sources
|
||||||
obs.source_list_release(sources)
|
obs.source_list_release(sources)
|
||||||
|
|
||||||
return props
|
return global_props
|
||||||
end
|
end
|
||||||
|
|
||||||
-- A function named script_description returns the description shown to
|
-- A function named script_description returns the description shown to
|
||||||
-- the user
|
-- the user
|
||||||
function script_description()
|
function script_description()
|
||||||
return "This script allows one to automatically change 'frames' depending on a game capture source's size.\n\nThe idea is to have several overlays for different aspect ratios of the game capture source and auto-select them dependinf on that.\nJust pick some overlays below for every aspect you'd like to have, and enjoy automation.\n\nMade by 4aiman"
|
return "This script allows one to automatically change 'frames' depending on a game capture source's size.\n\nThe idea is to have several overlays for different aspect ratios of the game capture source and auto-select them dependinf on that.\nJust pick some overlays below for every aspect you'd like to have, and enjoy automation.\n\nOnce the Game source is set *refresh* the script in order to be able to select the crop filter.\n\nMade by 4aiman"
|
||||||
end
|
end
|
||||||
|
|
||||||
-- A function named script_update will be called when settings are changed
|
-- A function named script_update will be called when settings are changed
|
||||||
function script_update(settings)
|
function script_update(settings)
|
||||||
total_seconds = obs.obs_data_get_int(settings, "sync_delay")
|
total_seconds = obs.obs_data_get_int(settings, "sync_delay")
|
||||||
master_source_name = obs.obs_data_get_string(settings, "master_source")
|
master_source_name = obs.obs_data_get_string(settings, "master_source")
|
||||||
|
padding_filter_name = obs.obs_data_get_string(settings, "filter_source")
|
||||||
slave_source_name = obs.obs_data_get_string(settings, "slave_source")
|
slave_source_name = obs.obs_data_get_string(settings, "slave_source")
|
||||||
print("Frame Synchronizer script upadted. Delay has been set to " .. total_seconds .. '; Master source is now "' .. master_source_name .. '"; Slave source is now "' .. slave_source_name ..'".')
|
base_fmames_path = obs.obs_data_get_string(settings, "frame_path_edit") .. '/'
|
||||||
|
print("Frame Synchronizer script upadted. Delay has been set to " .. total_seconds .. '; Master source is now "' .. master_source_name .. '; Filter source is now "' .. padding_filter_name .. '"; Slave source is now "' .. slave_source_name ..'".')
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
45
obs_source_set_settings_fix.lua
Normal file
45
obs_source_set_settings_fix.lua
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
--[[
|
||||||
|
|
||||||
|
Issue:
|
||||||
|
One can't iterate over a source properties in Lua
|
||||||
|
|
||||||
|
Why it happens:
|
||||||
|
-- obs.obs_get_source_properties always returns nill
|
||||||
|
-- obs.obs_source_get_settings can't be iterated over
|
||||||
|
-- obs_properties_first can be used, but obs_properties_next expects a pointer while Lua bindings operate with objects
|
||||||
|
-- OBS devs ignored issues aimed to fix this for several years
|
||||||
|
|
||||||
|
Solution accepted by the OBS devs:
|
||||||
|
Use FFI to create a second wrapper for something that an already embedded LUa bindings should give access to.
|
||||||
|
|
||||||
|
My solution:
|
||||||
|
Use json-lua by tiye (https://github.com/tiye/json-lua/tree/main) to make JSON dataiteratable
|
||||||
|
|
||||||
|
How to use:
|
||||||
|
- add these lines to any of your scripts to be able to iterate over source properties through lua
|
||||||
|
- work with native Lua tables using 2 new methods
|
||||||
|
|
||||||
|
|
||||||
|
]]
|
||||||
|
|
||||||
|
-- load JSON
|
||||||
|
json = require("deps.JSON")
|
||||||
|
|
||||||
|
-- helper to get the settings of a source
|
||||||
|
obs.obs_source_get_settings_json = function (source)
|
||||||
|
local properties = obs.obs_source_get_settings(source)
|
||||||
|
local json_encoded = obs.obs_data_get_json(properties)
|
||||||
|
local data = json:decode(json_encoded)
|
||||||
|
return data
|
||||||
|
end
|
||||||
|
|
||||||
|
-- helper to set the settings of a source
|
||||||
|
obs.obs_source_set_settings_json = function (source, json_properties)
|
||||||
|
local properties = obs.obs_source_get_settings(source)
|
||||||
|
for key, value in pairs(json_properties) do
|
||||||
|
obs.obs_data_set_string(properties, key, value)
|
||||||
|
end
|
||||||
|
obs.obs_source_update(slave_source, slave_props)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue