Всем привет,в этой части руководства рассмотрим :
фильтры, сцены, предметы сцен, Frontend API, создание функциональных фильтров и прочее...

Краткая справка для этой части
-
Источник - Источники используются для рендера аудио/видео, например: захват камеры,игры,звука. С помощью источников можно создавать фильтры,переходы
-
Фильтр - Источник который дополняет другие источники
-
Сцены - Коллекция источников, сцена является источником ( сцену можно добавить как источник в другой сцене)
-
Предмет сцены - конкретный источник в сцене, его можно: перемещать, увеличивать/уменьшать, переворачивать, менять состояние выкл/вкл и.т.д
-
Frontend API - Набор функций который предоставляет OBS Studio, например:
-
подписка на событие о переключении сцен
-
запрос статуса о том, идёт ли стрим/запись
-
вкл/выкл стрим/запись
-
переключение сцен
Фильтры
Типы фильтров так же как и источников, можно узнать через функцию obs_source_get_unversioned_id
| Название |
Внутреннее представление типа |
| Компрессор |
compressor_filter |
| Экспандер |
expander_filter |
| Усиление |
gain_filter |
| Инвертировать полярность |
invert_polarity_filter |
| Лимитер |
limiter_filter |
| Пропускной уровень шума |
noise_gate_filter |
| Шумоподавление |
noise_suppress_filter |
| VST 2.x плагин |
vst_filter |
| Задержка видео (асинхронность) |
async_delay_filter |
| Хромакей |
chroma_key_filter |
| Коррекция цвета |
color_filter |
| Цветовой ключ |
color_key_filter |
| Кадрирование |
crop_filter |
| Маска изображения/Смешивание |
mask_filter |
| Яркостный ключ |
luma_key_filter |
| Задержка отображения |
gpu_delay |
| Масштабирование/Соотношение сторон |
scale_filter |
| Прокрутка |
scroll_filter |
| Увеличить резкость |
sharpness_filter |
В английском варианте : ссылка
Скрипт: изменение параметра прозрачности у фильтра на случайную величину от 1 до 100.
Чтобы узнать название параметра "прозрачность" необходимо добавить фильтр с прозрачностью на какой-нибудь источник, изменить этот параметр. Далее открыть файл коллекции сцен, путь к директории можно узнать через меню OBS:
Справка > Файлы журнала > Показать файлы журнала
далее с этой директории поднимаемся выше, и получаем путь ~/basic>scenes>название_сцены.json
В этом файле ищем color_filter или color_key_filter (оба фильтра могут изменить прозрачность источника).
В строке settings видим что прозрачность записана как opacity.
Ещё один способ узнать название параметра, прочитать исходный код фильтра - ссылка
Находим источник по имени
function add_filter_to_source(random_n)
source = obs.obs_get_source_by_name(source_name)
Создаём настройки с изменением параметра opacity на случайное число
settings = obs.obs_data_create()
obs.obs_data_set_int(settings, "opacity",random_n)
Проверяем существует ли уже фильтр на источнике, если нет добавляем
_color_filter = obs.obs_source_get_filter_by_name(source,"opacity_random")
if _color_filter == nil then -- if not exists
_color_filter = obs.obs_source_create_private( "color_filter", "opacity_random", settings)
obs.obs_source_filter_add(source, _color_filter)
end
Обновляем и освобождаем память
obs.obs_source_update(_color_filter,settings)
obs.obs_source_release(source)
obs.obs_data_release(settings)
obs.obs_source_release(_color_filter)
end
Привязка к горячей клавише
function htk_1_cb(pressed)
if pressed then
n = math.random(1,100)
add_filter_to_source(n)
end
end

Исходный код
local obs = obslua
source_name = ''
function htk_1_cb(pressed)
if pressed then
n = math.random(1,100)
add_filter_to_source(n)
end
end
function add_filter_to_source(random_n)
source = obs.obs_get_source_by_name(source_name)
settings = obs.obs_data_create()
obs.obs_data_set_int(settings, "opacity",random_n)
_color_filter = obs.obs_source_get_filter_by_name(source,"opacity_random")
if _color_filter == nil then -- if not exists
_color_filter = obs.obs_source_create_private( "color_filter", "opacity_random", settings)
obs.obs_source_filter_add(source, _color_filter)
end
obs.obs_source_update(_color_filter,settings)
obs.obs_source_release(source)
obs.obs_data_release(settings)
obs.obs_source_release(_color_filter)
end
function script_properties()
-- source https://raw.githubusercontent.com/insin/obs-bounce/master/bounce.lua
local props = obs.obs_properties_create()
local source = obs.obs_properties_add_list(
props,
'source',
'Source:',
obs.OBS_COMBO_TYPE_EDITABLE,
obs.OBS_COMBO_FORMAT_STRING)
for _, name in ipairs(get_source_names()) do
obs.obs_property_list_add_string(source, name, name)
end
return props
end
function script_update(settings)
source_name = obs.obs_data_get_string(settings, 'source')
end
--- get a list of source names, sorted alphabetically
function get_source_names()
local sources = obs.obs_enum_sources()
local source_names = {}
if sources then
for _, source in ipairs(sources) do
-- exclude Desktop Audio and Mic/Aux by their capabilities
local capability_flags = obs.obs_source_get_output_flags(source)
if bit.band(capability_flags, obs.OBS_SOURCE_DO_NOT_SELF_MONITOR) == 0 and
capability_flags ~= bit.bor(obs.OBS_SOURCE_AUDIO, obs.OBS_SOURCE_DO_NOT_DUPLICATE) then
table.insert(source_names, obs.obs_source_get_name(source))
end
end
end
obs.source_list_release(sources)
table.sort(source_names, function(a, b)
return string.lower(a) < string.lower(b)
end)
return source_names
end
key_1 = '{"htk_1": [ { "key": "OBS_KEY_1" } ]}'
json_s = key_1
default_hotkeys = {
{id='htk_1',des='Кнопка 1 ',callback=htk_1_cb},
}
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
Стоит упомянуть также о функции obs_source_enum_filters с её помощью можно получить
список всех фильтров у конкретного источника, кстати эта функция не работает в obspython,
но об этом чуть позже.
function check()
source = obs.obs_get_source_by_name(source_name)
result = obs.obs_source_enum_filters(source)
for k,v in pairs(result) do
name = obs.obs_source_get_name(v)
print('name'.. name)
end
obs.source_list_release(result)
obs.obs_source_release(source)
end
Эвенты и состояние
Скрипт: звуковое оповещение о том что сцена изменена, с использованием .mp3 файла.
На основе этого скрипта
Создадим функцию для проигрывания звука при смене сцен.
function on_event(event)
if event == obs.OBS_FRONTEND_EVENT_SCENE_CHANGED
then obs_play_sound_release_source()
end
end
Добавим источник медиа, установим настройки: файл alert.mp3 относителен директории нахождения
скрипта, obs_source_set_monitoring_type выставляет прослушивание аудио.
function play_sound()
mediaSource = obs.obs_source_create_private("ffmpeg_source", "Global Media Source", nil)
local s = obs.obs_data_create()
obs.obs_data_set_string(s, "local_file",script_path() .. "alert.mp3")
obs.obs_source_update(mediaSource,s)
obs.obs_source_set_monitoring_type(mediaSource,obs.OBS_MONITORING_TYPE_MONITOR_AND_OUTPUT)
obs.obs_data_release(s)
obs.obs_set_output_source(outputIndex, mediaSource)
return mediaSource
end
function obs_play_sound_release_source()
r = play_sound()
obs.obs_source_release(r)
end
Исходный код
local obs = obslua
mediaSource = nil -- Null pointer
outputIndex = 63 -- Last index
function play_sound()
mediaSource = obs.obs_source_create_private("ffmpeg_source", "Global Media Source", nil)
local s = obs.obs_data_create()
obs.obs_data_set_string(s, "local_file",script_path() .. "alert.mp3")
obs.obs_source_update(mediaSource,s)
obs.obs_source_set_monitoring_type(mediaSource,obs.OBS_MONITORING_TYPE_MONITOR_AND_OUTPUT)
obs.obs_data_release(s)
obs.obs_set_output_source(outputIndex, mediaSource)
return mediaSource
end
function obs_play_sound_release_source()
r = play_sound()
obs.obs_source_release(r)
end
function on_event(event)
if event == obs.OBS_FRONTEND_EVENT_SCENE_CHANGED
then obs_play_sound_release_source()
end
end
function script_load(settings)
obs.obs_frontend_add_event_callback(on_event)
end
function script_unload()
obs.obs_set_output_source(outputIndex, nil)
end
Время и файлы
Запись в файл, "a" - создаст(если нет) файл и добавит "content", а "w" - перезапишет .
io.output(io.open(script_path() .. "out.txt","a"))
io.write("content")
io.close()
print(os.date("%c"))
-- День недели Месяц Время Год
Сцены и предметы сцен
obs_sceneitem_get_source - предметы сцен в источник
obs_scene_from_source - преобразование сцены в источник
obs_scene_find_source - преобразование источника в предмет сцены
obs_frontend_get_scenes - получение всех сцен, освобождать с source_list_release
obs_frontend_get_current_scene - получение текущей сцены
obs_scene_enum_items - список всех предметов в сцене, освобождать с sceneitem_list_release
Скрипт: включение и выключение предмета сцены(источника на сцене).
Получение всех сцен и предметов в них
function toggle_source()
scenes = obs.obs_frontend_get_scenes()
for _,scene in pairs(scenes) do
scene_source = obs.obs_scene_from_source(scene)
items = obs.obs_scene_enum_items(scene_source)
...
Поиск конкретного источника и его включение или выключение, source_name и boolean определены глобально.
...
for _,scene_item in pairs(items) do
_source = obs.obs_sceneitem_get_source(scene_item)
_name = obs.obs_source_get_name(_source)
if _name == source_name then
boolean = not boolean
obs.obs_sceneitem_set_visible(scene_item, boolean)
end
end
...

Исходный код
local obs = obslua
source_name = ''
boolean = true
function htk_1_cb(pressed)
if pressed then
toggle_source()
end
end
function toggle_source()
scenes = obs.obs_frontend_get_scenes()
for _,scene in pairs(scenes) do
scene_source = obs.obs_scene_from_source(scene)
items = obs.obs_scene_enum_items(scene_source)
for _,scene_item in pairs(items) do
_source = obs.obs_sceneitem_get_source(scene_item)
_name = obs.obs_source_get_name(_source)
if _name == source_name then
boolean = not boolean
obs.obs_sceneitem_set_visible(scene_item, boolean)
end
end
obs.sceneitem_list_release(items)
end
obs.source_list_release(scenes)
end
function script_properties()
-- source https://raw.githubusercontent.com/insin/obs-bounce/master/bounce.lua
local props = obs.obs_properties_create()
local source = obs.obs_properties_add_list(
props,
'source',
'Source:',
obs.OBS_COMBO_TYPE_EDITABLE,
obs.OBS_COMBO_FORMAT_STRING)
for _, name in ipairs(get_source_names()) do
obs.obs_property_list_add_string(source, name, name)
end
obs.obs_property_set_long_description(source,"?" )
return props
end
function script_update(settings)
source_name = obs.obs_data_get_string(settings, 'source')
end
--- get a list of source names, sorted alphabetically
function get_source_names()
local sources = obs.obs_enum_sources()
local source_names = {}
if sources then
for _, source in ipairs(sources) do
-- exclude Desktop Audio and Mic/Aux by their capabilities
local capability_flags = obs.obs_source_get_output_flags(source)
if bit.band(capability_flags, obs.OBS_SOURCE_DO_NOT_SELF_MONITOR) == 0 and
capability_flags ~= bit.bor(obs.OBS_SOURCE_AUDIO, obs.OBS_SOURCE_DO_NOT_DUPLICATE) then
table.insert(source_names, obs.obs_source_get_name(source))
end
end
end
obs.source_list_release(sources)
table.sort(source_names, function(a, b)
return string.lower(a) < string.lower(b)
end)
return source_names
end
key_1 = '{"htk_1": [ { "key": "OBS_KEY_1" } ]}'
json_s = key_1
default_hotkeys = {
{id='htk_1',des='Кнопка 1 ',callback=htk_1_cb},
}
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
Регистрация фильтров
В obslua доступна функция obs_register_source, с её помощью можно зарегистрировать
источник( переходы и фильтры это источники). Для этого понадобится создать таблицу источника
Регистрация фильтров удобна тем,что позволяет закрепить функциональность скрипта за
определенным источником. Поддерживает горячие клавиши, интерфейс, таймеры.
Скрипт: закрепление горячих клавиш на фильтре, и полный доступ к источнику.
Импорт библиотеки, и определение типа как источник-фильтр.
local obs = obslua
local bit = require("bit")
local info = {} -- obs_source_info https://obsproject.com/docs/reference-sources.html
info.id = "uniq_filter_id"
info.type = obs.OBS_SOURCE_TYPE_FILTER
info.output_flags = bit.bor(obs.OBS_SOURCE_VIDEO)
info.get_name = function() return 'default filter name' end
Инициализация фильтра, будет вызываться при запуске программы или при добавлении к источнику
info.create = function(settings,source)
local filter = {}
filter.context = source
Начальная регистрация горячих клавиш, принадлежащих конкретному фильтру.
filter.hotkeys = {
htk_stop = "[stop] ",
htk_restart = "[start] ",
}
filter.hotkey_mapping = function(hotkey,data)
if hotkey == "htk_stop" then
print('stop '.. data.srsn .. " : " .. data.filn)
elseif hotkey == "htk_restart" then
print('restart ' .. data.srsn .. " : " .. data.filn)
end
end
filter.hk = {}
for k,v in pairs(filter.hotkeys) do
filter.hk[k] = obs.OBS_INVALID_HOTKEY_ID
end
Создание функции которая запустится не сразу ( это необходимо т.к фильтр ещё не создан)
Он будет создан после return
filter._reg_htk = function()
info.reg_htk(filter,settings)
end
obs.timer_add(filter._reg_htk,100) -- callback to register hotkeys, one time only
Завершающая регистрация горячих клавиш,obs_filter_get_parent источник который фильтруется
к которому прикреплён фильтр этого типа. Удаление таймера.
info.reg_htk = function(filter,settings) -- register hotkeys after 100 ms since filter was created
local target = obs.obs_filter_get_parent(filter.context)
local srsn = obs.obs_source_get_name(target)
local filn = obs.obs_source_get_name(filter.context)
local data = {srsn = srsn, filn = filn}
for k, v in pairs(filter.hotkeys) do
filter.hk[k] = obs.obs_hotkey_register_frontend(k, v .. srsn .. " : " .. filn, function(pressed)
if pressed then filter.hotkey_mapping(k,data) end end)
local a = obs.obs_data_get_array(settings, k)
obs.obs_hotkey_load(filter.hk[k], a)
obs.obs_data_array_release(a)
end
obs.remove_current_callback()
end
Необходимый код для пропуска фильтрации, без него при добавлении фильтра источник "выключится"
info.video_render = function(filter, effect)
-- called every frame
local target = obs.obs_filter_get_parent(filter.context)
if target ~= nil then
filter.width = obs.obs_source_get_base_width(target)
filter.height = obs.obs_source_get_base_height(target)
end
obs.obs_source_skip_video_filter(filter.context)
end
info.get_width = function(filter)
return filter.width
end
info.get_height = function(filter)
return filter.height
end
Функция .save вызывается при сохранении настроек,т.е можно переназначить горячие клавиши.
obs.obs_register_source(info) - регистрация фильтра, теперь его видно при нажатии ПКМ
info.save = function(filter,settings)
for k, v in pairs(filter.hotkeys) do
local a = obs.obs_hotkey_save(filter.hk[k])
obs.obs_data_set_array(settings, k, a)
obs.obs_data_array_release(a)
end
end
obs.obs_register_source(info)
info.load - также как и script_load, вызывается при запуске программы, но в данном
случае дублирует функциональность и требует перезапуска. .update, .get_properties
функции аналогичные script_update, script_properties.

Исходный код
local obs = obslua
local bit = require("bit")
local info = {} -- obs_source_info https://obsproject.com/docs/reference-sources.html
info.id = "uniq_filter_id"
info.type = obs.OBS_SOURCE_TYPE_FILTER
info.output_flags = bit.bor(obs.OBS_SOURCE_VIDEO)
info.get_name = function() return 'default filter name' end
info.create = function(settings,source)
local filter = {}
filter.context = source
filter.hotkeys = {
htk_stop = "[stop] ",
htk_restart = "[start] ",
}
filter.hotkey_mapping = function(hotkey,data)
if hotkey == "htk_stop" then
print('stop '.. data.srsn .. " : " .. data.filn)
elseif hotkey == "htk_restart" then
print('restart ' .. data.srsn .. " : " .. data.filn)
end
end
filter.hk = {}
for k,v in pairs(filter.hotkeys) do
filter.hk[k] = obs.OBS_INVALID_HOTKEY_ID
end
filter._reg_htk = function()
info.reg_htk(filter,settings)
end
obs.timer_add(filter._reg_htk,100) -- callback to register hotkeys, one time only
return filter
end
info.reg_htk = function(filter,settings) -- register hotkeys after 100 ms since filter was created
local target = obs.obs_filter_get_parent(filter.context)
local srsn = obs.obs_source_get_name(target)
local filn = obs.obs_source_get_name(filter.context)
local data = {srsn = srsn, filn = filn}
for k, v in pairs(filter.hotkeys) do
filter.hk[k] = obs.obs_hotkey_register_frontend(k, v .. srsn .. " : " .. filn, function(pressed)
if pressed then filter.hotkey_mapping(k,data) end end)
local a = obs.obs_data_get_array(settings, k)
obs.obs_hotkey_load(filter.hk[k], a)
obs.obs_data_array_release(a)
end
obs.remove_current_callback()
end
info.video_render = function(filter, effect)
-- called every frame
local target = obs.obs_filter_get_parent(filter.context)
if target ~= nil then
filter.width = obs.obs_source_get_base_width(target)
filter.height = obs.obs_source_get_base_height(target)
end
obs.obs_source_skip_video_filter(filter.context)
end
info.get_width = function(filter)
return filter.width
end
info.get_height = function(filter)
return filter.height
end
--info.load = function(filter,settings) -- restart required
--... same code as in info.reg_htk, but filters will be created from scratch every time
--obs restarts, there is no reason to define it here again becuase hotkeys will be duplicated
--end
info.save = function(filter,settings)
for k, v in pairs(filter.hotkeys) do
local a = obs.obs_hotkey_save(filter.hk[k])
obs.obs_data_set_array(settings, k, a)
obs.obs_data_array_release(a)
end
end
obs.obs_register_source(info)
obspython
В OBS также доступен скриптинг через Python, для Windows только 3.6 версия, для Linux встроенная (т.к в настройках нельзя указать путь),
для MacOS Python не доступен для текущей (26.0.0) версии.
В отличии от Lua тут нельзя регистрировать источники, перебор фильтров не работает,
т.к не написан wrapper на функции с аргументом типа указатель-указатель.
Но в контексте скриптинга имеет место быть т.к:
Задачи
Перед тем как начать делать задачи, рекомендую сделать бэкап коллекции сцен,
с осторожностью использовать script_tick(вызывается раз в каждый кадр)
Проверять утечки памяти в папке logs, последняя строка последнего файла
пример - время: Number of memory leaks: 0,если скрипт написан неправильно то
этой строчки там не окажется т.к OBS вылетит с ошибкой при закрытии.
3)[фильтры] "Динамическая прокрутка"
Создать программно или выбрать через интерфейс источник который будет фильтроваться,
к этом источнику добавить(если нет) фильтр Прокрутка (scroll_filter),
добавить интерфейс и/или горячие клавиши которые меняют значение вертикальной скорости
на случайную величину от 0 до 1000 при этом включать/выключать повторение с 50% шансом.

4)[эвенты] "Проверка"
При переключении сцен проверять идёт ли запись.
Если нет - вывести оповещение ( например через error())
5)[время и файлы] "Пост-продакшен"
Создать скрипт который при нажатии горячей клавиши записывает текущее время,
относительное время от старта записи, добавляет текст "МЕТКА",
а через интерфейс UI кнопку записать текст, и место для набора текста.

6)[предметы сцены] "Сумма"
Посчитать количество сцен и предметов сцен, записать ответ в названии первой сцены.
Не учитывать группы, т.к перебор предметов груп не работает.

- [фильтры и источники] "Нэйтив скриптинг"
Создать фильтр который будет с интервалом в 2 секунды включать и выключать источник за которым он закреплён.

Ответы на задачи и код скриптов включая первую часть на Github
Ссылки
Всем привет,в этой части руководства рассмотрим :
фильтры, сцены, предметы сцен, Frontend API, создание функциональных фильтров и прочее...
Краткая справка для этой части
Источник - Источники используются для рендера аудио/видео, например: захват камеры,игры,звука. С помощью источников можно создавать фильтры,переходы
Фильтр - Источник который дополняет другие источники
Сцены - Коллекция источников, сцена является источником ( сцену можно добавить как источник в другой сцене)
Предмет сцены - конкретный источник в сцене, его можно: перемещать, увеличивать/уменьшать, переворачивать, менять состояние выкл/вкл и.т.д
Frontend API - Набор функций который предоставляет OBS Studio, например:
подписка на событие о переключении сцен
запрос статуса о том, идёт ли стрим/запись
вкл/выкл стрим/запись
переключение сцен
Фильтры
Типы фильтров так же как и источников, можно узнать через функцию
obs_source_get_unversioned_idВ английском варианте : ссылка
Скрипт: изменение параметра прозрачности у фильтра на случайную величину от 1 до 100.
Чтобы узнать название параметра "прозрачность" необходимо добавить фильтр с прозрачностью на какой-нибудь источник, изменить этот параметр. Далее открыть файл коллекции сцен, путь к директории можно узнать через меню OBS:
Справка>Файлы журнала>Показать файлы журналадалее с этой директории поднимаемся выше, и получаем путь
~/basic>scenes>название_сцены.jsonВ этом файле ищем
color_filterилиcolor_key_filter(оба фильтра могут изменить прозрачность источника).В строке
settingsвидим что прозрачность записана какopacity.Ещё один способ узнать название параметра, прочитать исходный код фильтра - ссылка
Находим источник по имени
Создаём настройки с изменением параметра
opacityна случайное числоПроверяем существует ли уже фильтр на источнике, если нет добавляем
Обновляем и освобождаем память
Привязка к горячей клавише
Исходный код
Стоит упомянуть также о функции
obs_source_enum_filtersс её помощью можно получитьсписок всех фильтров у конкретного источника, кстати эта функция не работает в
obspython,но об этом чуть позже.
Эвенты и состояние
Скрипт: звуковое оповещение о том что сцена изменена, с использованием .mp3 файла.
На основе этого скрипта
Создадим функцию для проигрывания звука при смене сцен.
Добавим источник медиа, установим настройки: файл
alert.mp3относителен директории нахожденияскрипта,
obs_source_set_monitoring_typeвыставляет прослушивание аудио.Исходный код
Время и файлы
Запись в файл, "a" - создаст(если нет) файл и добавит "content", а "w" - перезапишет .
Сцены и предметы сцен
obs_sceneitem_get_source- предметы сцен в источникobs_scene_from_source- преобразование сцены в источникobs_scene_find_source- преобразование источника в предмет сценыobs_frontend_get_scenes- получение всех сцен, освобождать сsource_list_releaseobs_frontend_get_current_scene- получение текущей сценыobs_scene_enum_items- список всех предметов в сцене, освобождать сsceneitem_list_releaseСкрипт: включение и выключение предмета сцены(источника на сцене).
Получение всех сцен и предметов в них
Поиск конкретного источника и его включение или выключение,
source_nameиbooleanопределены глобально.Исходный код
Регистрация фильтров
В
obsluaдоступна функцияobs_register_source, с её помощью можно зарегистрироватьисточник( переходы и фильтры это источники). Для этого понадобится создать таблицу источника
Регистрация фильтров удобна тем,что позволяет закрепить функциональность скрипта за
определенным источником. Поддерживает горячие клавиши, интерфейс, таймеры.
Скрипт: закрепление горячих клавиш на фильтре, и полный доступ к источнику.
Импорт библиотеки, и определение типа как источник-фильтр.
Инициализация фильтра, будет вызываться при запуске программы или при добавлении к источнику
Начальная регистрация горячих клавиш, принадлежащих конкретному фильтру.
Создание функции которая запустится не сразу ( это необходимо т.к фильтр ещё не создан)
Он будет создан после
returnЗавершающая регистрация горячих клавиш,
obs_filter_get_parentисточник который фильтруетсяк которому прикреплён фильтр этого типа. Удаление таймера.
Необходимый код для пропуска фильтрации, без него при добавлении фильтра источник "выключится"
Функция .save вызывается при сохранении настроек,т.е можно переназначить горячие клавиши.
obs.obs_register_source(info)- регистрация фильтра, теперь его видно при нажатии ПКМinfo.load- также как иscript_load, вызывается при запуске программы, но в данномслучае дублирует функциональность и требует перезапуска.
.update,.get_propertiesфункции аналогичные
script_update,script_properties.Исходный код
obspython
В OBS также доступен скриптинг через Python, для Windows только 3.6 версия, для Linux встроенная (т.к в настройках нельзя указать путь),
для MacOS Python не доступен для текущей (26.0.0) версии.
В отличии от Lua тут нельзя регистрировать источники, перебор фильтров не работает,
т.к не написан wrapper на функции с аргументом типа указатель-указатель.
Но в контексте скриптинга имеет место быть т.к:
Задачи
Перед тем как начать делать задачи, рекомендую сделать бэкап коллекции сцен,
с осторожностью использовать
script_tick(вызывается раз в каждый кадр)Проверять утечки памяти в папке
logs, последняя строка последнего файлапример -
время: Number of memory leaks: 0,если скрипт написан неправильно тоэтой строчки там не окажется т.к OBS вылетит с ошибкой при закрытии.
3)[фильтры] "Динамическая прокрутка"
Создать программно или выбрать через интерфейс источник который будет фильтроваться,
к этом источнику добавить(если нет) фильтр Прокрутка (scroll_filter),
добавить интерфейс и/или горячие клавиши которые меняют значение вертикальной скорости
на случайную величину от 0 до 1000 при этом включать/выключать повторение с 50% шансом.
4)[эвенты] "Проверка"
При переключении сцен проверять идёт ли запись.
Если нет - вывести оповещение ( например через error())
5)[время и файлы] "Пост-продакшен"

Создать скрипт который при нажатии горячей клавиши записывает текущее время,
относительное время от старта записи, добавляет текст "МЕТКА",
а через интерфейс UI кнопку записать текст, и место для набора текста.
6)[предметы сцены] "Сумма"

Посчитать количество сцен и предметов сцен, записать ответ в названии первой сцены.
Не учитывать группы, т.к перебор предметов груп не работает.
Создать фильтр который будет с интервалом в 2 секунды включать и выключать источник за которым он закреплён.
Ответы на задачи и код скриптов включая первую часть на Github
Ссылки