From 041a9e7f1985c264edac2828791c04aff772d71f Mon Sep 17 00:00:00 2001 From: WarmUpTill Date: Fri, 30 Apr 2021 15:20:25 -0700 Subject: [PATCH] Add option to set transition duration (#171) --- data/locale/de-DE.ini | 2 +- data/locale/en-US.ini | 2 +- src/headers/advanced-scene-switcher.hpp | 3 +- src/headers/switch-transitions.hpp | 11 ++++-- src/switch-transitions.cpp | 47 +++++++++++++++++++------ 5 files changed, 50 insertions(+), 15 deletions(-) diff --git a/data/locale/de-DE.ini b/data/locale/de-DE.ini index 5e4a4d4a..cadf97da 100644 --- a/data/locale/de-DE.ini +++ b/data/locale/de-DE.ini @@ -61,7 +61,7 @@ AdvSceneSwitcher.transitionTab.transitionBehaviorSelectionError="Mindestens eine AdvSceneSwitcher.transitionTab.transitionForAToB="Szenenübergänge für automatisierte Szenenwechsel von Szene A zu Szene B" AdvSceneSwitcher.transitionTab.transitionsHelp="

Diese Einstellungen beeinflussen nur vom Szenenwechsler ausgelöste Szenenübergänge - Siehe Transition Table um auch manuelle Szenenübergänge zu konfigurieren.
Einstellungen auf diesem Tab haben Vorrang, vor denen welche auf den übrigen Tabs konfiguriert wurden.

Klicke auf das Plus Symbol, um einen neuen Eintrag hinzuzufügen.

" AdvSceneSwitcher.transitionTab.defaultTransition="Ändere den Szenenübergang wenn eine Szene aktiv ist" -AdvSceneSwitcher.transitionTab.entry="Wechsle von {{scenes}} zu {{scenes2}} mit {{transitions}}" +AdvSceneSwitcher.transitionTab.entry="Wechsle von {{scenes}} zu {{scenes2}} mit {{transitions}} mit einer Dauer von {{duration}}" AdvSceneSwitcher.transitionTab.defaultTransitionEntry="Wenn {{scenes}} aktiv ist ändere den Szenenübergang zu {{transitions}}" AdvSceneSwitcher.transitionTab.defaultTransitionsHelp="Klicke auf das Plus Symbol, um einen neuen Eintrag hinzuzufügen." AdvSceneSwitcher.transitionTab.defaultTransition.delay="Wechsle Szenenübergang {{defTransitionDelay}} nach Szenenwechsel." diff --git a/data/locale/en-US.ini b/data/locale/en-US.ini index 471be4d3..513af24a 100644 --- a/data/locale/en-US.ini +++ b/data/locale/en-US.ini @@ -61,7 +61,7 @@ AdvSceneSwitcher.transitionTab.transitionBehaviorSelectionError="At least one op AdvSceneSwitcher.transitionTab.transitionForAToB="Use transition for automated scene switch from scene A to scene B" AdvSceneSwitcher.transitionTab.transitionsHelp="

These settings only affect transitions caused by the scene switcher - Check out Transition Table if you want to configure this for manual scene changes.
Settings defined here take priority over transition settings configured elsewhere in the scene switcher.

Click the plus symbol below to add a new entry.

" AdvSceneSwitcher.transitionTab.defaultTransition="Change transition if scene is active" -AdvSceneSwitcher.transitionTab.entry="Switch from {{scenes}} to {{scenes2}} using {{transitions}}" +AdvSceneSwitcher.transitionTab.entry="Switch from {{scenes}} to {{scenes2}} using {{transitions}} with a duration of {{duration}}" AdvSceneSwitcher.transitionTab.defaultTransitionEntry="When scene {{scenes}} is active change default scene transition to {{transitions}}" AdvSceneSwitcher.transitionTab.defaultTransitionsHelp="Click on the plus symbol to add an entry." AdvSceneSwitcher.transitionTab.defaultTransition.delay="Switch transition {{defTransitionDelay}} after scene change." diff --git a/src/headers/advanced-scene-switcher.hpp b/src/headers/advanced-scene-switcher.hpp index 80e8eb18..b923861f 100644 --- a/src/headers/advanced-scene-switcher.hpp +++ b/src/headers/advanced-scene-switcher.hpp @@ -291,7 +291,8 @@ void setNextTransition(OBSWeakSource &targetScene, obs_source_t *currentSource, bool transitionOverrideOverride, bool adjustActiveTransitionType, transitionData &td); void overwriteTransitionOverride(obs_weak_source_t *sceneWs, - obs_source_t *transition, transitionData &td); + obs_source_t *transition, int duration, + transitionData &td); void restoreTransitionOverride(obs_source_t *scene, transitionData td); void switchScene(OBSWeakSource &scene, OBSWeakSource &transition, bool transitionOverrideOverride, diff --git a/src/headers/switch-transitions.hpp b/src/headers/switch-transitions.hpp index a91874ec..fd1e4053 100644 --- a/src/headers/switch-transitions.hpp +++ b/src/headers/switch-transitions.hpp @@ -1,8 +1,11 @@ #pragma once +#include + #include "switch-generic.hpp" struct SceneTransition : SceneSwitcherEntry { OBSWeakSource scene2 = nullptr; + double duration = 0.; const char *getType() { return "transition"; } bool initialized(); @@ -10,8 +13,10 @@ struct SceneTransition : SceneSwitcherEntry { inline SceneTransition(){}; inline SceneTransition(OBSWeakSource scene_, OBSWeakSource scene2_, - OBSWeakSource transition_) - : SceneSwitcherEntry(scene_, transition_), scene2(scene2_) + OBSWeakSource transition_, double duration_) + : SceneSwitcherEntry(scene_, transition_), + scene2(scene2_), + duration(duration_) { } }; @@ -45,9 +50,11 @@ public: private slots: void Scene2Changed(const QString &text); + void DurationChanged(double dur); private: QComboBox *scenes2; + QDoubleSpinBox *duration; SceneTransition *switchData; }; diff --git a/src/switch-transitions.cpp b/src/switch-transitions.cpp index 7355dabd..95944a5a 100644 --- a/src/switch-transitions.cpp +++ b/src/switch-transitions.cpp @@ -219,10 +219,11 @@ void AdvSceneSwitcher::defTransitionDelayValueChanged(int value) DefaultSceneTransition::delay = value; } -obs_weak_source_t *getNextTransition(obs_weak_source_t *scene1, - obs_weak_source_t *scene2) +std::pair getNextTransition(obs_weak_source_t *scene1, + obs_weak_source_t *scene2) { obs_weak_source_t *ws = nullptr; + int duration = 0; if (scene1 && scene2) { for (SceneTransition &t : switcher->sceneTransitions) { if (!t.initialized()) { @@ -231,16 +232,18 @@ obs_weak_source_t *getNextTransition(obs_weak_source_t *scene1, if (t.scene == scene1 && t.scene2 == scene2) { ws = t.transition; + duration = t.duration * 1000; break; } } obs_weak_source_addref(ws); } - return ws; + return std::make_pair(ws, duration); } void overwriteTransitionOverride(obs_weak_source_t *sceneWs, - obs_source_t *transition, transitionData &td) + obs_source_t *transition, + int nextTransitionDuration, transitionData &td) { obs_source_t *scene = obs_weak_source_get_source(sceneWs); obs_data_t *data = obs_source_get_private_settings(scene); @@ -249,10 +252,9 @@ void overwriteTransitionOverride(obs_weak_source_t *sceneWs, td.duration = obs_data_get_int(data, "duration"); const char *name = obs_source_get_name(transition); - int duration = obs_frontend_get_transition_duration(); obs_data_set_string(data, "transition", name); - obs_data_set_int(data, "transition_duration", duration); + obs_data_set_int(data, "transition_duration", nextTransitionDuration); obs_data_release(data); obs_source_release(scene); @@ -275,10 +277,12 @@ void setNextTransition(OBSWeakSource &targetScene, obs_source_t *currentSource, { obs_weak_source_t *currentScene = obs_source_get_weak_source(currentSource); - obs_weak_source_t *nextTransitionWs = - getNextTransition(currentScene, targetScene); + auto tinfo = getNextTransition(currentScene, targetScene); obs_weak_source_release(currentScene); + obs_weak_source_t *nextTransitionWs = tinfo.first; + int nextTransitionDuration = tinfo.second; + obs_source_t *nextTransition = nullptr; if (nextTransitionWs) { nextTransition = obs_weak_source_get_source(nextTransitionWs); @@ -287,11 +291,13 @@ void setNextTransition(OBSWeakSource &targetScene, obs_source_t *currentSource, } if (nextTransition && adjustActiveTransitionType) { + obs_frontend_set_transition_duration(nextTransitionDuration); obs_frontend_set_current_transition(nextTransition); } if (transitionOverrideOverride) { - overwriteTransitionOverride(targetScene, nextTransition, td); + overwriteTransitionOverride(targetScene, nextTransition, + nextTransitionDuration, td); } obs_weak_source_release(nextTransitionWs); @@ -317,6 +323,7 @@ void SwitcherData::saveSceneTransitions(obs_data_t *obj) obs_data_set_string(array_obj, "Scene2", sceneName2); obs_data_set_string(array_obj, "transition", transitionName); + obs_data_set_double(array_obj, "duration", s.duration); obs_data_array_push_back(sceneTransitionsArray, array_obj); } @@ -378,11 +385,12 @@ void SwitcherData::loadSceneTransitions(obs_data_t *obj) const char *scene2 = obs_data_get_string(array_obj, "Scene2"); const char *transition = obs_data_get_string(array_obj, "transition"); + double duration = obs_data_get_double(array_obj, "duration"); switcher->sceneTransitions.emplace_back( GetWeakSourceByName(scene1), GetWeakSourceByName(scene2), - GetWeakTransitionByName(transition)); + GetWeakTransitionByName(transition), duration); obs_data_release(array_obj); } @@ -492,20 +500,29 @@ TransitionSwitchWidget::TransitionSwitchWidget(QWidget *parent, : SwitchWidget(parent, s, false, false, false) { scenes2 = new QComboBox(); + duration = new QDoubleSpinBox(); + + duration->setMinimum(0.0); + duration->setMaximum(99.000000); + duration->setSuffix("s"); QWidget::connect(scenes2, SIGNAL(currentTextChanged(const QString &)), this, SLOT(Scene2Changed(const QString &))); + QWidget::connect(duration, SIGNAL(valueChanged(double)), this, + SLOT(DurationChanged(double))); AdvSceneSwitcher::populateSceneSelection(scenes2, false); if (s) { scenes2->setCurrentText(GetWeakSourceName(s->scene2).c_str()); + duration->setValue(s->duration); } QHBoxLayout *mainLayout = new QHBoxLayout; std::unordered_map widgetPlaceholders = { {"{{scenes}}", scenes}, {"{{scenes2}}", scenes2}, + {"{{duration}}", duration}, {"{{transitions}}", transitions}}; placeWidgets(obs_module_text("AdvSceneSwitcher.transitionTab.entry"), mainLayout, widgetPlaceholders); @@ -546,6 +563,16 @@ void TransitionSwitchWidget::Scene2Changed(const QString &text) switchData->scene2 = GetWeakSourceByQString(text); } +void TransitionSwitchWidget::DurationChanged(double dur) +{ + if (loading || !switchData) { + return; + } + + std::lock_guard lock(switcher->m); + switchData->duration = dur; +} + DefTransitionSwitchWidget::DefTransitionSwitchWidget(QWidget *parent, DefaultSceneTransition *s) : SwitchWidget(parent, s, false, false, false)