Skip to content

Instantly share code, notes, and snippets.

@to
Last active April 16, 2024 19:30
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save to/a35f45e3fc2548c985435b72b35015e3 to your computer and use it in GitHub Desktop.
Save to/a35f45e3fc2548c985435b72b35015e3 to your computer and use it in GitHub Desktop.
OBS: シーンが切り替わるタイミングでメディアをフェードアウト/フェードインする
local obs = obslua
local duration = 1200
local interval = 50
local steps = duration / interval
local current_scene_name
local debug = false
local fade_table = {}
local is_running = false
function on_source_show(calldata)
local source = obs.calldata_source(calldata, "source")
if source == nil then return end
local source_id = obs.obs_source_get_id(source)
if source_id ~= "scene" then return end
-- 初回の実行か?
local next_scene_name = obs.obs_source_get_name(source)
if current_scene_name == nil then
current_scene_name = next_scene_name
return
end
log("SCENE_SHOW:" .. next_scene_name);
-- 古いシーンのメディアを繰り返す
local source = obs.obs_get_source_by_name(current_scene_name)
for_each_scene_items(source, function(source, source_name)
log("FADE_OUT: " .. source_name)
-- フェード方向をフェードアウトにする
fade_table[source_name].direction = -1
end)
obs.obs_source_release(source)
-- 新しいシーンのメディアを繰り返す
local source = obs.obs_get_source_by_name(next_scene_name)
for_each_scene_items(source, function(source, source_name)
log("FADE_IN: " .. source_name)
-- フェードアウトの途中でなかったか?
-- (前後のシーンで同一のメディアがあった場合、フェードがスキップされる)
if fade_table[source_name].direction == nil then
-- 音量をゼロにする
obs.obs_source_set_volume(source, 0)
end
-- フェード方向をフェードインにする
fade_table[source_name].direction = 1
end)
obs.obs_source_release(source)
start_timer()
current_scene_name = next_scene_name
end
function for_each_scene_items(source, func)
local scene = obs.obs_scene_from_source(source)
local items = obs.obs_scene_enum_items(scene)
for _, item in ipairs(items) do
-- メディアソースか?
local source = obs.obs_sceneitem_get_source(item)
local source_id = obs.obs_source_get_id(source)
if source_id == "vlc_source" or source_id == "ffmpeg_source" then
local source_name = obs.obs_source_get_name(source)
local volume = obs.obs_source_get_volume(source)
if not obs.obs_source_muted(source) then
if fade_table[source_name] == nil then
fade_table[source_name] = {volume = volume}
end
func(source, source_name)
end
end
end
obs.sceneitem_list_release(items)
end
function start_timer()
if table.empty(fade_table) or is_running then return end
obs.timer_add(function()
for source_name, info in pairs(fade_table) do
-- フェードインか?
local source = obs.obs_get_source_by_name(source_name)
local volume = obs.obs_source_get_volume(source)
if info.direction > 0 then
volume = math.min(volume + (info.volume / steps), info.volume)
-- 最大音量に達しているか?
if volume == info.volume then
fade_table[source_name] = nil
end
else
volume = math.max(volume - (info.volume / steps), 0)
-- メディアの再生が終了しているか?
if not obs.obs_source_active(source) then
-- 音量を元に戻す
volume = info.volume
fade_table[source_name] = nil
end
end
obs.obs_source_set_volume(source, volume)
obs.obs_source_release(source)
end
-- 全てのフェードが終了したか?
if table.empty(fade_table) then
log("TIMER_END:")
obs.remove_current_callback()
is_running = false
end
end, interval)
log("TIMER_START:")
is_running = true
end
function log(msg)
if not debug then return end
print(msg)
end
function script_description()
return "auto fade in/out audios"
end
function script_load(settings)
log("LOAD:");
obs.signal_handler_connect(
obs.obs_get_signal_handler(), "source_show", on_source_show)
end
function table.empty(tbl)
if tbl == nil then return true end
return not next(tbl)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment