OBS Studio Lua Scripting

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).



image



Description of global functions, API, settings



-> -> -> "".

, , .



c -API



: API, .



: ( ) , .



, "~/obs-studio/basic/scenes".



settings JSON , // JSON .



:



  • obslua — OBS
  • script_description() — , HTML
  • script_properties()
  • script_defaults(settings)
  • script_update(settings)
  • script_load(settings)
  • script_unload()
  • script_save(settings) — , c
  • script_tick(seconds) — , seconds
  • script_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 varnil, 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


.

GIF



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


GIF



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




:

, /.



GIF



:

, /,

JSON, JSON.



GIF








All Articles