-
-
Save to/a35f45e3fc2548c985435b72b35015e3 to your computer and use it in GitHub Desktop.
| 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 |
4年前のことで 私も 現在 利用していないので まったく わからなくなっちゃってます><
どうにか修正できないかとChatGPTといろいろやりましたが、結果は芳しく無く……
このスクリプトは非常に便利でグレートなものなので、どうにか!どうにか!していただけないでしょうか!
ちなみにChatGPTとの知識皆無な私が行った恥ずかしいやり取りはこちらです(/////)
https://chat.openai.com/share/47f64417-5e7b-41a3-85b5-8ccb46f3e04b
私のほうでOBS Studio 30.2.3でフェードアウト中にすぐにシーンを戻すと再現しました。
ログを差し込んでデバッグをしたところ再現時にsource_showのsignalイベントが発火していないように見受けられました。
コード的に、スタジオモードでの切替時も動作しなさそうです。
OBS自体初心者なのですが、意外に、プラグインなども含めて音声をうまくクロスフェードする手段って提供されていないのですかね?
「高機能シーンスイッチャー」のマクロだと設定しにくかったので、
もう少し探して見当たらなければ私のほうで本スクリプトを参考に書きなおそうかと思います。
ざっと書き直しました。もう少し自分で使ってみてバグが取れたところで、近日中に共有したいと思います。
デフォルトの機能でトランジションのフェード設定さえしていれば音声もフェードイン・フェードアウトしていることに気が付きました。
音声をモニターしているだけではわからないのですが、配信や録画ではフェードが効いているようですね。
一通り書き直していろいろテストしている間に気がつきました・・・!
せっかく作ったスクリプトですが無用ですね。。どこかで供養はしますが。
つまり最新のOBSのトランジションのフェード設定さえしておけば、
今までバツンと音声が切り替わっていたのが、音もフェードして滑らかに切り替わってくれるようになったということですか?
……だとしたらOBS神アプデ!?
それにしてもray34g様スクリプトの見直しと現状の確認作業本当に助かりました。ありがとうございます。神と崇めます。
https://github.com/NagaoSouma/OBS-fade-audio-when-transitioning
1000001901.mp4
OBSを最新にしているものの音声ごとフェードしていることが確認できなかったため、一応トランジション毎(フェード、カット、スティンガーなど)にフェード時間を設定できるスクリプトを公開しました。
スタジオモードでも使えます(スタジオモードの方がいいまである)
便利なスクリプトで実装不可避なのですが問題が発生しております。
フェードアウト後音声設定が-inf dBになって固定される
具体的に記述すると、例えば
この問題は致命的で、シーンを切り替えると音声が出力されなくなってしまい放送に支障出てしまいます。
修正できないでしょうか?