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")
When I try to set the scene from within a timer callback function, OBS ends up crashing. I've tried to print the number for every time the callback function is called, and when I look at the logs, it shows every print function it's supposed to call, but it doesn't tell me why OBS crashed.
This is the code where I use a helper function to set the scene. With or without the helper function, it crashes either way. However, when I set the scene from outside the timer, everything works fine.
Any form of help is appreciated!
It's been a while since I worked on this script, but I have managed to fix the problem so I'll try my best to recall how I fixed it.
It appears that the crash only occurs when the combination of the 3 functions (obs_frontend_add_event_callback()
, timer_add()
and obs_frontend_set_current_scene()
) appears, so instead of using the frontend event callback, I used signal handlers instead.
I first got the current scene and got the signal handler of that scene. Afterwards I connected a callback function which runs when the signal handler sends a "deactivate" signal. From there I added the timer callback which switches the scene when the timer reaches 0. This stopped the crashes from happening. My code for reference:
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)
For some reason, even when obs_frontend_add_event_callback()
is being used in another script, using obs_frontend_set_current_scene()
within timer_add()
continues to cause the crash. I have concluded that obs_frontend_add_event_callback()
should be avoided.
I switched to attaching a stream signal handler in script_load()
to signal when the stream started. However, the signal handler only calls the callback function from the second stream onwards of the OBS instance. We had to use the frontend event callback at this point. So my steps was to add the frontend event callback on script load with the callback function removing the frontend event callback immediately and replacing it with a signal handler instead for future streams on the same instance.
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)