scenes = obs.obs_frontend_get_scenes()
def script_load(settings):
obs.obs_frontend_add_event_callback(onevent)
def script_update(settings):
global trigger, s_minutes, s_seconds, ending, e_minutes, e_seconds
trigger = obs.obs_data_get_string(settings, "e_trigger scene")
s_minutes = obs.obs_data_get_int(settings, "s_minutes")
s_seconds = obs.obs_data_get_int(settings, "s_seconds")
e_minutes = obs.obs_data_get_int(settings, "e_minutes")
e_seconds = obs.obs_data_get_int(settings, "e_seconds")
ending = obs.obs_data_get_string(settings, "s_ending scene")
def timer_callback():
global tElapsed
if state == 0:
print("Error: State = 0")
obs.remove_current_callback()
if state == 1:
tElapsed += 1
print(tElapsed)
if tElapsed == timer:
tElapsed = 0
set_scene()
obs.remove_current_callback()
if state == 2:
tElapsed += 1
print(tElapsed)
if tElapsed == timer:
tElapsed = 0
obs.obs_frontend_streaming_stop()
obs.remove_current_callback()
def set_scene():
index = (obs.obs_frontend_get_scene_names()).index(ending)
scene = scenes[index]
obs.obs_frontend_set_current_scene(scene)
def onevent(event):
global state, timer
if event==obs.OBS_FRONTEND_EVENT_STREAMING_STOPPED:
state = 0
if event==obs.OBS_FRONTEND_EVENT_STREAMING_STARTED:
state = 1
timer = s_minutes * 60 + s_seconds
obs.timer_add(timer_callback,1000)
if event==obs.OBS_FRONTEND_EVENT_SCENE_CHANGED:
if obs.obs_source_get_name(obs.obs_frontend_get_current_scene()) == trigger:
state = 2
timer = e_minutes * 60 + e_seconds
obs.timer_add(timer_callback,1000)
else:
obs.timer_remove(timer_callback)
if state == 1:
print("Start timer stopped")
elif state == 2:
print("End timer stopped")
当我尝试从计时器回调函数中设置场景时,OBS 最终崩溃了。我尝试在每次调用回调函数时打印数字,当我查看日志时,它显示了它应该调用的每个打印函数,但它没有告诉我OBS崩溃的原因。
这是我使用辅助函数来设置场景的代码。无论有没有辅助函数,它都会崩溃。但是,当我从计时器外部设置场景时,一切正常。
感谢任何形式的帮助!
我已经有一段时间没有编写这个脚本了,但我已经设法解决了这个问题,所以我会尽力回忆一下我是如何解决它的。
看来只有当 3 个函数(
obs_frontend_add_event_callback()
、timer_add()
和 obs_frontend_set_current_scene()
)的组合出现时才会发生崩溃,因此我没有使用前端事件回调,而是使用了信号处理程序。
我首先获取当前场景并获取该场景的信号处理程序。之后,我连接了一个回调函数,该函数在信号处理程序发送“停用”信号时运行。从那里我添加了计时器回调,当计时器达到 0 时切换场景。这阻止了崩溃的发生。我的代码供参考:
current_scene = obs.obs_frontend_get_current_scene()
current_handler = obs.obs_source_get_signal_handler(current_scene)
obs.obs_source_release(current_scene)
obs.signal_handler_connect(current_handler, "deactivate", checker)
timer = s_minutes * 60 + s_seconds
obs.timer_add(timer_callback, 1000)
出于某种原因,即使在另一个脚本中使用
obs_frontend_add_event_callback()
,在 obs_frontend_set_current_scene()
中使用 timer_add()
仍然会导致崩溃。我的结论是应该避免obs_frontend_add_event_callback()
。
我切换到在
script_load()
中附加流信号处理程序,以在流启动时发出信号。但是,信号处理程序仅从 OBS 实例的第二个流开始调用回调函数。此时我们必须使用前端事件回调。因此,我的步骤是在脚本加载时添加前端事件回调,并使用回调函数删除前端事件回调立即,并将其替换为信号处理程序,而不是用于同一实例上的未来流。
def script_load(settings):
obs.obs_frontend_add_event_callback(onevent)
def onevent(event):
global output
if event == obs.OBS_FRONTEND_EVENT_STREAMING_STARTED:
stream = obs.obs_frontend_get_streaming_output()
output = obs.obs_output_get_signal_handler(stream)
obs.signal_handler_connect_global(output, frontevent)
obs.obs_output_release(stream)
obs.obs_frontend_remove_event_callback(onevent)
这可能有点晚了,我对 OBS 编程还比较陌生,但我注意到你的代码使用了“
obs_frontend_get_current_scene()
”。有一些调用,包括这个调用,每当调用它们时都会创建指针。这些指针必须被释放,否则它们会继续消耗越来越多的资源。
根据API文档(https://obsproject.com/docs/reference-frontend-api.html?highlight=obs_frontend_get_current_scene),调用时会创建一个新的引用。尽管从该文档条目中看不出来,但可以使用“
obs.obs_source_release(<sourcename>)
”发布引用,因为obs_frontend_get_current_scene()
返回源。
我不知道是否像您所做的那样在内联使用时创建引用(不将其分配给变量),但这可能是问题所在。尝试将
obs_frontend_get_current_scene()
分配给变量,在 obs_source_get_name(<source name>)
调用中使用该变量,然后“释放”该变量。像这样的东西:
scene_as_source = obs.obs_frontend_get_current_scene()
if obs.obs_source_get_name(scene_as_source) == trigger:
state = 2
timer = e_minutes * 60 + e_seconds
obs.timer_add(timer_callback,1000)
else:
obs.timer_remove(timer_callback)
if state == 1:
print("Start timer stopped")
elif state == 2:
print("End timer stopped")
obs.obs_source_release(scene_as_source)