Skip to content
Open
61 changes: 55 additions & 6 deletions src/eventhandler/EventHandler_Transitions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,43 @@ void EventHandler::HandleCurrentSceneTransitionDurationChanged()
BroadcastEvent(EventSubscription::Transitions, "CurrentSceneTransitionDurationChanged", eventData);
}

// The "Fade to Black" transition works funny in studio mode.
// In studio mode this first fades to black, essentially not showing a scene at all.
// Then upon a second fade to black, it actually moves to the correct scene, but the from scene is null.
void SetFromAndToScene(json &eventData, obs_source_t *transition)
{
if (OBSSourceAutoRelease sourceScene = obs_transition_get_source(transition, OBS_TRANSITION_SOURCE_A)) {
eventData["fromScene"] = obs_source_get_name(sourceScene);
} else {
eventData["fromScene"] = nullptr;
}

if (OBSSourceAutoRelease destinationScene = obs_transition_get_source(transition, OBS_TRANSITION_SOURCE_B)) {
eventData["toScene"] = obs_source_get_name(destinationScene);
} else {
eventData["toScene"] = nullptr;
}
}

// FIXME: OBS bug causes source B to be null for transition end but not video transition end.
// Needs to be fixed in obs itself
void SetToScene(json &eventData, obs_source_t *transition)
{
if (OBSSourceAutoRelease sourceScene = obs_transition_get_source(transition, OBS_TRANSITION_SOURCE_A)) {
eventData["toScene"] = obs_source_get_name(sourceScene);
} else {
eventData["toScene"] = nullptr;
}
}

/**
* A scene transition has started.
*
* @dataField transitionName | String | Scene transition name
* @dataField transitionUuid | String | Scene transition UUID
* @dataField transitionName | String | Scene transition name
* @dataField transitionUuid | String | Scene transition UUID
* @dataField transitionDuration | Number | Transition duration in milliseconds
* @dataField toScene | String | Scene that we transitioned to, possibly missing when using "Fade to Black" in studio mode.
* @dataField fromScene | String | Scene that we transitioned away from, possibly missing when using "Fade to Black" in studio mode.
*
* @eventType SceneTransitionStarted
* @eventSubscription Transitions
Expand All @@ -88,6 +120,10 @@ void EventHandler::HandleSceneTransitionStarted(void *param, calldata_t *data)
json eventData;
eventData["transitionName"] = obs_source_get_name(source);
eventData["transitionUuid"] = obs_source_get_uuid(source);
eventData["transitionDuration"] = obs_frontend_get_transition_duration();

SetFromAndToScene(eventData, source);

eventHandler->BroadcastEvent(EventSubscription::Transitions, "SceneTransitionStarted", eventData);
}

Expand All @@ -96,8 +132,10 @@ void EventHandler::HandleSceneTransitionStarted(void *param, calldata_t *data)
*
* Note: Does not appear to trigger when the transition is interrupted by the user.
*
* @dataField transitionName | String | Scene transition name
* @dataField transitionUuid | String | Scene transition UUID
* @dataField transitionName | String | Scene transition name
* @dataField transitionUuid | String | Scene transition UUID
* @dataField transitionDuration | Number | Transition duration in milliseconds
* @dataField toScene | String | Scene that we transitioned to, possibly missing when using "Fade to Black" in studio mode.
*
* @eventType SceneTransitionEnded
* @eventSubscription Transitions
Expand All @@ -118,6 +156,10 @@ void EventHandler::HandleSceneTransitionEnded(void *param, calldata_t *data)
json eventData;
eventData["transitionName"] = obs_source_get_name(source);
eventData["transitionUuid"] = obs_source_get_uuid(source);
eventData["transitionDuration"] = obs_frontend_get_transition_duration();

SetToScene(eventData, source);

eventHandler->BroadcastEvent(EventSubscription::Transitions, "SceneTransitionEnded", eventData);
}

Expand All @@ -129,8 +171,11 @@ void EventHandler::HandleSceneTransitionEnded(void *param, calldata_t *data)
*
* Note: Appears to be called by every transition, regardless of relevance.
*
* @dataField transitionName | String | Scene transition name
* @dataField transitionUuid | String | Scene transition UUID
* @dataField transitionName | String | Scene transition name
* @dataField transitionUuid | String | Scene transition UUID
* @dataField transitionDuration | Number | Transition duration in milliseconds
* @dataField toScene | String | Scene that we transitioned to, possibly missing when using "Fade to Black" in studio mode.
* @dataField fromScene | String | Scene that we transitioned away from, possibly missing when using "Fade to Black" in studio mode.
*
* @eventType SceneTransitionVideoEnded
* @eventSubscription Transitions
Expand All @@ -151,5 +196,9 @@ void EventHandler::HandleSceneTransitionVideoEnded(void *param, calldata_t *data
json eventData;
eventData["transitionName"] = obs_source_get_name(source);
eventData["transitionUuid"] = obs_source_get_uuid(source);
eventData["transitionDuration"] = obs_frontend_get_transition_duration();

SetFromAndToScene(eventData, source);

eventHandler->BroadcastEvent(EventSubscription::Transitions, "SceneTransitionVideoEnded", eventData);
}