Merge pull request #18 from exeldro/media

add media
This commit is contained in:
WarmUpTill 2020-04-26 15:09:51 +02:00 committed by GitHub
commit 9305576789
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 1387 additions and 726 deletions

View File

@ -51,6 +51,7 @@ if(BUILD_OUT_OF_TREE)
src/scene-round-trip.cpp
src/file-switch.cpp
src/window-title-switch.cpp
src/media-switch.cpp
src/hotkey.cpp
src/general.cpp
src/pause-switch.cpp
@ -175,6 +176,7 @@ else ()
src/scene-round-trip.cpp
src/file-switch.cpp
src/window-title-switch.cpp
src/media-switch.cpp
src/hotkey.cpp
src/general.cpp
src/pause-switch.cpp

View File

@ -2373,6 +2373,176 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="mediaTab">
<attribute name="title">
<string> Media </string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_11">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_39">
<item>
<widget class="QLabel" name="label_48">
<property name="text">
<string>When</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="mediaSources"/>
</item>
<item>
<widget class="QLabel" name="label_49">
<property name="text">
<string>state is</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="mediaStates"/>
</item>
<item>
<widget class="QLabel" name="label_50">
<property name="text">
<string>and</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="mediaTimeRestrictions"/>
</item>
<item>
<widget class="QSpinBox" name="mediaTime">
<property name="suffix">
<string notr="true">ms</string>
</property>
<property name="minimum">
<number>00</number>
</property>
<property name="maximum">
<number>1000000</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_51">
<property name="text">
<string>switch to</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="mediaScenes">
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_52">
<property name="text">
<string>using the</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="mediaTransitions"/>
</item>
<item>
<widget class="QLabel" name="label_53">
<property name="text">
<string>transition</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_29">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="QListWidget" name="mediaSwitches">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_40">
<property name="spacing">
<number>4</number>
</property>
<item>
<widget class="QPushButton" name="mediaAdd">
<property name="maximumSize">
<size>
<width>22</width>
<height>22</height>
</size>
</property>
<property name="flat">
<bool>true</bool>
</property>
<property name="themeID" stdset="0">
<string notr="true">addIconSmall</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="mediaRemove">
<property name="maximumSize">
<size>
<width>22</width>
<height>22</height>
</size>
</property>
<property name="flat">
<bool>true</bool>
</property>
<property name="themeID" stdset="0">
<string notr="true">removeIconSmall</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_35">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_54">
<property name="text">
<string>Implemented by Exeldro</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</widget>
</item>
</layout>

File diff suppressed because it is too large Load Diff

View File

@ -4,7 +4,7 @@
#include <memory>
#include <vector>
#include <string>
#ifdef BUILD_OUT_OF_TREE
#ifdef BUILD_OUT_OF_TREE
#include "../../forms/ui_advanced-scene-switcher.h"
#else
#include "ui_advanced-scene-switcher.h"
@ -13,7 +13,6 @@
class QCloseEvent;
/*******************************************************************************
* Advanced Scene Switcher window
*******************************************************************************/
@ -37,16 +36,17 @@ public:
int PauseWindowsFindByData(const QString &window);
int IgnoreWindowsFindByData(const QString &window);
int SceneRoundTripFindByData(const QString &scene1);
int SceneTransitionsFindByData(const QString &scene1, const QString &scene2);
int SceneTransitionsFindByData(const QString &scene1,
const QString &scene2);
int DefaultTransitionsFindByData(const QString &scene);
int executableFindByData(const QString &exe);
int IgnoreIdleWindowsFindByData(const QString& window);
int randomFindByData(const QString& scene);
int IgnoreIdleWindowsFindByData(const QString &window);
int randomFindByData(const QString &scene);
void UpdateNonMatchingScene(const QString &name);
void UpdateAutoStopScene(const QString &name);
void UpdateIdleDataTransition(const QString& name);
void UpdateIdleDataScene(const QString& name);
void UpdateIdleDataTransition(const QString &name);
void UpdateIdleDataScene(const QString &name);
public slots:
void on_switches_currentRowChanged(int idx);
@ -94,8 +94,8 @@ public slots:
void on_browseButton_clicked();
void on_readFileCheckBox_stateChanged(int state);
void on_readPathLineEdit_textChanged(const QString & text);
void on_writePathLineEdit_textChanged(const QString & text);
void on_readPathLineEdit_textChanged(const QString &text);
void on_writePathLineEdit_textChanged(const QString &text);
void on_browseButton_2_clicked();
void on_executableAdd_clicked();
@ -103,8 +103,8 @@ public slots:
void on_executables_currentRowChanged(int idx);
void on_idleCheckBox_stateChanged(int state);
void on_idleTransitions_currentTextChanged(const QString& text);
void on_idleScenes_currentTextChanged(const QString& text);
void on_idleTransitions_currentTextChanged(const QString &text);
void on_idleScenes_currentTextChanged(const QString &text);
void on_idleSpinBox_valueChanged(int i);
void on_ignoreIdleWindows_currentRowChanged(int idx);
void on_ignoreIdleAdd_clicked();
@ -119,6 +119,9 @@ public slots:
void on_fileScenesList_currentRowChanged(int idx);
void on_browseButton_3_clicked();
void on_mediaAdd_clicked();
void on_mediaRemove_clicked();
void on_priorityUp_clicked();
void on_priorityDown_clicked();
@ -127,7 +130,6 @@ public slots:
void on_close_clicked();
};
/********************************************************************************
* Windowtitle helper
********************************************************************************/
@ -135,35 +137,32 @@ void GetWindowList(std::vector<std::string> &windows);
void GetCurrentWindowTitle(std::string &title);
bool isFullscreen();
/********************************************************************************
* Screenregion helper
********************************************************************************/
pair<int, int> getCursorPos();
/********************************************************************************
* Idle detection helper
********************************************************************************/
int secondsSinceLastInput();
/********************************************************************************
* Executable helper
********************************************************************************/
void GetProcessList(QStringList &processes);
bool isInFocus(const QString &exeToCheck);
/********************************************************************************
* Sceneswitch helper
********************************************************************************/
struct obs_weak_source;
typedef struct obs_weak_source obs_weak_source_t;
obs_weak_source_t* getNextTransition(obs_weak_source_t* scene1, obs_weak_source_t* scene2);
void switchScene(OBSWeakSource& scene, OBSWeakSource& transition, unique_lock<mutex>& lock);
obs_weak_source_t *getNextTransition(obs_weak_source_t *scene1,
obs_weak_source_t *scene2);
void switchScene(OBSWeakSource &scene, OBSWeakSource &transition,
unique_lock<mutex> &lock);
/********************************************************************************
* Hotkey helper
@ -173,14 +172,16 @@ void switchScene(OBSWeakSource& scene, OBSWeakSource& transition, unique_lock<mu
#define STOP_HOTKEY_PATH "hotkey_stop.txt"
#define START_HOTKEY_PATH "hotkey_start.txt"
void stopHotkeyFunc(void* data, obs_hotkey_id id, obs_hotkey_t* hotkey, bool pressed);
void startHotkeyFunc(void* data, obs_hotkey_id id, obs_hotkey_t* hotkey, bool pressed);
void startStopToggleHotkeyFunc(void* data, obs_hotkey_id id, obs_hotkey_t* hotkey, bool pressed);
void stopHotkeyFunc(void *data, obs_hotkey_id id, obs_hotkey_t *hotkey,
bool pressed);
void startHotkeyFunc(void *data, obs_hotkey_id id, obs_hotkey_t *hotkey,
bool pressed);
void startStopToggleHotkeyFunc(void *data, obs_hotkey_id id,
obs_hotkey_t *hotkey, bool pressed);
void loadKeybinding(obs_hotkey_id hotkeyId, string path);
/********************************************************************************
* Main SwitcherData
********************************************************************************/
struct SwitcherData;
extern SwitcherData* switcher;
extern SwitcherData *switcher;

View File

@ -22,6 +22,7 @@
#define EXE_FUNC 3
#define SCREEN_REGION_FUNC 4
#define WINDOW_TITLE_FUNC 5
#define MEDIA_FUNC 6
#define DEFAULT_PRIORITY_0 READ_FILE_FUNC
#define DEFAULT_PRIORITY_1 ROUND_TRIP_FUNC
@ -29,69 +30,68 @@
#define DEFAULT_PRIORITY_3 EXE_FUNC
#define DEFAULT_PRIORITY_4 SCREEN_REGION_FUNC
#define DEFAULT_PRIORITY_5 WINDOW_TITLE_FUNC
#define DEFAULT_PRIORITY_6 MEDIA_FUNC
using namespace std;
/********************************************************************************
* Data structs for each scene switching method
********************************************************************************/
struct WindowSceneSwitch
{
struct WindowSceneSwitch {
OBSWeakSource scene;
string window;
OBSWeakSource transition;
bool fullscreen;
inline WindowSceneSwitch(
OBSWeakSource scene_, const char* window_, OBSWeakSource transition_, bool fullscreen_)
: scene(scene_)
, window(window_)
, transition(transition_)
, fullscreen(fullscreen_)
inline WindowSceneSwitch(OBSWeakSource scene_, const char *window_,
OBSWeakSource transition_, bool fullscreen_)
: scene(scene_),
window(window_),
transition(transition_),
fullscreen(fullscreen_)
{
}
};
struct ExecutableSceneSwitch
{
struct ExecutableSceneSwitch {
OBSWeakSource mScene;
OBSWeakSource mTransition;
QString mExe;
bool mInFocus;
inline ExecutableSceneSwitch(
OBSWeakSource scene, OBSWeakSource transition, const QString& exe, bool inFocus)
: mScene(scene)
, mTransition(transition)
, mExe(exe)
, mInFocus(inFocus)
inline ExecutableSceneSwitch(OBSWeakSource scene,
OBSWeakSource transition,
const QString &exe, bool inFocus)
: mScene(scene),
mTransition(transition),
mExe(exe),
mInFocus(inFocus)
{
}
};
struct ScreenRegionSwitch
{
struct ScreenRegionSwitch {
OBSWeakSource scene;
OBSWeakSource transition;
int minX, minY, maxX, maxY;
string regionStr;
inline ScreenRegionSwitch(OBSWeakSource scene_, OBSWeakSource transition_, int minX_, int minY_,
int maxX_, int maxY_, string regionStr_)
: scene(scene_)
, transition(transition_)
, minX(minX_)
, minY(minY_)
, maxX(maxX_)
, maxY(maxY_)
, regionStr(regionStr_)
inline ScreenRegionSwitch(OBSWeakSource scene_,
OBSWeakSource transition_, int minX_,
int minY_, int maxX_, int maxY_,
string regionStr_)
: scene(scene_),
transition(transition_),
minX(minX_),
minY(minY_),
maxX(maxX_),
maxY(maxY_),
regionStr(regionStr_)
{
}
};
struct SceneRoundTripSwitch
{
struct SceneRoundTripSwitch {
OBSWeakSource scene1;
OBSWeakSource scene2;
OBSWeakSource transition;
@ -99,69 +99,69 @@ struct SceneRoundTripSwitch
bool usePreviousScene;
string sceneRoundTripStr;
inline SceneRoundTripSwitch(OBSWeakSource scene1_, OBSWeakSource scene2_,
OBSWeakSource transition_, int delay_, bool usePreviousScene_, string str)
: scene1(scene1_)
, scene2(scene2_)
, transition(transition_)
, delay(delay_)
, usePreviousScene(usePreviousScene_)
, sceneRoundTripStr(str)
inline SceneRoundTripSwitch(OBSWeakSource scene1_,
OBSWeakSource scene2_,
OBSWeakSource transition_, int delay_,
bool usePreviousScene_, string str)
: scene1(scene1_),
scene2(scene2_),
transition(transition_),
delay(delay_),
usePreviousScene(usePreviousScene_),
sceneRoundTripStr(str)
{
}
};
struct RandomSwitch
{
struct RandomSwitch {
OBSWeakSource scene;
OBSWeakSource transition;
double delay;
string randomSwitchStr;
inline RandomSwitch(OBSWeakSource scene_, OBSWeakSource transition_
, double delay_, string str)
: scene(scene_)
, transition(transition_)
, delay(delay_)
, randomSwitchStr(str)
inline RandomSwitch(OBSWeakSource scene_, OBSWeakSource transition_,
double delay_, string str)
: scene(scene_),
transition(transition_),
delay(delay_),
randomSwitchStr(str)
{
}
};
struct SceneTransition
{
struct SceneTransition {
OBSWeakSource scene1;
OBSWeakSource scene2;
OBSWeakSource transition;
string sceneTransitionStr;
inline SceneTransition(OBSWeakSource scene1_, OBSWeakSource scene2_, OBSWeakSource transition_,
string sceneTransitionStr_)
: scene1(scene1_)
, scene2(scene2_)
, transition(transition_)
, sceneTransitionStr(sceneTransitionStr_)
inline SceneTransition(OBSWeakSource scene1_, OBSWeakSource scene2_,
OBSWeakSource transition_,
string sceneTransitionStr_)
: scene1(scene1_),
scene2(scene2_),
transition(transition_),
sceneTransitionStr(sceneTransitionStr_)
{
}
};
struct DefaultSceneTransition
{
struct DefaultSceneTransition {
OBSWeakSource scene;
OBSWeakSource transition;
string sceneTransitionStr;
inline DefaultSceneTransition(OBSWeakSource scene_, OBSWeakSource transition_,
string sceneTransitionStr_)
: scene(scene_)
, transition(transition_)
, sceneTransitionStr(sceneTransitionStr_)
inline DefaultSceneTransition(OBSWeakSource scene_,
OBSWeakSource transition_,
string sceneTransitionStr_)
: scene(scene_),
transition(transition_),
sceneTransitionStr(sceneTransitionStr_)
{
}
};
struct FileSwitch
{
struct FileSwitch {
OBSWeakSource scene;
OBSWeakSource transition;
string file;
@ -170,29 +170,28 @@ struct FileSwitch
bool useTime = false;
QDateTime lastMod;
inline FileSwitch(
OBSWeakSource scene_, OBSWeakSource transition_, const char* file_, const char* text_, bool useRegex_, bool useTime_)
: scene(scene_)
, transition(transition_)
, file(file_)
, text(text_)
, useRegex(useRegex_)
, useTime(useTime_)
, lastMod()
inline FileSwitch(OBSWeakSource scene_, OBSWeakSource transition_,
const char *file_, const char *text_, bool useRegex_,
bool useTime_)
: scene(scene_),
transition(transition_),
file(file_),
text(text_),
useRegex(useRegex_),
useTime(useTime_),
lastMod()
{
}
};
struct FileIOData
{
struct FileIOData {
bool readEnabled = false;
string readPath;
bool writeEnabled = false;
string writePath;
};
struct IdleData
{
struct IdleData {
bool idleEnable = false;
int time = DEFAULT_IDLE_TIME;
OBSWeakSource scene;
@ -201,18 +200,34 @@ struct IdleData
bool alreadySwitched = false;
};
typedef enum {
NO_SWITCH = 0,
SWITCH = 1,
RANDOM_SWITCH = 2
} NoMatch;
struct MediaSwitch {
OBSWeakSource scene;
OBSWeakSource source;
OBSWeakSource transition;
obs_media_state state;
uint64_t time;
time_restriction restriction;
bool matched;
inline MediaSwitch(OBSWeakSource scene_, OBSWeakSource source_,
OBSWeakSource transition_, obs_media_state state_,
time_restriction restriction_, uint64_t time_)
: scene(scene_),
source(source_),
transition(transition_),
state(state_),
restriction(restriction_),
time(time_)
{
}
};
typedef enum { NO_SWITCH = 0, SWITCH = 1, RANDOM_SWITCH = 2 } NoMatch;
/********************************************************************************
* SwitcherData
********************************************************************************/
struct SwitcherData
{
struct SwitcherData {
thread th;
condition_variable cv;
mutex m;
@ -224,7 +239,7 @@ struct SwitcherData
int interval = DEFAULT_INTERVAL;
obs_source_t* waitScene = NULL; //scene during which wait started
obs_source_t *waitScene = NULL; //scene during which wait started
OBSWeakSource previousScene = NULL;
OBSWeakSource PreviousScene2 = NULL;
OBSWeakSource lastRandomScene;
@ -259,14 +274,12 @@ struct SwitcherData
vector<SceneTransition> sceneTransitions;
vector<DefaultSceneTransition> defaultSceneTransitions;
vector<MediaSwitch> mediaSwitches;
vector<int> functionNamesByPriority = vector<int>{
DEFAULT_PRIORITY_0,
DEFAULT_PRIORITY_1,
DEFAULT_PRIORITY_2,
DEFAULT_PRIORITY_3,
DEFAULT_PRIORITY_4,
DEFAULT_PRIORITY_5,
};
DEFAULT_PRIORITY_0, DEFAULT_PRIORITY_1, DEFAULT_PRIORITY_2,
DEFAULT_PRIORITY_3, DEFAULT_PRIORITY_4, DEFAULT_PRIORITY_5,
DEFAULT_PRIORITY_6};
void Thread();
void Start();
@ -278,101 +291,116 @@ struct SwitcherData
void setDefaultSceneTransitions();
void autoStopStreamAndRecording();
bool checkPause();
void checkSceneRoundTrip(bool& match, OBSWeakSource& scene, OBSWeakSource& transition, unique_lock<mutex>& lock);
void checkIdleSwitch(bool& match, OBSWeakSource& scene, OBSWeakSource& transition);
void checkWindowTitleSwitch(bool& match, OBSWeakSource& scene, OBSWeakSource& transition);
void checkExeSwitch(bool& match, OBSWeakSource& scene, OBSWeakSource& transition);
void checkScreenRegionSwitch(bool& match, OBSWeakSource& scene, OBSWeakSource& transition);
void checkSwitchInfoFromFile(bool& match, OBSWeakSource& scene, OBSWeakSource& transition);
void checkFileContent(bool& match, OBSWeakSource& scene, OBSWeakSource& transition);
void checkRandom(bool& match, OBSWeakSource& scene, OBSWeakSource& transition, int& delay);
void checkSceneRoundTrip(bool &match, OBSWeakSource &scene,
OBSWeakSource &transition,
unique_lock<mutex> &lock);
void checkIdleSwitch(bool &match, OBSWeakSource &scene,
OBSWeakSource &transition);
void checkWindowTitleSwitch(bool &match, OBSWeakSource &scene,
OBSWeakSource &transition);
void checkExeSwitch(bool &match, OBSWeakSource &scene,
OBSWeakSource &transition);
void checkScreenRegionSwitch(bool &match, OBSWeakSource &scene,
OBSWeakSource &transition);
void checkSwitchInfoFromFile(bool &match, OBSWeakSource &scene,
OBSWeakSource &transition);
void checkFileContent(bool &match, OBSWeakSource &scene,
OBSWeakSource &transition);
void checkRandom(bool &match, OBSWeakSource &scene,
OBSWeakSource &transition, int &delay);
void checkMediaSwitch(bool &match, OBSWeakSource &scene,
OBSWeakSource &transition);
void Prune()
{
for (size_t i = 0; i < windowSwitches.size(); i++)
{
WindowSceneSwitch& s = windowSwitches[i];
if (!WeakSourceValid(s.scene) || !WeakSourceValid(s.transition))
windowSwitches.erase(windowSwitches.begin() + i--);
for (size_t i = 0; i < windowSwitches.size(); i++) {
WindowSceneSwitch &s = windowSwitches[i];
if (!WeakSourceValid(s.scene) ||
!WeakSourceValid(s.transition))
windowSwitches.erase(windowSwitches.begin() +
i--);
}
if (nonMatchingScene && !WeakSourceValid(nonMatchingScene))
{
if (nonMatchingScene && !WeakSourceValid(nonMatchingScene)) {
switchIfNotMatching = NO_SWITCH;
nonMatchingScene = nullptr;
}
for (size_t i = 0; i < randomSwitches.size(); i++)
{
RandomSwitch& s = randomSwitches[i];
if (!WeakSourceValid(s.scene) || !WeakSourceValid(s.transition))
randomSwitches.erase(randomSwitches.begin() + i--);
for (size_t i = 0; i < randomSwitches.size(); i++) {
RandomSwitch &s = randomSwitches[i];
if (!WeakSourceValid(s.scene) ||
!WeakSourceValid(s.transition))
randomSwitches.erase(randomSwitches.begin() +
i--);
}
for (size_t i = 0; i < screenRegionSwitches.size(); i++)
{
ScreenRegionSwitch& s = screenRegionSwitches[i];
if (!WeakSourceValid(s.scene) || !WeakSourceValid(s.transition))
screenRegionSwitches.erase(screenRegionSwitches.begin() + i--);
for (size_t i = 0; i < screenRegionSwitches.size(); i++) {
ScreenRegionSwitch &s = screenRegionSwitches[i];
if (!WeakSourceValid(s.scene) ||
!WeakSourceValid(s.transition))
screenRegionSwitches.erase(
screenRegionSwitches.begin() + i--);
}
for (size_t i = 0; i < pauseScenesSwitches.size(); i++)
{
OBSWeakSource& scene = pauseScenesSwitches[i];
for (size_t i = 0; i < pauseScenesSwitches.size(); i++) {
OBSWeakSource &scene = pauseScenesSwitches[i];
if (!WeakSourceValid(scene))
pauseScenesSwitches.erase(pauseScenesSwitches.begin() + i--);
pauseScenesSwitches.erase(
pauseScenesSwitches.begin() + i--);
}
for (size_t i = 0; i < sceneRoundTripSwitches.size(); i++)
{
SceneRoundTripSwitch& s = sceneRoundTripSwitches[i];
if (!WeakSourceValid(s.scene1) || (!s.usePreviousScene && !WeakSourceValid(s.scene2))
|| !WeakSourceValid(s.transition))
sceneRoundTripSwitches.erase(sceneRoundTripSwitches.begin() + i--);
for (size_t i = 0; i < sceneRoundTripSwitches.size(); i++) {
SceneRoundTripSwitch &s = sceneRoundTripSwitches[i];
if (!WeakSourceValid(s.scene1) ||
(!s.usePreviousScene &&
!WeakSourceValid(s.scene2)) ||
!WeakSourceValid(s.transition))
sceneRoundTripSwitches.erase(
sceneRoundTripSwitches.begin() + i--);
}
if (!WeakSourceValid(autoStopScene))
{
if (!WeakSourceValid(autoStopScene)) {
autoStopScene = nullptr;
autoStopEnable = false;
}
for (size_t i = 0; i < sceneTransitions.size(); i++)
{
SceneTransition& s = sceneTransitions[i];
if (!WeakSourceValid(s.scene1) || !WeakSourceValid(s.scene2)
|| !WeakSourceValid(s.transition))
sceneTransitions.erase(sceneTransitions.begin() + i--);
for (size_t i = 0; i < sceneTransitions.size(); i++) {
SceneTransition &s = sceneTransitions[i];
if (!WeakSourceValid(s.scene1) ||
!WeakSourceValid(s.scene2) ||
!WeakSourceValid(s.transition))
sceneTransitions.erase(
sceneTransitions.begin() + i--);
}
for (size_t i = 0; i < defaultSceneTransitions.size(); i++)
{
DefaultSceneTransition& s = defaultSceneTransitions[i];
if (!WeakSourceValid(s.scene) || !WeakSourceValid(s.transition))
defaultSceneTransitions.erase(defaultSceneTransitions.begin() + i--);
for (size_t i = 0; i < defaultSceneTransitions.size(); i++) {
DefaultSceneTransition &s = defaultSceneTransitions[i];
if (!WeakSourceValid(s.scene) ||
!WeakSourceValid(s.transition))
defaultSceneTransitions.erase(
defaultSceneTransitions.begin() + i--);
}
for (size_t i = 0; i < executableSwitches.size(); i++)
{
ExecutableSceneSwitch& s = executableSwitches[i];
if (!WeakSourceValid(s.mScene) || !WeakSourceValid(s.mTransition))
executableSwitches.erase(executableSwitches.begin() + i--);
for (size_t i = 0; i < executableSwitches.size(); i++) {
ExecutableSceneSwitch &s = executableSwitches[i];
if (!WeakSourceValid(s.mScene) ||
!WeakSourceValid(s.mTransition))
executableSwitches.erase(
executableSwitches.begin() + i--);
}
for (size_t i = 0; i < fileSwitches.size(); i++)
{
FileSwitch& s = fileSwitches[i];
if (!WeakSourceValid(s.scene) || !WeakSourceValid(s.transition))
for (size_t i = 0; i < fileSwitches.size(); i++) {
FileSwitch &s = fileSwitches[i];
if (!WeakSourceValid(s.scene) ||
!WeakSourceValid(s.transition))
fileSwitches.erase(fileSwitches.begin() + i--);
}
if (!idleData.usePreviousScene && !WeakSourceValid(idleData.scene) || !WeakSourceValid(idleData.transition))
{
if (!idleData.usePreviousScene &&
!WeakSourceValid(idleData.scene) ||
!WeakSourceValid(idleData.transition)) {
idleData.idleEnable = false;
}
}
inline ~SwitcherData()
{
Stop();
}
inline ~SwitcherData() { Stop(); }
};

View File

@ -13,67 +13,85 @@ static inline bool WeakSourceValid(obs_weak_source_t* ws)
return !!source;
}
static inline QString MakeSwitchName(
const QString& scene, const QString& value, const QString& transition, bool fullscreen)
static inline QString MakeSwitchName(const QString &scene, const QString &value,
const QString &transition, bool fullscreen)
{
if (!fullscreen)
return QStringLiteral("[") + scene + QStringLiteral(", ") + transition
+ QStringLiteral("]: ") + value;
return QStringLiteral("[") + scene + QStringLiteral(", ") + transition + QStringLiteral("]: ")
+ value + QStringLiteral(" (only if window is fullscreen)");
return QStringLiteral("[") + scene + QStringLiteral(", ") +
transition + QStringLiteral("]: ") + value;
return QStringLiteral("[") + scene + QStringLiteral(", ") + transition +
QStringLiteral("]: ") + value +
QStringLiteral(" (only if window is fullscreen)");
}
static inline QString MakeSwitchNameExecutable(
const QString& scene, const QString& value, const QString& transition, bool inFocus)
static inline QString MakeSwitchNameExecutable(const QString &scene,
const QString &value,
const QString &transition,
bool inFocus)
{
if (!inFocus)
return QStringLiteral("[") + scene + QStringLiteral(", ") + transition
+ QStringLiteral("]: ") + value;
return QStringLiteral("[") + scene + QStringLiteral(", ") + transition + QStringLiteral("]: ")
+ value + QStringLiteral(" (only if window is focused)");
return QStringLiteral("[") + scene + QStringLiteral(", ") +
transition + QStringLiteral("]: ") + value;
return QStringLiteral("[") + scene + QStringLiteral(", ") + transition +
QStringLiteral("]: ") + value +
QStringLiteral(" (only if window is focused)");
}
static inline QString MakeScreenRegionSwitchName(
const QString& scene, const QString& transition, int minX, int minY, int maxX, int maxY)
static inline QString MakeScreenRegionSwitchName(const QString &scene,
const QString &transition,
int minX, int minY, int maxX,
int maxY)
{
return QStringLiteral("[") + scene + QStringLiteral(", ") + transition + QStringLiteral("]: ")
+ QString::number(minX) + QStringLiteral(", ") + QString::number(minY)
+ QStringLiteral(" x ") + QString::number(maxX) + QStringLiteral(", ")
+ QString::number(maxY);
return QStringLiteral("[") + scene + QStringLiteral(", ") + transition +
QStringLiteral("]: ") + QString::number(minX) +
QStringLiteral(", ") + QString::number(minY) +
QStringLiteral(" x ") + QString::number(maxX) +
QStringLiteral(", ") + QString::number(maxY);
}
static inline QString MakeSceneRoundTripSwitchName(
const QString& scene1, const QString& scene2, const QString& transition, double delay)
static inline QString MakeSceneRoundTripSwitchName(const QString &scene1,
const QString &scene2,
const QString &transition,
double delay)
{
return scene1 + QStringLiteral(" -> wait for ") + QString::number(delay)
+ QStringLiteral(" seconds -> ") + scene2 + QStringLiteral(" (using ") + transition
+ QStringLiteral(" transition)");
return scene1 + QStringLiteral(" -> wait for ") +
QString::number(delay) + QStringLiteral(" seconds -> ") +
scene2 + QStringLiteral(" (using ") + transition +
QStringLiteral(" transition)");
}
static inline QString MakeSceneTransitionName(
const QString& scene1, const QString& scene2, const QString& transition)
static inline QString MakeSceneTransitionName(const QString &scene1,
const QString &scene2,
const QString &transition)
{
return scene1 + QStringLiteral(" --- ") + transition + QStringLiteral(" --> ") + scene2;
return scene1 + QStringLiteral(" --- ") + transition +
QStringLiteral(" --> ") + scene2;
}
static inline QString MakeDefaultSceneTransitionName(
const QString& scene, const QString& transition)
static inline QString MakeDefaultSceneTransitionName(const QString &scene,
const QString &transition)
{
return scene + QStringLiteral(" --> ") + transition;
}
static inline QString MakeRandomSwitchName(
const QString& scene, const QString& transition, double& delay)
static inline QString MakeRandomSwitchName(const QString &scene,
const QString &transition,
double &delay)
{
return QStringLiteral("[") + scene + QStringLiteral(", ") + transition + QStringLiteral("]: ")
+ QString::number(delay) + QStringLiteral(" seconds");
return QStringLiteral("[") + scene + QStringLiteral(", ") + transition +
QStringLiteral("]: ") + QString::number(delay) +
QStringLiteral(" seconds");
}
static inline QString MakeFileSwitchName(
const QString& scene, const QString& transition, const QString& fileName, const QString& text, bool useRegex, bool useTime)
static inline QString MakeFileSwitchName(const QString &scene,
const QString &transition,
const QString &fileName,
const QString &text, bool useRegex,
bool useTime)
{
QString switchName = QStringLiteral("Switch to ") + scene + QStringLiteral(" using ") + transition + QStringLiteral(" if ")
+ fileName;
QString switchName = QStringLiteral("Switch to ") + scene +
QStringLiteral(" using ") + transition +
QStringLiteral(" if ") + fileName;
if (useTime)
switchName += QStringLiteral(" was modified and");
switchName += QStringLiteral(" contains");
@ -89,13 +107,64 @@ static inline QString MakeFileSwitchName(
return switchName;
}
static inline string GetWeakSourceName(obs_weak_source_t* weak_source)
typedef enum {
TIME_RESTRICTION_NONE,
TIME_RESTRICTION_SHORTER,
TIME_RESTRICTION_LONGER,
TIME_RESTRICTION_REMAINING_SHORTER,
TIME_RESTRICTION_REMAINING_LONGER,
} time_restriction;
static inline QString
MakeMediaSwitchName(const QString &source, const QString &scene,
const QString &transition, obs_media_state state,
time_restriction restriction, uint64_t time)
{
QString switchName = QStringLiteral("Switch to ") + scene +
QStringLiteral(" using ") + transition +
QStringLiteral(" if ") + source +
QStringLiteral(" state is ");
if (state == OBS_MEDIA_STATE_NONE) {
switchName += QStringLiteral("none");
} else if (state == OBS_MEDIA_STATE_PLAYING) {
switchName += QStringLiteral("playing");
} else if (state == OBS_MEDIA_STATE_OPENING) {
switchName += QStringLiteral("opening");
} else if (state == OBS_MEDIA_STATE_BUFFERING) {
switchName += QStringLiteral("buffering");
} else if (state == OBS_MEDIA_STATE_PAUSED) {
switchName += QStringLiteral("paused");
} else if (state == OBS_MEDIA_STATE_STOPPED) {
switchName += QStringLiteral("stopped");
} else if (state == OBS_MEDIA_STATE_ENDED) {
switchName += QStringLiteral("ended");
} else if (state == OBS_MEDIA_STATE_ERROR) {
switchName += QStringLiteral("error");
}
if (restriction == TIME_RESTRICTION_SHORTER) {
switchName += QStringLiteral(" and time shorter than ");
} else if (restriction == TIME_RESTRICTION_LONGER) {
switchName += QStringLiteral(" and time longer than ");
} else if (restriction == TIME_RESTRICTION_REMAINING_SHORTER) {
switchName +=
QStringLiteral(" and time remaining shorter than ");
} else if (restriction == TIME_RESTRICTION_REMAINING_LONGER) {
switchName +=
QStringLiteral(" and time remaining longer than ");
}
if (restriction != TIME_RESTRICTION_NONE) {
switchName += std::to_string(time).c_str();
switchName += QStringLiteral(" ms");
}
return switchName;
}
static inline string GetWeakSourceName(obs_weak_source_t *weak_source)
{
string name;
obs_source_t* source = obs_weak_source_get_source(weak_source);
if (source)
{
obs_source_t *source = obs_weak_source_get_source(weak_source);
if (source) {
name = obs_source_get_name(source);
obs_source_release(source);
}
@ -103,12 +172,11 @@ static inline string GetWeakSourceName(obs_weak_source_t* weak_source)
return name;
}
static inline OBSWeakSource GetWeakSourceByName(const char* name)
static inline OBSWeakSource GetWeakSourceByName(const char *name)
{
OBSWeakSource weak;
obs_source_t* source = obs_get_source_by_name(name);
if (source)
{
obs_source_t *source = obs_get_source_by_name(name);
if (source) {
weak = obs_source_get_weak_source(source);
obs_weak_source_release(weak);
obs_source_release(source);
@ -117,18 +185,17 @@ static inline OBSWeakSource GetWeakSourceByName(const char* name)
return weak;
}
static inline OBSWeakSource GetWeakSourceByQString(const QString& name)
static inline OBSWeakSource GetWeakSourceByQString(const QString &name)
{
return GetWeakSourceByName(name.toUtf8().constData());
}
static inline OBSWeakSource GetWeakTransitionByName(const char* transitionName)
static inline OBSWeakSource GetWeakTransitionByName(const char *transitionName)
{
OBSWeakSource weak;
obs_source_t* source = nullptr;
obs_source_t *source = nullptr;
if (strcmp(transitionName, "Default") == 0)
{
if (strcmp(transitionName, "Default") == 0) {
source = obs_frontend_get_current_transition();
weak = obs_source_get_weak_source(source);
obs_source_release(source);
@ -136,22 +203,21 @@ static inline OBSWeakSource GetWeakTransitionByName(const char* transitionName)
return weak;
}
obs_frontend_source_list* transitions = new obs_frontend_source_list();
obs_frontend_source_list *transitions = new obs_frontend_source_list();
obs_frontend_get_transitions(transitions);
bool match = false;
for (size_t i = 0; i < transitions->sources.num; i++)
{
const char* name = obs_source_get_name(transitions->sources.array[i]);
if (strcmp(transitionName, name) == 0)
{
for (size_t i = 0; i < transitions->sources.num; i++) {
const char *name =
obs_source_get_name(transitions->sources.array[i]);
if (strcmp(transitionName, name) == 0) {
match = true;
source = transitions->sources.array[i];
break;
}
}
if (match){
if (match) {
weak = obs_source_get_weak_source(source);
obs_weak_source_release(weak);
}
@ -160,7 +226,7 @@ static inline OBSWeakSource GetWeakTransitionByName(const char* transitionName)
return weak;
}
static inline OBSWeakSource GetWeakTransitionByQString(const QString& name)
static inline OBSWeakSource GetWeakTransitionByQString(const QString &name)
{
return GetWeakTransitionByName(name.toUtf8().constData());
}

87
src/media-switch.cpp Normal file
View File

@ -0,0 +1,87 @@
#include <obs-module.h>
#include "headers/advanced-scene-switcher.hpp"
void SceneSwitcher::on_mediaAdd_clicked()
{
QString sourceName = ui->mediaSources->currentText();
QString sceneName = ui->mediaScenes->currentText();
QString transitionName = ui->mediaTransitions->currentText();
obs_media_state state =
(obs_media_state)ui->mediaStates->currentIndex();
time_restriction restriction =
(time_restriction)ui->mediaTimeRestrictions->currentIndex();
uint64_t time = ui->mediaTime->value();
if (sceneName.isEmpty() || transitionName.isEmpty() ||
sourceName.isEmpty())
return;
OBSWeakSource source = GetWeakSourceByQString(sourceName);
OBSWeakSource scene = GetWeakSourceByQString(sceneName);
OBSWeakSource transition = GetWeakTransitionByQString(transitionName);
QString switchText = MakeMediaSwitchName(sourceName, sceneName,
transitionName, state,
restriction, time);
QVariant v = QVariant::fromValue(switchText);
QListWidgetItem *item =
new QListWidgetItem(switchText, ui->mediaSwitches);
item->setData(Qt::UserRole, v);
lock_guard<mutex> lock(switcher->m);
switcher->mediaSwitches.emplace_back(scene, source, transition, state,
restriction, time);
}
void SceneSwitcher::on_mediaRemove_clicked()
{
QListWidgetItem *item = ui->mediaSwitches->currentItem();
if (!item)
return;
int idx = ui->mediaSwitches->currentRow();
if (idx == -1)
return;
{
lock_guard<mutex> lock(switcher->m);
auto &switches = switcher->mediaSwitches;
switches.erase(switches.begin() + idx);
}
qDeleteAll(ui->mediaSwitches->selectedItems());
}
void SwitcherData::checkMediaSwitch(bool &match, OBSWeakSource &scene,
OBSWeakSource &transition)
{
for (MediaSwitch &mediaSwitch : mediaSwitches) {
obs_source_t *source =
obs_weak_source_get_source(mediaSwitch.source);
auto duration = obs_source_media_get_duration(source);
auto time = obs_source_media_get_time(source);
obs_media_state state = obs_source_media_get_state(source);
bool matched =
state == mediaSwitch.state &&
(mediaSwitch.restriction == TIME_RESTRICTION_NONE ||
(mediaSwitch.restriction == TIME_RESTRICTION_LONGER &&
time > mediaSwitch.time) ||
(mediaSwitch.restriction == TIME_RESTRICTION_SHORTER &&
time < mediaSwitch.time) ||
(mediaSwitch.restriction ==
TIME_RESTRICTION_REMAINING_SHORTER &&
duration > time &&
duration - time < mediaSwitch.time) ||
(mediaSwitch.restriction ==
TIME_RESTRICTION_REMAINING_LONGER &&
duration > time &&
duration - time > mediaSwitch.time));
if (matched && !mediaSwitch.matched) {
match = true;
scene = mediaSwitch.scene;
transition = mediaSwitch.transition;
}
mediaSwitch.matched = matched;
}
}

View File

@ -36,7 +36,7 @@ bool SwitcherData::prioFuncsValid()
for (int p : functionNamesByPriority)
{
if (p < 0 || p > 5)
if (p < 0 || p > 6)
return false;
}
return true;