Hey everyone, in this tutorial we will look at scripting for OBS in Lua.
Scripting in OBS is available starting from version 21, at the moment the newest 26.0.0-rc3 version is available for testing. The update includes a virtual webcam (so far only on Windows), an improved UI, the ability to take a screenshot of any source (KDPV was made with using this function).
Description of global functions, API, settings
-> -> -> "".
, , .
c -API
: API, .
: ( ) , .
, "~/obs-studio/basic/scenes".
settings
JSON , // JSON .
:
obslua
— OBSscript_description()
— , HTMLscript_properties()
—script_defaults(settings)
—script_update(settings)
—script_load(settings)
—script_unload()
—script_save(settings)
— , cscript_tick(seconds)
— , secondsscript_path()
—timer_add(callback,milliseconds)
—timer_remove(callback)
— ,remove_current_callback()
: .
local obs = obslua
local selected_source
pos = obs.vec2()
switch = false
counter = 0
, local var
— nil
, pos
— OBS .
function script_properties()
local props = obs.obs_properties_create()
obs.obs_properties_add_button(props, "button1", "/",on_off)
obs.obs_properties_add_button(props, "button2", " ",add_source)
obs.obs_properties_add_button(props, "button3", " +10,0",move_button)
local p = obs.obs_properties_add_list(props, "selected_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_unversioned_id(source)
if source_id == "color_source" then
local name = obs.obs_source_get_name(source)
obs.obs_property_list_add_string(p, name, name)
end
end
end
obs.source_list_release(sources)
return props
end
. obs.obs_properties_add_button(props, "", "",)
, local p = obs.obs_properties_add_list
— , source_id = obs.obs_source_get_unversioned_id(source)
— , obs.source_list_release(sources)
—
function script_update(settings)
selected_source = obs.obs_data_get_string(settings,"selected_source")
end
selected_source
( ) .
function add_source()
current_scene = obs.obs_frontend_get_current_scene()
scene = obs.obs_scene_from_source(current_scene)
settings = obs.obs_data_create()
counter = counter + 1
green = 0xff00ff00
hotkey_data = nil
obs.obs_data_set_int(settings, "width",200)
obs.obs_data_set_int(settings, "height",200)
obs.obs_data_set_int(settings, "color",green)
source = obs.obs_source_create("color_source", "#" .. counter, settings, hotkey_data)
obs.obs_scene_add(scene, source)
obs.obs_scene_release(scene)
obs.obs_data_release(settings)
obs.obs_source_release(source)
end
, , .
function move_source_on_scene()
current_scene = obs.obs_frontend_get_current_scene()
scene = obs.obs_scene_from_source(current_scene)
scene_item = obs.obs_scene_find_source(scene, selected_source)
if scene_item then
dx, dy = 10, 0
obs.obs_sceneitem_get_pos( scene_item, pos) --
pos.x = pos.x + dx
pos.y = pos.y + dy
obs.obs_sceneitem_set_pos(scene_item, pos)
end
obs.obs_scene_release(scene)
end
.
function move_button(props,p)
move_source_on_scene()
end
2 .
function on_off()
if switch then
obs.timer_add(move_source_on_scene,50)
else
obs.timer_remove(move_source_on_scene)
end
switch = not switch
end
.
local obs = obslua
local selected_source
pos = obs.vec2()
switch = false
counter = 0
function on_off()
if switch then
obs.timer_add(move_source_on_scene,50)
else
obs.timer_remove(move_source_on_scene)
end
switch = not switch
end
function add_source()
current_scene = obs.obs_frontend_get_current_scene()
scene = obs.obs_scene_from_source(current_scene)
settings = obs.obs_data_create()
counter = counter + 1
green = 0xff00ff00
hotkey_data = nil
obs.obs_data_set_int(settings, "width",200)
obs.obs_data_set_int(settings, "height",200)
obs.obs_data_set_int(settings, "color",green)
source = obs.obs_source_create("color_source", "#" .. counter, settings, hotkey_data)
obs.obs_scene_add(scene, source)
obs.obs_scene_release(scene)
obs.obs_data_release(settings)
obs.obs_source_release(source)
end
function move_button(props,p)
move_source_on_scene()
end
function move_source_on_scene()
current_scene = obs.obs_frontend_get_current_scene()
scene = obs.obs_scene_from_source(current_scene)
scene_item = obs.obs_scene_find_source(scene, selected_source)
if scene_item then
dx, dy = 10, 0
obs.obs_sceneitem_get_pos( scene_item, pos) --
pos.x = pos.x + dx
pos.y = pos.y + dy
obs.obs_sceneitem_set_pos(scene_item, pos)
end
obs.obs_scene_release(scene)
end
function script_properties()
local props = obs.obs_properties_create()
obs.obs_properties_add_button(props, "button1", "/",on_off)
obs.obs_properties_add_button(props, "button2", " ",add_source)
obs.obs_properties_add_button(props, "button3", "C +10,0",move_button)
local p = obs.obs_properties_add_list(props, "selected_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_unversioned_id(source)
if source_id == "color_source" then
local name = obs.obs_source_get_name(source)
obs.obs_property_list_add_string(p, name, name)
end
end
end
obs.source_list_release(sources)
return props
end
function script_update(settings)
selected_source = obs.obs_data_get_string(settings,"selected_source")
end
: .
, OBS.
hotkeys = {
htk_stop = "",
htk_start = "",
}
hk = {}
function hotkey_mapping(hotkey)
if hotkey == "htk_stop" then
print('')
elseif hotkey == "htk_start" then
print('')
end
end
"switch"
function script_load(settings)
for k, v in pairs(hotkeys) do
hk[k] = obs.obs_hotkey_register_frontend(k, v, function(pressed)
if pressed then
hotkey_mapping(k)
end
end)
a = obs.obs_data_get_array(settings, k)
obs.obs_hotkey_load(hk[k], a)
obs.obs_data_array_release(a)
end
...
function script_save(settings)
for k, v in pairs(hotkeys) do
a = obs.obs_hotkey_save(hk[k])
obs.obs_data_set_array(settings, k, a)
obs.obs_data_array_release(a)
end
end
/ .
function htk_1_cb(pressed)
if pressed then
print('1')
end
end
function htk_2_cb(pressed)
if pressed then
print('2 ')
else
print('2 ')
end
end
key_1 = '{"htk_1": [ { "key": "OBS_KEY_1" } ],'
key_2 = '"htk_2": [ { "key": "OBS_KEY_2" } ]}'
json_s = key_1 .. key_2
default_hotkeys = {
{id='htk_1',des=' 1 ',callback=htk_1_cb},
{id='htk_2',des=' 2 ',callback=htk_2_cb},
}
, , OBS . 1 2.
function script_load(settings)
...
s = obs.obs_data_create_from_json(json_s)
for _,v in pairs(default_hotkeys) do
a = obs.obs_data_get_array(s,v.id)
h = obs.obs_hotkey_register_frontend(v.id,v.des,v.callback)
obs.obs_hotkey_load(h,a)
obs.obs_data_array_release(a)
end
obs.obs_data_release(s)
end
local obs = obslua
hotkeys = {
htk_stop = "",
htk_start = "",
}
hk = {}
function hotkey_mapping(hotkey)
if hotkey == "htk_stop" then
print('')
elseif hotkey == "htk_start" then
print('')
end
end
function htk_1_cb(pressed)
if pressed then
print('1')
end
end
function htk_2_cb(pressed)
if pressed then
print('2 ')
else
print('2 ')
end
end
key_1 = '{"htk_1": [ { "key": "OBS_KEY_1" } ],'
key_2 = '"htk_2": [ { "key": "OBS_KEY_2" } ]}'
json_s = key_1 .. key_2
default_hotkeys = {
{id='htk_1',des=' 1 ',callback=htk_1_cb},
{id='htk_2',des=' 2 ',callback=htk_2_cb},
}
function script_load(settings)
for k, v in pairs(hotkeys) do
hk[k] = obs.obs_hotkey_register_frontend(k, v, function(pressed)
if pressed then
hotkey_mapping(k)
end
end)
a = obs.obs_data_get_array(settings, k)
obs.obs_hotkey_load(hk[k], a)
obs.obs_data_array_release(a)
end
s = obs.obs_data_create_from_json(json_s)
for _,v in pairs(default_hotkeys) do
a = obs.obs_data_get_array(s,v.id)
h = obs.obs_hotkey_register_frontend(v.id,v.des,v.callback)
obs.obs_hotkey_load(h,a)
obs.obs_data_array_release(a)
end
obs.obs_data_release(s)
end
function script_save(settings)
for k, v in pairs(hotkeys) do
a = obs.obs_hotkey_save(hk[k])
obs.obs_data_set_array(settings, k, a)
obs.obs_data_array_release(a)
end
end
:
, /.
:
, /,
JSON, JSON.