mirror of
https://github.com/WarmUpTill/SceneSwitcher.git
synced 2026-08-16 14:19:02 -05:00
Fix waiting for transition to complete with fixed duration transitions
This commit is contained in:
@@ -2,6 +2,8 @@
|
||||
#include "headers/advanced-scene-switcher.hpp"
|
||||
#include "headers/utility.hpp"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
const std::string MacroActionSwitchScene::id = "scene_switch";
|
||||
|
||||
bool MacroActionSwitchScene::_registered = MacroActionFactory::Register(
|
||||
@@ -9,7 +11,21 @@ bool MacroActionSwitchScene::_registered = MacroActionFactory::Register(
|
||||
{MacroActionSwitchScene::Create, MacroActionSwitchSceneEdit::Create,
|
||||
"AdvSceneSwitcher.action.switchScene"});
|
||||
|
||||
void waitForTransitionChange(int duration)
|
||||
void waitForTransitionChange(OBSWeakSource &transition)
|
||||
{
|
||||
const auto time = 100ms;
|
||||
obs_source_t *source = obs_weak_source_get_source(transition);
|
||||
std::unique_lock<std::mutex> lock(switcher->m);
|
||||
bool stillTransitioning = true;
|
||||
while (stillTransitioning && !switcher->abortMacroWait) {
|
||||
switcher->macroTransitionCv.wait_for(lock, time);
|
||||
float t = obs_transition_get_time(source);
|
||||
stillTransitioning = t < 1.0f && t > 0.0f;
|
||||
}
|
||||
obs_source_release(source);
|
||||
}
|
||||
|
||||
void waitForTransitionChangeFixedDuration(int duration)
|
||||
{
|
||||
duration += 200; // It seems to be necessary to add a small buffer
|
||||
auto time = std::chrono::high_resolution_clock::now() +
|
||||
@@ -25,7 +41,7 @@ void waitForTransitionChange(int duration)
|
||||
}
|
||||
}
|
||||
|
||||
int getTransitionOverrideDuration(OBSWeakSource scene)
|
||||
int getTransitionOverrideDuration(OBSWeakSource &scene)
|
||||
{
|
||||
int duration = 0;
|
||||
obs_source_t *source = obs_weak_source_get_source(scene);
|
||||
@@ -39,11 +55,41 @@ int getTransitionOverrideDuration(OBSWeakSource scene)
|
||||
return duration;
|
||||
}
|
||||
|
||||
int getExpectedTransitionDuration(OBSWeakSource scene, double duration)
|
||||
bool isUsingFixedLengthTransition(OBSWeakSource &transition)
|
||||
{
|
||||
int overrideDuration = getTransitionOverrideDuration(scene);
|
||||
if (overrideDuration && !switcher->transitionOverrideOverride) {
|
||||
return overrideDuration;
|
||||
obs_source_t *source = obs_weak_source_get_source(transition);
|
||||
bool ret = obs_transition_fixed(source);
|
||||
obs_source_release(source);
|
||||
return ret;
|
||||
}
|
||||
|
||||
OBSWeakSource getOverrideTransition(OBSWeakSource &scene)
|
||||
{
|
||||
OBSWeakSource transition;
|
||||
obs_source_t *source = obs_weak_source_get_source(scene);
|
||||
obs_data_t *data = obs_source_get_private_settings(source);
|
||||
transition = GetWeakTransitionByName(
|
||||
obs_data_get_string(data, "transition"));
|
||||
obs_data_release(data);
|
||||
obs_source_release(source);
|
||||
return transition;
|
||||
}
|
||||
|
||||
int getExpectedTransitionDuration(OBSWeakSource &scene, OBSWeakSource &t,
|
||||
double duration)
|
||||
{
|
||||
OBSWeakSource transition = t;
|
||||
if (!switcher->transitionOverrideOverride) {
|
||||
auto overrideTransition = getOverrideTransition(scene);
|
||||
if (overrideTransition) {
|
||||
transition = overrideTransition;
|
||||
if (!isUsingFixedLengthTransition(transition)) {
|
||||
return getTransitionOverrideDuration(scene);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isUsingFixedLengthTransition(transition)) {
|
||||
return -1; // no API is available to access the fixed duration
|
||||
}
|
||||
if (duration != 0) {
|
||||
return duration * 1000;
|
||||
@@ -54,12 +100,19 @@ int getExpectedTransitionDuration(OBSWeakSource scene, double duration)
|
||||
bool MacroActionSwitchScene::PerformAction()
|
||||
{
|
||||
auto scene = _scene.GetScene();
|
||||
switchScene({scene, _transition.GetTransition(),
|
||||
(int)(_duration.seconds * 1000)},
|
||||
auto transition = _transition.GetTransition();
|
||||
switchScene({scene, transition, (int)(_duration.seconds * 1000)},
|
||||
obs_frontend_preview_program_mode_active());
|
||||
if (_blockUntilTransitionDone && scene) {
|
||||
waitForTransitionChange(getExpectedTransitionDuration(
|
||||
scene, _duration.seconds));
|
||||
const int expectedTransitionDuration =
|
||||
getExpectedTransitionDuration(scene, transition,
|
||||
_duration.seconds);
|
||||
if (expectedTransitionDuration < 0) {
|
||||
waitForTransitionChange(transition);
|
||||
} else {
|
||||
waitForTransitionChangeFixedDuration(
|
||||
expectedTransitionDuration);
|
||||
}
|
||||
return !switcher->abortMacroWait;
|
||||
}
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user