Русский
Русский
English
Статистика
Реклама

Из песочницы OBS Studio Lua Скриптинг

Всем привет, в этом руководстве рассмотрим создание скриптов для OBS на языке Lua.


Скриптинг в OBS доступен начиная с версии 21, на данный момент новейшая 26.0.0-rc3 версия доступна для тестирования.Обновление включает в себя виртуальную веб камеру (пока что только на Windows), улучшенный UI, возможность скриншота любого источника( КДПВ была сделана с помощью этой функции).


image


Описание глобальных функций, API, настроек


Добавить скрипт можно через меню -> Инструменты -> Скрипты -> значок "плюс".
Скрипты могут быть добавлены, перезагружены, удалены в режиме реального времени.


Сходства и различия 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 = obslualocal selected_sourcepos = obs.vec2()switch = falsecounter = 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 propsend

Добавляем пользовательский интерфейс. 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 switchend

Кнопка переключатель и таймер периодического запуска функции в миллисекундах.
Гифка


Исходный код
local obs = obslualocal selected_sourcepos = obs.vec2()switch = falsecounter = 0function on_off()  if switch then     obs.timer_add(move_source_on_scene,50)  else    obs.timer_remove(move_source_on_scene)  end  switch = not switchendfunction 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)endfunction move_button(props,p)  move_source_on_scene()endfunction 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)endfunction 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 propsendfunction 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('Старт')  endend

Словарь с клавишами и функция типа "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)  endend

Сохранение/загрузка изменяющихся горячих клавиш.


function htk_1_cb(pressed)   if pressed then    print('1')  endendfunction htk_2_cb(pressed)   if pressed then    print('2 активно')  else    print('2 не активно')  endendkey_1 = '{"htk_1": [ { "key": "OBS_KEY_1" } ],'key_2 = '"htk_2": [ { "key": "OBS_KEY_2" } ]}'json_s = key_1 .. key_2default_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 = obsluahotkeys = {  htk_stop = "Стоп",  htk_start = "Старт",}hk = {}function hotkey_mapping(hotkey)  if hotkey == "htk_stop" then    print('Стоп')  elseif hotkey == "htk_start" then    print('Старт')  endendfunction htk_1_cb(pressed)   if pressed then    print('1')  endendfunction htk_2_cb(pressed)   if pressed then    print('2 активно')  else    print('2 не активно')  endendkey_1 = '{"htk_1": [ { "key": "OBS_KEY_1" } ],'key_2 = '"htk_2": [ { "key": "OBS_KEY_2" } ]}'json_s = key_1 .. key_2default_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)endfunction 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)  endend

Задачи


Задача на движение по кругу:
На основе скрипта движение по линии, создайте скрипт с движением вокруг часовой/против.


Гифка


Задача на использование кнопок клавиатуры:
На основе скрипта с горячими клавишами, создайте скрипт с переключателем вкл/выкл,
доп кнопкой через JSON, доп кнопкой с комбинацией клавиш через JSON.


Гифка


Ссылки


Источник: habr.com
К списку статей
Опубликовано: 25.09.2020 18:15:34
0

Сейчас читают

Комментариев (0)
Имя
Электронная почта

Работа с видео

Api

Lua

Obs

Obslua

Obs studio

Video

Livestream

Streaming video

Luajit

Стрим

Стриминг

Запись видео

Реальное время

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru