Compare commits

...

14 Commits
1.5 ... 1.6

Author SHA1 Message Date
WarmUpTill
80cc8ba06c fix install_name_tool path for libobs 2020-06-01 15:21:45 +02:00
WarmUpTill
f1d5b110b8 adjustments for macos installer
adjust default install path
adjust lib lookup paths
2020-06-01 14:56:59 +02:00
WarmUpTill
2e475b8059 add first draft of thread priority 2020-06-01 14:54:08 +02:00
WarmUpTill
99b5c16406 add Time scene switching 2020-05-31 12:43:34 +02:00
WarmUpTill
9bedeedcb6 fix issue with out-of-tree builds not being able to find *ui on some platforms 2020-05-22 19:41:48 +02:00
WarmUpTill
a88a5bb2da adjust macos pkg name 2020-05-21 21:04:26 +02:00
WarmUpTill
cfd6be2ba0 fix mac and linux builds
ignore data/ dir as it is not used by this plugin
adjust path to .so in SceneSwitcher.pkgproj
2020-05-21 20:53:49 +02:00
WarmUpTill
3658efff20 add missing env. 2020-05-21 20:16:37 +02:00
WarmUpTill
8331b50c5a try to resovle github actions issues
add CI/ for mac
use LIB_NAME instead of PLUGIN_NAME when saving results
2020-05-21 20:11:17 +02:00
WarmUpTill
7a343c2070 try setting up actions 2020-05-21 19:19:08 +02:00
WarmUpTill
228a18eb77 fix media switch not saving when using previous scene as target 2020-04-27 20:51:58 +02:00
WarmUpTill
4ed12db12b add support for previous scene on media tab 2020-04-27 20:20:50 +02:00
WarmUpTill
b20b894b2f add hint about install_name_tool for MacOS builds 2020-04-27 19:39:05 +02:00
WarmUpTill
7c052f2633 do not link against X11 for MAC in-tree builds 2020-04-27 18:46:32 +02:00
13 changed files with 1588 additions and 26 deletions

284
.github/workflows/build.yml vendored Normal file
View File

@@ -0,0 +1,284 @@
name: build obs plugin
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
env:
PLUGIN_NAME: SceneSwitcher
LIB_NAME: advanced-scene-switcher
jobs:
macos64:
name: "macOS 64-bit"
runs-on: [macos-latest]
env:
QT_VERSION: 5.14.1
OSX_DEPS_VERSION: '2020-04-07'
steps:
- name: Checkout
uses: actions/checkout@v2
with:
repository: obsproject/obs-studio
submodules: 'recursive'
- name: "Checkout plugin"
uses: actions/checkout@v2
with:
path: UI/frontend-plugins/${{ env.PLUGIN_NAME }}
- name: Fetch Git Tags
run: |
cd UI/frontend-plugins/${{ env.PLUGIN_NAME }}
git fetch --prune --tags --unshallow
- name: 'Install prerequisites (Homebrew)'
shell: bash
run: |
cd UI/frontend-plugins/${{ env.PLUGIN_NAME }}/CI/macos
brew bundle
cd -
- name: 'Install prerequisite: Pre-built dependencies'
shell: bash
run: |
curl -L -O https://github.com/obsproject/obs-deps/releases/download/${{ env.OSX_DEPS_VERSION }}/osx-deps-${{ env.OSX_DEPS_VERSION }}.tar.gz
tar -xf ./osx-deps-${{ env.OSX_DEPS_VERSION }}.tar.gz -C "/tmp"
- name: Configure
shell: bash
run: |
echo "add_subdirectory(${{ env.PLUGIN_NAME }})" >> UI/frontend-plugins/CMakeLists.txt
mkdir ./build
cd ./build
cmake -DCMAKE_OSX_DEPLOYMENT_TARGET=10.11 -DDepsPath="/tmp/obsdeps" -DQTDIR="/usr/local/Cellar/qt/${{ env.QT_VERSION }}" ..
cd -
- name: Build
shell: bash
run: |
set -e
cd ./build
make -j4
cd -
- name: 'Install prerequisite: Packages app'
if: success()
shell: bash
run: |
curl -L -O https://s3-us-west-2.amazonaws.com/obs-nightly/Packages.pkg
sudo installer -pkg ./Packages.pkg -target /
- name: Package
if: success()
shell: bash
run: |
cd UI/frontend-plugins/${{ env.PLUGIN_NAME }}
install_name_tool -change @rpath/libobs-frontend-api.dylib @executable_path/../Frameworks/libobs-frontend-api.dylib ../../../build/UI/frontend-plugins/SceneSwitcher/advanced-scene-switcher.so
install_name_tool -change @rpath/libobs.0.dylib @executable_path/../Frameworks/libobs.0.dylib ../../../build/UI/frontend-plugins/SceneSwitcher/advanced-scene-switcher.so
install_name_tool -change /usr/local/opt/qt5/lib/QtWidgets.framework/Versions/5/QtWidgets @executable_path/../Frameworks/QtWidgets.framework/Versions/5/QtWidgets ../../../build/UI/frontend-plugins/SceneSwitcher/advanced-scene-switcher.so
install_name_tool -change /usr/local/opt/qt5/lib/QtGui.framework/Versions/5/QtGui @executable_path/../Frameworks/QtGui.framework/Versions/5/QtGui ../../../build/UI/frontend-plugins/SceneSwitcher/advanced-scene-switcher.so
install_name_tool -change /usr/local/opt/qt5/lib/QtCore.framework/Versions/5/QtCore @executable_path/../Frameworks/QtCore.framework/Versions/5/QtCore ../../../build/UI/frontend-plugins/SceneSwitcher/advanced-scene-switcher.so
FILE_DATE=$(date +%Y-%m-%d)
FILE_NAME=${{ env.PLUGIN_NAME }}-$FILE_DATE-${{ github.sha }}-macos.pkg
echo "::set-env name=FILE_NAME::${FILE_NAME}"
packagesbuild ./CI/macos/${{ env.PLUGIN_NAME }}.pkgproj
cd -
mkdir ./nightly
mv UI/frontend-plugins/${{ env.PLUGIN_NAME }}/${{ env.PLUGIN_NAME }}.pkg ./nightly/${FILE_NAME}
- name: Publish
if: success()
uses: actions/upload-artifact@v2-preview
with:
name: '${{ env.FILE_NAME }}'
path: ./nightly/*.pkg
ubuntu64:
name: 'Linux/Ubuntu 64-bit'
runs-on: [ubuntu-latest]
steps:
- name: Checkout
uses: actions/checkout@v2
with:
repository: obsproject/obs-studio
submodules: 'recursive'
- name: "Checkout plugin"
uses: actions/checkout@v2
with:
path: UI/frontend-plugins/${{ env.PLUGIN_NAME }}
- name: Add plugin to obs cmake
shell: bash
run: echo "add_subdirectory(${{ env.PLUGIN_NAME }})" >> UI/frontend-plugins/CMakeLists.txt
- name: Fetch Git Tags
run: git fetch --prune --tags --unshallow
- name: Install prerequisites (Apt)
shell: bash
run: |
sudo dpkg --add-architecture amd64
sudo apt-get -qq update
sudo apt-get install -y \
build-essential \
checkinstall \
cmake \
libasound2-dev \
libavcodec-dev \
libavdevice-dev \
libavfilter-dev \
libavformat-dev \
libavutil-dev \
libcurl4-openssl-dev \
libfdk-aac-dev \
libfontconfig-dev \
libfreetype6-dev \
libgl1-mesa-dev \
libjack-jackd2-dev \
libjansson-dev \
libluajit-5.1-dev \
libpulse-dev \
libqt5x11extras5-dev \
libspeexdsp-dev \
libswresample-dev \
libswscale-dev \
libudev-dev \
libv4l-dev \
libva-dev \
libvlc-dev \
libx11-dev \
libx264-dev \
libxcb-randr0-dev \
libxcb-shm0-dev \
libxcb-xinerama0-dev \
libxcomposite-dev \
libxinerama-dev \
libmbedtls-dev \
pkg-config \
python3-dev \
qtbase5-dev \
libqt5svg5-dev \
swig \
libxss-dev
- name: 'Configure'
shell: bash
run: |
mkdir ./build
cd ./build
cmake -DUNIX_STRUCTURE=0 -DCMAKE_INSTALL_PREFIX="${{ github.workspace }}/obs-studio-portable" -DBUILD_CAPTIONS=OFF -DWITH_RTMPS=OFF -DBUILD_BROWSER=OFF ..
- name: 'Build'
shell: bash
working-directory: ${{ github.workspace }}/build
run: make -j4
- name: 'Package'
shell: bash
run: |
FILE_DATE=$(date +%Y-%m-%d)
FILE_NAME=${{ env.PLUGIN_NAME }}-$FILE_DATE-${{ github.sha }}-linux64.tar.gz
echo "::set-env name=FILE_NAME::${FILE_NAME}"
mkdir -p ./${{ env.PLUGIN_NAME }}/bin/64bit/
mv ./build/UI/frontend-plugins/${{ env.PLUGIN_NAME }}/${{ env.LIB_NAME }}.so ./${{ env.PLUGIN_NAME }}/bin/64bit/${{ env.LIB_NAME }}.so
tar -cvzf "${FILE_NAME}" ${{ env.PLUGIN_NAME }}
- name: 'Publish'
uses: actions/upload-artifact@v2-preview
with:
name: '${{ env.FILE_NAME }}'
path: '*.tar.gz'
win64:
name: Windows 64-bit
runs-on: [windows-latest]
env:
QT_VERSION: 5.10.1
CMAKE_GENERATOR: "Visual Studio 16 2019"
CMAKE_SYSTEM_VERSION: "10.0.18363.657"
steps:
- name: Add msbuild to PATH
uses: microsoft/setup-msbuild@v1.0.0
- name: Checkout obs
uses: actions/checkout@v2
with:
repository: obsproject/obs-studio
submodules: 'recursive'
- name: Checkout plugin
uses: actions/checkout@v2
with:
path: UI/frontend-plugins/${{ env.PLUGIN_NAME}}
- name: Add plugin to obs cmake
shell: cmd
run: echo add_subdirectory(${{ env.PLUGIN_NAME }}) >> UI/frontend-plugins/CMakeLists.txt
- name: Fetch Git Tags
run: git fetch --prune --tags --unshallow
- name: 'Install prerequisite: QT'
run: |
curl -kLO https://cdn-fastly.obsproject.com/downloads/Qt_${{ env.QT_VERSION }}.7z -f --retry 5 -C -
7z x Qt_${{ env.QT_VERSION }}.7z -o"${{ github.workspace }}/cmbuild/QT"
- name: 'Install prerequisite: Pre-built dependencies'
run: |
curl -kLO https://cdn-fastly.obsproject.com/downloads/dependencies2017.zip -f --retry 5 -C -
7z x dependencies2017.zip -o"${{ github.workspace }}/cmbuild/deps"
- name: Configure
run: |
mkdir ./build
mkdir ./build64
cd ./build64
cmake -G"${{ env.CMAKE_GENERATOR }}" -A"x64" -DCMAKE_SYSTEM_VERSION="${{ env.CMAKE_SYSTEM_VERSION }}" -DBUILD_BROWSER=false -DBUILD_CAPTIONS=false -DCOMPILE_D3D12_HOOK=false -DDepsPath="${{ github.workspace }}/cmbuild/deps/win64" -DQTDIR="${{ github.workspace }}/cmbuild/QT/${{ env.QT_VERSION }}/msvc2017_64" -DCOPIED_DEPENDENCIES=FALSE -DCOPY_DEPENDENCIES=TRUE ..
- name: Build
run: msbuild /m /p:Configuration=RelWithDebInfo .\build64\obs-studio.sln
- name: Package
if: success()
run: |
$env:FILE_DATE=(Get-Date -UFormat "%F")
$env:FILE_NAME="${{ env.PLUGIN_NAME }}-${env:FILE_DATE}-${{ github.sha }}-win64.zip"
echo "::set-env name=FILE_NAME::${env:FILE_NAME}"
robocopy .\build64\rundir\RelWithDebInfo\obs-plugins\64bit\ .\build\obs-plugins\64bit ${{ env.LIB_NAME }}.* /E /XF .gitignore
7z a ${env:FILE_NAME} .\build\*
- name: Publish
if: success()
uses: actions/upload-artifact@v2-preview
with:
name: '${{ env.FILE_NAME }}'
path: '*-win64.zip'
win32:
name: Windows 32-bit
runs-on: [windows-latest]
env:
QT_VERSION: 5.10.1
CMAKE_GENERATOR: "Visual Studio 16 2019"
CMAKE_SYSTEM_VERSION: "10.0.18363.657"
steps:
- name: Add msbuild to PATH
uses: microsoft/setup-msbuild@v1.0.0
- name: Checkout obs
uses: actions/checkout@v2
with:
repository: obsproject/obs-studio
submodules: 'recursive'
- name: Checkout plugin
uses: actions/checkout@v2
with:
path: UI/frontend-plugins/${{ env.PLUGIN_NAME }}
- name: Add plugin to obs cmake
shell: cmd
run: echo add_subdirectory(${{ env.PLUGIN_NAME }}) >> UI/frontend-plugins/CMakeLists.txt
- name: Fetch Git Tags
run: git fetch --prune --tags --unshallow
- name: 'Install prerequisite: QT'
run: |
curl -kLO https://cdn-fastly.obsproject.com/downloads/Qt_${{ env.QT_VERSION }}.7z -f --retry 5 -C -
7z x Qt_${{ env.QT_VERSION }}.7z -o"${{ github.workspace }}/cmbuild/QT"
- name: 'Install prerequisite: Pre-built dependencies'
run: |
curl -kLO https://cdn-fastly.obsproject.com/downloads/dependencies2017.zip -f --retry 5 -C -
7z x dependencies2017.zip -o"${{ github.workspace }}/cmbuild/deps"
- name: Configure
run: |
mkdir ./build
mkdir ./build32
cd ./build32
cmake -G"${{ env.CMAKE_GENERATOR }}" -A"Win32" -DCMAKE_SYSTEM_VERSION="${{ env.CMAKE_SYSTEM_VERSION }}" -DBUILD_BROWSER=false -DBUILD_CAPTIONS=false -DCOMPILE_D3D12_HOOK=false -DDepsPath="${{ github.workspace }}/cmbuild/deps/win32" -DQTDIR="${{ github.workspace }}/cmbuild/QT/${{ env.QT_VERSION }}/msvc2017" -DCOPIED_DEPENDENCIES=FALSE -DCOPY_DEPENDENCIES=TRUE ..
- name: Build
run: msbuild /m /p:Configuration=RelWithDebInfo .\build32\obs-studio.sln
- name: Package
if: success()
run: |
$env:FILE_DATE=(Get-Date -UFormat "%F")
$env:FILE_NAME="${{ env.PLUGIN_NAME }}-${env:FILE_DATE}-${{ github.sha }}-win32.zip"
echo "::set-env name=FILE_NAME::${env:FILE_NAME}"
robocopy .\build32\rundir\RelWithDebInfo\obs-plugins\32bit\ .\build\obs-plugins\32bit ${{ env.LIB_NAME }}.* /E /XF .gitignore
7z a ${env:FILE_NAME} .\build\*
- name: Publish
if: success()
uses: actions/upload-artifact@v2-preview
with:
name: '${{ env.FILE_NAME }}'
path: '*-win32.zip'

6
CI/macos/Brewfile Normal file
View File

@@ -0,0 +1,6 @@
brew "jack"
brew "speexdsp"
brew "cmake"
brew "freetype"
brew "fdk-aac"
brew "https://gist.githubusercontent.com/DDRBoxman/9c7a2b08933166f4b61ed9a44b242609/raw/ef4de6c587c6bd7f50210eccd5bd51ff08e6de13/qt.rb"

View File

@@ -0,0 +1,760 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PROJECT</key>
<dict>
<key>PACKAGE_FILES</key>
<dict>
<key>DEFAULT_INSTALL_LOCATION</key>
<string>/</string>
<key>HIERARCHY</key>
<dict>
<key>CHILDREN</key>
<array>
<dict>
<key>CHILDREN</key>
<array>
<dict>
<key>CHILDREN</key>
<array>
<dict>
<key>CHILDREN</key>
<array>
<dict>
<key>CHILDREN</key>
<array>
<dict>
<key>CHILDREN</key>
<array>
<dict>
<key>CHILDREN</key>
<array>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>80</integer>
<key>PATH</key>
<string>../../../../../build/UI/frontend-plugins/SceneSwitcher/advanced-scene-switcher.so</string>
<key>PATH_TYPE</key>
<integer>3</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>3</integer>
<key>UID</key>
<integer>0</integer>
</dict>
</array>
<key>GID</key>
<integer>80</integer>
<key>PATH</key>
<string>bin</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>2</integer>
<key>UID</key>
<integer>0</integer>
</dict>
</array>
<key>GID</key>
<integer>80</integer>
<key>PATH</key>
<string>advanced-scene-switcher</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>2</integer>
<key>UID</key>
<integer>0</integer>
</dict>
</array>
<key>GID</key>
<integer>80</integer>
<key>PATH</key>
<string>plugins</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>2</integer>
<key>UID</key>
<integer>0</integer>
</dict>
</array>
<key>GID</key>
<integer>80</integer>
<key>PATH</key>
<string>obs-studio</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>2</integer>
<key>UID</key>
<integer>0</integer>
</dict>
</array>
<key>GID</key>
<integer>80</integer>
<key>PATH</key>
<string>Application Support</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>Automator</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>Documentation</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>Extensions</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>Filesystems</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>Frameworks</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>Input Methods</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>Internet Plug-Ins</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>LaunchAgents</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>LaunchDaemons</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>PreferencePanes</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>Preferences</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>80</integer>
<key>PATH</key>
<string>Printers</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>PrivilegedHelperTools</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>1005</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>QuickLook</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>QuickTime</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>Screen Savers</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>Scripts</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>Services</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>Widgets</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
</array>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>Library</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>Shared</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>1023</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
</array>
<key>GID</key>
<integer>80</integer>
<key>PATH</key>
<string>Users</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>80</integer>
<key>PATH</key>
<string>Applications</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>509</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
</array>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>/</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<key>PAYLOAD_TYPE</key>
<integer>0</integer>
<key>PRESERVE_EXTENDED_ATTRIBUTES</key>
<false/>
<key>SHOW_INVISIBLE</key>
<false/>
<key>SPLIT_FORKS</key>
<true/>
<key>TREAT_MISSING_FILES_AS_WARNING</key>
<false/>
<key>VERSION</key>
<integer>5</integer>
</dict>
<key>PACKAGE_SCRIPTS</key>
<dict>
<key>POSTINSTALL_PATH</key>
<dict>
<key>PATH_TYPE</key>
<integer>0</integer>
</dict>
<key>PREINSTALL_PATH</key>
<dict>
<key>PATH_TYPE</key>
<integer>0</integer>
</dict>
<key>RESOURCES</key>
<array/>
</dict>
<key>PACKAGE_SETTINGS</key>
<dict>
<key>AUTHENTICATION</key>
<integer>1</integer>
<key>CONCLUSION_ACTION</key>
<integer>0</integer>
<key>FOLLOW_SYMBOLIC_LINKS</key>
<false/>
<key>IDENTIFIER</key>
<string>com.warmuptill.SceneSwitcher</string>
<key>LOCATION</key>
<integer>0</integer>
<key>NAME</key>
<string></string>
<key>OVERWRITE_PERMISSIONS</key>
<false/>
<key>PAYLOAD_SIZE</key>
<integer>-1</integer>
<key>REFERENCE_PATH</key>
<string></string>
<key>RELOCATABLE</key>
<false/>
<key>USE_HFS+_COMPRESSION</key>
<false/>
<key>VERSION</key>
<string>0.0.2</string>
</dict>
<key>PROJECT_COMMENTS</key>
<dict>
<key>NOTES</key>
<data>
PCFET0NUWVBFIGh0bWwgUFVCTElDICItLy9XM0MvL0RURCBIVE1M
IDQuMDEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvVFIvaHRtbDQv
c3RyaWN0LmR0ZCI+CjxodG1sPgo8aGVhZD4KPG1ldGEgaHR0cC1l
cXVpdj0iQ29udGVudC1UeXBlIiBjb250ZW50PSJ0ZXh0L2h0bWw7
IGNoYXJzZXQ9VVRGLTgiPgo8bWV0YSBodHRwLWVxdWl2PSJDb250
ZW50LVN0eWxlLVR5cGUiIGNvbnRlbnQ9InRleHQvY3NzIj4KPHRp
dGxlPjwvdGl0bGU+CjxtZXRhIG5hbWU9IkdlbmVyYXRvciIgY29u
dGVudD0iQ29jb2EgSFRNTCBXcml0ZXIiPgo8bWV0YSBuYW1lPSJD
b2NvYVZlcnNpb24iIGNvbnRlbnQ9IjE0MDQuMTMiPgo8c3R5bGUg
dHlwZT0idGV4dC9jc3MiPgo8L3N0eWxlPgo8L2hlYWQ+Cjxib2R5
Pgo8L2JvZHk+CjwvaHRtbD4K
</data>
</dict>
<key>PROJECT_SETTINGS</key>
<dict>
<key>BUILD_PATH</key>
<dict>
<key>PATH</key>
<string>../..</string>
<key>PATH_TYPE</key>
<integer>1</integer>
</dict>
<key>EXCLUDED_FILES</key>
<array>
<dict>
<key>PATTERNS_ARRAY</key>
<array>
<dict>
<key>REGULAR_EXPRESSION</key>
<false/>
<key>STRING</key>
<string>.DS_Store</string>
<key>TYPE</key>
<integer>0</integer>
</dict>
</array>
<key>PROTECTED</key>
<true/>
<key>PROXY_NAME</key>
<string>Remove .DS_Store files</string>
<key>PROXY_TOOLTIP</key>
<string>Remove ".DS_Store" files created by the Finder.</string>
<key>STATE</key>
<true/>
</dict>
<dict>
<key>PATTERNS_ARRAY</key>
<array>
<dict>
<key>REGULAR_EXPRESSION</key>
<false/>
<key>STRING</key>
<string>.pbdevelopment</string>
<key>TYPE</key>
<integer>0</integer>
</dict>
</array>
<key>PROTECTED</key>
<true/>
<key>PROXY_NAME</key>
<string>Remove .pbdevelopment files</string>
<key>PROXY_TOOLTIP</key>
<string>Remove ".pbdevelopment" files created by ProjectBuilder or Xcode.</string>
<key>STATE</key>
<true/>
</dict>
<dict>
<key>PATTERNS_ARRAY</key>
<array>
<dict>
<key>REGULAR_EXPRESSION</key>
<false/>
<key>STRING</key>
<string>CVS</string>
<key>TYPE</key>
<integer>1</integer>
</dict>
<dict>
<key>REGULAR_EXPRESSION</key>
<false/>
<key>STRING</key>
<string>.cvsignore</string>
<key>TYPE</key>
<integer>0</integer>
</dict>
<dict>
<key>REGULAR_EXPRESSION</key>
<false/>
<key>STRING</key>
<string>.cvspass</string>
<key>TYPE</key>
<integer>0</integer>
</dict>
<dict>
<key>REGULAR_EXPRESSION</key>
<false/>
<key>STRING</key>
<string>.svn</string>
<key>TYPE</key>
<integer>1</integer>
</dict>
<dict>
<key>REGULAR_EXPRESSION</key>
<false/>
<key>STRING</key>
<string>.git</string>
<key>TYPE</key>
<integer>1</integer>
</dict>
<dict>
<key>REGULAR_EXPRESSION</key>
<false/>
<key>STRING</key>
<string>.gitignore</string>
<key>TYPE</key>
<integer>0</integer>
</dict>
</array>
<key>PROTECTED</key>
<true/>
<key>PROXY_NAME</key>
<string>Remove SCM metadata</string>
<key>PROXY_TOOLTIP</key>
<string>Remove helper files and folders used by the CVS, SVN or Git Source Code Management systems.</string>
<key>STATE</key>
<true/>
</dict>
<dict>
<key>PATTERNS_ARRAY</key>
<array>
<dict>
<key>REGULAR_EXPRESSION</key>
<false/>
<key>STRING</key>
<string>classes.nib</string>
<key>TYPE</key>
<integer>0</integer>
</dict>
<dict>
<key>REGULAR_EXPRESSION</key>
<false/>
<key>STRING</key>
<string>designable.db</string>
<key>TYPE</key>
<integer>0</integer>
</dict>
<dict>
<key>REGULAR_EXPRESSION</key>
<false/>
<key>STRING</key>
<string>info.nib</string>
<key>TYPE</key>
<integer>0</integer>
</dict>
</array>
<key>PROTECTED</key>
<true/>
<key>PROXY_NAME</key>
<string>Optimize nib files</string>
<key>PROXY_TOOLTIP</key>
<string>Remove "classes.nib", "info.nib" and "designable.nib" files within .nib bundles.</string>
<key>STATE</key>
<true/>
</dict>
<dict>
<key>PATTERNS_ARRAY</key>
<array>
<dict>
<key>REGULAR_EXPRESSION</key>
<false/>
<key>STRING</key>
<string>Resources Disabled</string>
<key>TYPE</key>
<integer>1</integer>
</dict>
</array>
<key>PROTECTED</key>
<true/>
<key>PROXY_NAME</key>
<string>Remove Resources Disabled folders</string>
<key>PROXY_TOOLTIP</key>
<string>Remove "Resources Disabled" folders.</string>
<key>STATE</key>
<true/>
</dict>
<dict>
<key>SEPARATOR</key>
<true/>
</dict>
</array>
<key>NAME</key>
<string>SceneSwitcher</string>
<key>PAYLOAD_ONLY</key>
<false/>
</dict>
</dict>
<key>TYPE</key>
<integer>1</integer>
<key>VERSION</key>
<integer>2</integer>
</dict>
</plist>

View File

@@ -8,9 +8,6 @@ if(BUILD_OUT_OF_TREE)
set(CMAKE_PREFIX_PATH "${QTDIR}") set(CMAKE_PREFIX_PATH "${QTDIR}")
set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_INCLUDE_CURRENT_DIR ON)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/external") list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/external")
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
include(external/FindLibObs.cmake) include(external/FindLibObs.cmake)
find_package(LibObs REQUIRED) find_package(LibObs REQUIRED)
@@ -56,6 +53,7 @@ if(BUILD_OUT_OF_TREE)
src/general.cpp src/general.cpp
src/pause-switch.cpp src/pause-switch.cpp
src/random.cpp src/random.cpp
src/time-switch.cpp
) )
set(advanced-scene-switcher_UI set(advanced-scene-switcher_UI
@@ -82,6 +80,10 @@ if(BUILD_OUT_OF_TREE)
Xss) Xss)
endif() endif()
qt5_wrap_ui(advanced-scene-switcher_UI_HEADERS
${advanced-scene-switcher_UI}
${advanced-scene-switcher_PLATFORM_UI})
add_library(advanced-scene-switcher MODULE add_library(advanced-scene-switcher MODULE
${advanced-scene-switcher_HEADERS} ${advanced-scene-switcher_HEADERS}
${advanced-scene-switcher_SOURCES} ${advanced-scene-switcher_SOURCES}
@@ -151,7 +153,7 @@ else ()
include_directories(${COCOA}) include_directories(${COCOA})
endif() endif()
if(UNIX) if(UNIX AND NOT APPLE)
find_package(X11 REQUIRED) find_package(X11 REQUIRED)
link_libraries(${X11_LIBRARIES}) link_libraries(${X11_LIBRARIES})
include_directories(${X11_INCLUDE_DIR}) include_directories(${X11_INCLUDE_DIR})
@@ -181,7 +183,9 @@ else ()
src/general.cpp src/general.cpp
src/pause-switch.cpp src/pause-switch.cpp
src/random.cpp src/random.cpp
src/time-switch.cpp
) )
set(advanced-scene-switcher_UI set(advanced-scene-switcher_UI
${advanced-scene-switcher_UI} ${advanced-scene-switcher_UI}
forms/advanced-scene-switcher.ui forms/advanced-scene-switcher.ui
@@ -190,13 +194,11 @@ else ()
if(WIN32) if(WIN32)
set(advanced-scene-switcher_PLATFORM_SOURCES set(advanced-scene-switcher_PLATFORM_SOURCES
src/win/advanced-scene-switcher-win.cpp) src/win/advanced-scene-switcher-win.cpp)
elseif(APPLE) elseif(APPLE)
set(advanced-scene-switcher_PLATFORM_SOURCES set(advanced-scene-switcher_PLATFORM_SOURCES
src/osx/advanced-scene-switcher-osx.mm) src/osx/advanced-scene-switcher-osx.mm)
set_source_files_properties(advanced-scene-switcher-osx.mm set_source_files_properties(advanced-scene-switcher-osx.mm
PROPERTIES COMPILE_FLAGS "-fobjc-arc") PROPERTIES COMPILE_FLAGS "-fobjc-arc")
set(advanced-scene-switcher_PLATFORM_LIBS set(advanced-scene-switcher_PLATFORM_LIBS
${COCOA}) ${COCOA})
else() else()
@@ -217,6 +219,7 @@ else ()
${advanced-scene-switcher_PLATFORM_SOURCES} ${advanced-scene-switcher_PLATFORM_SOURCES}
${advanced-scene-switcher_PLATFORM_HEADERS} ${advanced-scene-switcher_PLATFORM_HEADERS}
) )
target_link_libraries(advanced-scene-switcher target_link_libraries(advanced-scene-switcher
${advanced-scene-switcher_PLATFORM_LIBS} ${advanced-scene-switcher_PLATFORM_LIBS}
obs-frontend-api obs-frontend-api
@@ -224,4 +227,4 @@ else ()
libobs) libobs)
install_obs_plugin(advanced-scene-switcher data) install_obs_plugin(advanced-scene-switcher data)
endif() endif()

View File

@@ -106,4 +106,13 @@ in the source code of OBS Studio, located at [source_directory]/UI/obs-frontend-
Just keep hitting configure until all the vars are filled out. Then hit generate. Just keep hitting configure until all the vars are filled out. Then hit generate.
Open xcode (or a terminal, depending on the build type you chose), build and copy Open xcode (or a terminal, depending on the build type you chose), build and copy
the advanced-scene-switcher.so file to /Applications/OBS.app/Contents/Resources/obs-plugins/ the advanced-scene-switcher.so file to /Applications/OBS.app/Contents/PlugIns
Note that you might have to adjust the library search paths using the install_name_tool if you want the plugin to run on machines other than your build machine:
```
install_name_tool -change @rpath/libobs-frontend-api.dylib @executable_path/../Frameworks/libobs-frontend-api.dylib UI/frontend-plugins/SceneSwitcher/advanced-scene-switcher.so
install_name_tool -change @rpath/libobs.0.dylib @executable_path/../Frameworks/libobs.0.dylib UI/frontend-plugins/SceneSwitcher/advanced-scene-switcher.so
install_name_tool -change /usr/local/opt/qt5/lib/QtWidgets.framework/Versions/5/QtWidgets @executable_path/../Frameworks/QtWidgets.framework/Versions/5/QtWidgets UI/frontend-plugins/SceneSwitcher/advanced-scene-switcher.so
install_name_tool -change /usr/local/opt/qt5/lib/QtGui.framework/Versions/5/QtGui @executable_path/../Frameworks/QtGui.framework/Versions/5/QtGui UI/frontend-plugins/SceneSwitcher/advanced-scene-switcher.so
install_name_tool -change /usr/local/opt/qt5/lib/QtCore.framework/Versions/5/QtCore @executable_path/../Frameworks/QtCore.framework/Versions/5/QtCore UI/frontend-plugins/SceneSwitcher/advanced-scene-switcher.so
```

View File

@@ -7,7 +7,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>981</width> <width>981</width>
<height>457</height> <height>492</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@@ -336,6 +336,53 @@
</item> </item>
</layout> </layout>
</item> </item>
<item>
<widget class="Line" name="line_10">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_44">
<item>
<widget class="QLabel" name="label_56">
<property name="text">
<string>Use thread priority (experimental)</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="threadPriority">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_41">
<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> <item>
<widget class="Line" name="line_7"> <widget class="Line" name="line_7">
<property name="orientation"> <property name="orientation">
@@ -2416,7 +2463,7 @@
<string notr="true">ms</string> <string notr="true">ms</string>
</property> </property>
<property name="minimum"> <property name="minimum">
<number>00</number> <number>0</number>
</property> </property>
<property name="maximum"> <property name="maximum">
<number>1000000</number> <number>1000000</number>
@@ -2543,6 +2590,140 @@
</item> </item>
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="timeTab">
<attribute name="title">
<string>Time</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_10">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_42">
<item>
<widget class="QLabel" name="label_55">
<property name="text">
<string>At</string>
</property>
</widget>
</item>
<item>
<widget class="QTimeEdit" name="timeEdit">
<property name="displayFormat">
<string>HH:mm:ss</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_59">
<property name="text">
<string>switch to</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="timeScenes">
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_60">
<property name="text">
<string>using the</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="timeTransitions"/>
</item>
<item>
<widget class="QLabel" name="label_61">
<property name="text">
<string>transition</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_40">
<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="timeSwitches">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_41">
<property name="spacing">
<number>4</number>
</property>
<item>
<widget class="QPushButton" name="timeAdd">
<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="timeRemove">
<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_39">
<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>
</layout>
</widget>
</widget> </widget>
</item> </item>
</layout> </layout>

View File

@@ -57,6 +57,7 @@ SceneSwitcher::SceneSwitcher(QWidget *parent)
ui->randomScenes->addItem(name); ui->randomScenes->addItem(name);
ui->fileScenes->addItem(name); ui->fileScenes->addItem(name);
ui->mediaScenes->addItem(name); ui->mediaScenes->addItem(name);
ui->timeScenes->addItem(name);
temp++; temp++;
} }
@@ -90,6 +91,8 @@ SceneSwitcher::SceneSwitcher(QWidget *parent)
ui->sceneRoundTripScenes2->addItem(PREVIOUS_SCENE_NAME); ui->sceneRoundTripScenes2->addItem(PREVIOUS_SCENE_NAME);
ui->idleScenes->addItem(PREVIOUS_SCENE_NAME); ui->idleScenes->addItem(PREVIOUS_SCENE_NAME);
ui->mediaScenes->addItem(PREVIOUS_SCENE_NAME);
ui->timeScenes->addItem(PREVIOUS_SCENE_NAME);
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); obs_frontend_get_transitions(transitions);
@@ -107,6 +110,7 @@ SceneSwitcher::SceneSwitcher(QWidget *parent)
ui->randomTransitions->addItem(name); ui->randomTransitions->addItem(name);
ui->fileTransitions->addItem(name); ui->fileTransitions->addItem(name);
ui->mediaTransitions->addItem(name); ui->mediaTransitions->addItem(name);
ui->timeTransitions->addItem(name);
} }
obs_frontend_source_list_free(transitions); obs_frontend_source_list_free(transitions);
@@ -291,7 +295,9 @@ SceneSwitcher::SceneSwitcher(QWidget *parent)
for (auto &s : switcher->mediaSwitches) { for (auto &s : switcher->mediaSwitches) {
string sourceName = GetWeakSourceName(s.source); string sourceName = GetWeakSourceName(s.source);
string sceneName = GetWeakSourceName(s.scene); string sceneName = (s.usePreviousScene)
? PREVIOUS_SCENE_NAME
: GetWeakSourceName(s.scene);
string transitionName = GetWeakSourceName(s.transition); string transitionName = GetWeakSourceName(s.transition);
QString listText = MakeMediaSwitchName( QString listText = MakeMediaSwitchName(
sourceName.c_str(), sceneName.c_str(), sourceName.c_str(), sceneName.c_str(),
@@ -302,6 +308,19 @@ SceneSwitcher::SceneSwitcher(QWidget *parent)
item->setData(Qt::UserRole, listText); item->setData(Qt::UserRole, listText);
} }
for (auto &s : switcher->timeSwitches) {
string sceneName = (s.usePreviousScene)
? PREVIOUS_SCENE_NAME
: GetWeakSourceName(s.scene);
string transitionName = GetWeakSourceName(s.transition);
QString listText = MakeTimeSwitchName(
sceneName.c_str(), transitionName.c_str(), s.time);
QListWidgetItem *item =
new QListWidgetItem(listText, ui->timeSwitches);
item->setData(Qt::UserRole, listText);
}
ui->idleCheckBox->setChecked(switcher->idleData.idleEnable); ui->idleCheckBox->setChecked(switcher->idleData.idleEnable);
ui->idleScenes->setCurrentText( ui->idleScenes->setCurrentText(
switcher->idleData.usePreviousScene switcher->idleData.usePreviousScene
@@ -372,12 +391,19 @@ SceneSwitcher::SceneSwitcher(QWidget *parent)
case MEDIA_FUNC: case MEDIA_FUNC:
s = "Media"; s = "Media";
break; break;
case TIME_FUNC:
s = "Time";
break;
} }
QString text(s.c_str()); QString text(s.c_str());
QListWidgetItem *item = QListWidgetItem *item =
new QListWidgetItem(text, ui->priorityList); new QListWidgetItem(text, ui->priorityList);
item->setData(Qt::UserRole, text); item->setData(Qt::UserRole, text);
} }
for (std::string p : switcher->threadPrioritiesNamesOrderdByPrio) {
ui->threadPriority->addItem(p.c_str());
}
} }
/******************************************************************************** /********************************************************************************
@@ -404,6 +430,7 @@ static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *)
obs_data_array_t *randomArray = obs_data_array_create(); obs_data_array_t *randomArray = obs_data_array_create();
obs_data_array_t *fileArray = obs_data_array_create(); obs_data_array_t *fileArray = obs_data_array_create();
obs_data_array_t *mediaArray = obs_data_array_create(); obs_data_array_t *mediaArray = obs_data_array_create();
obs_data_array_t *timeArray = obs_data_array_create();
switcher->Prune(); switcher->Prune();
@@ -723,7 +750,8 @@ static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *)
obs_weak_source_get_source(s.scene); obs_weak_source_get_source(s.scene);
obs_source_t *transition = obs_source_t *transition =
obs_weak_source_get_source(s.transition); obs_weak_source_get_source(s.transition);
if (source && sceneSource && transition) { if ((s.usePreviousScene || sceneSource) && source &&
transition) {
const char *sourceName = const char *sourceName =
obs_source_get_name(source); obs_source_get_name(source);
const char *sceneName = const char *sceneName =
@@ -732,8 +760,10 @@ static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *)
obs_source_get_name(transition); obs_source_get_name(transition);
obs_data_set_string(array_obj, "source", obs_data_set_string(array_obj, "source",
sourceName); sourceName);
obs_data_set_string(array_obj, "scene", obs_data_set_string(
sceneName); array_obj, "scene",
s.usePreviousScene ? PREVIOUS_SCENE_NAME
: sceneName);
obs_data_set_string(array_obj, "transition", obs_data_set_string(array_obj, "transition",
transitionName); transitionName);
obs_data_set_int(array_obj, "state", s.state); obs_data_set_int(array_obj, "state", s.state);
@@ -749,6 +779,35 @@ static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *)
obs_data_release(array_obj); obs_data_release(array_obj);
} }
for (TimeSwitch &s : switcher->timeSwitches) {
obs_data_t *array_obj = obs_data_create();
obs_source_t *sceneSource =
obs_weak_source_get_source(s.scene);
obs_source_t *transition =
obs_weak_source_get_source(s.transition);
if ((s.usePreviousScene || sceneSource) && transition) {
const char *sceneName =
obs_source_get_name(sceneSource);
const char *transitionName =
obs_source_get_name(transition);
obs_data_set_string(
array_obj, "scene",
s.usePreviousScene ? PREVIOUS_SCENE_NAME
: sceneName);
obs_data_set_string(array_obj, "transition",
transitionName);
obs_data_set_string(
array_obj, "time",
s.time.toString().toStdString().c_str());
obs_data_array_push_back(timeArray, array_obj);
}
obs_source_release(sceneSource);
obs_source_release(transition);
obs_data_release(array_obj);
}
string nonMatchingSceneName = string nonMatchingSceneName =
GetWeakSourceName(switcher->nonMatchingScene); GetWeakSourceName(switcher->nonMatchingScene);
@@ -775,6 +834,7 @@ static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *)
obs_data_set_array(obj, "randomSwitches", randomArray); obs_data_set_array(obj, "randomSwitches", randomArray);
obs_data_set_array(obj, "fileSwitches", fileArray); obs_data_set_array(obj, "fileSwitches", fileArray);
obs_data_set_array(obj, "mediaSwitches", mediaArray); obs_data_set_array(obj, "mediaSwitches", mediaArray);
obs_data_set_array(obj, "timeSwitches", timeArray);
string autoStopSceneName = string autoStopSceneName =
GetWeakSourceName(switcher->autoStopScene); GetWeakSourceName(switcher->autoStopScene);
@@ -820,6 +880,8 @@ static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *)
switcher->functionNamesByPriority[5]); switcher->functionNamesByPriority[5]);
obs_data_set_int(obj, "priority6", obs_data_set_int(obj, "priority6",
switcher->functionNamesByPriority[6]); switcher->functionNamesByPriority[6]);
obs_data_set_int(obj, "priority7",
switcher->functionNamesByPriority[7]);
obs_data_set_obj(save_data, "advanced-scene-switcher", obj); obs_data_set_obj(save_data, "advanced-scene-switcher", obj);
@@ -836,6 +898,7 @@ static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *)
obs_data_array_release(randomArray); obs_data_array_release(randomArray);
obs_data_array_release(fileArray); obs_data_array_release(fileArray);
obs_data_array_release(mediaArray); obs_data_array_release(mediaArray);
obs_data_array_release(timeArray);
obs_data_release(obj); obs_data_release(obj);
} else { } else {
@@ -868,6 +931,8 @@ static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *)
obs_data_get_array(obj, "fileSwitches"); obs_data_get_array(obj, "fileSwitches");
obs_data_array_t *mediaArray = obs_data_array_t *mediaArray =
obs_data_get_array(obj, "mediaSwitches"); obs_data_get_array(obj, "mediaSwitches");
obs_data_array_t *timeArray =
obs_data_get_array(obj, "timeSwitches");
if (!obj) if (!obj)
obj = obs_data_create(); obj = obs_data_create();
@@ -1179,7 +1244,38 @@ static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *)
GetWeakSourceByName(scene), GetWeakSourceByName(scene),
GetWeakSourceByName(source), GetWeakSourceByName(source),
GetWeakTransitionByName(transition), state, GetWeakTransitionByName(transition), state,
restriction, time); restriction, time,
(strcmp(scene, PREVIOUS_SCENE_NAME) == 0));
obs_data_release(array_obj);
}
switcher->timeSwitches.clear();
count = obs_data_array_count(timeArray);
for (size_t i = 0; i < count; i++) {
obs_data_t *array_obj =
obs_data_array_item(timeArray, i);
const char *scene =
obs_data_get_string(array_obj, "scene");
const char *transition =
obs_data_get_string(array_obj, "transition");
QTime time = QTime::fromString(
obs_data_get_string(array_obj, "time"));
string timeSwitchStr =
MakeTimeSwitchName(scene, transition, time)
.toUtf8()
.constData();
switcher->timeSwitches.emplace_back(
GetWeakSourceByName(scene),
GetWeakTransitionByName(transition), time,
(strcmp(scene, PREVIOUS_SCENE_NAME) == 0),
timeSwitchStr);
obs_data_release(array_obj);
} }
string autoStopScene = string autoStopScene =
@@ -1223,6 +1319,7 @@ static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *)
obs_data_set_default_int(obj, "priority4", DEFAULT_PRIORITY_4); obs_data_set_default_int(obj, "priority4", DEFAULT_PRIORITY_4);
obs_data_set_default_int(obj, "priority5", DEFAULT_PRIORITY_5); obs_data_set_default_int(obj, "priority5", DEFAULT_PRIORITY_5);
obs_data_set_default_int(obj, "priority6", DEFAULT_PRIORITY_6); obs_data_set_default_int(obj, "priority6", DEFAULT_PRIORITY_6);
obs_data_set_default_int(obj, "priority7", DEFAULT_PRIORITY_7);
switcher->functionNamesByPriority[0] = switcher->functionNamesByPriority[0] =
(obs_data_get_int(obj, "priority0")); (obs_data_get_int(obj, "priority0"));
@@ -1238,6 +1335,8 @@ static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *)
(obs_data_get_int(obj, "priority5")); (obs_data_get_int(obj, "priority5"));
switcher->functionNamesByPriority[6] = switcher->functionNamesByPriority[6] =
(obs_data_get_int(obj, "priority6")); (obs_data_get_int(obj, "priority6"));
switcher->functionNamesByPriority[6] =
(obs_data_get_int(obj, "priority7"));
if (!switcher->prioFuncsValid()) { if (!switcher->prioFuncsValid()) {
switcher->functionNamesByPriority[0] = switcher->functionNamesByPriority[0] =
(DEFAULT_PRIORITY_0); (DEFAULT_PRIORITY_0);
@@ -1253,6 +1352,8 @@ static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *)
(DEFAULT_PRIORITY_5); (DEFAULT_PRIORITY_5);
switcher->functionNamesByPriority[6] = switcher->functionNamesByPriority[6] =
(DEFAULT_PRIORITY_6); (DEFAULT_PRIORITY_6);
switcher->functionNamesByPriority[7] =
(DEFAULT_PRIORITY_7);
} }
obs_data_array_release(array); obs_data_array_release(array);
@@ -1266,6 +1367,8 @@ static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *)
obs_data_array_release(ignoreIdleWindowsArray); obs_data_array_release(ignoreIdleWindowsArray);
obs_data_array_release(randomArray); obs_data_array_release(randomArray);
obs_data_array_release(fileArray); obs_data_array_release(fileArray);
obs_data_array_release(mediaArray);
obs_data_array_release(timeArray);
obs_data_release(obj); obs_data_release(obj);
@@ -1283,7 +1386,6 @@ static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *)
********************************************************************************/ ********************************************************************************/
void SwitcherData::Thread() void SwitcherData::Thread()
{ {
//to avoid scene duplication when rapidly switching scene collection //to avoid scene duplication when rapidly switching scene collection
this_thread::sleep_for(chrono::seconds(2)); this_thread::sleep_for(chrono::seconds(2));
@@ -1349,7 +1451,11 @@ void SwitcherData::Thread()
case MEDIA_FUNC: case MEDIA_FUNC:
checkMediaSwitch(match, scene, transition); checkMediaSwitch(match, scene, transition);
break; break;
case TIME_FUNC:
checkTimeSwitch(match, scene, transition);
break;
} }
if (switcher->stop) { if (switcher->stop) {
goto endLoop; goto endLoop;
} }

View File

@@ -42,6 +42,7 @@ public:
int executableFindByData(const QString &exe); int executableFindByData(const QString &exe);
int IgnoreIdleWindowsFindByData(const QString &window); int IgnoreIdleWindowsFindByData(const QString &window);
int randomFindByData(const QString &scene); int randomFindByData(const QString &scene);
int timeFindByData(const QString &timeStr);
void UpdateNonMatchingScene(const QString &name); void UpdateNonMatchingScene(const QString &name);
void UpdateAutoStopScene(const QString &name); void UpdateAutoStopScene(const QString &name);
@@ -122,6 +123,10 @@ public slots:
void on_mediaAdd_clicked(); void on_mediaAdd_clicked();
void on_mediaRemove_clicked(); void on_mediaRemove_clicked();
void on_timeSwitches_currentRowChanged(int idx);
void on_timeAdd_clicked();
void on_timeRemove_clicked();
void on_priorityUp_clicked(); void on_priorityUp_clicked();
void on_priorityDown_clicked(); void on_priorityDown_clicked();

View File

@@ -8,6 +8,7 @@
#include <mutex> #include <mutex>
#include <fstream> #include <fstream>
#include <QDateTime> #include <QDateTime>
#include <QThread>
#include "utility.hpp" #include "utility.hpp"
#define DEFAULT_INTERVAL 300 #define DEFAULT_INTERVAL 300
@@ -23,6 +24,7 @@
#define SCREEN_REGION_FUNC 4 #define SCREEN_REGION_FUNC 4
#define WINDOW_TITLE_FUNC 5 #define WINDOW_TITLE_FUNC 5
#define MEDIA_FUNC 6 #define MEDIA_FUNC 6
#define TIME_FUNC 7
#define DEFAULT_PRIORITY_0 READ_FILE_FUNC #define DEFAULT_PRIORITY_0 READ_FILE_FUNC
#define DEFAULT_PRIORITY_1 ROUND_TRIP_FUNC #define DEFAULT_PRIORITY_1 ROUND_TRIP_FUNC
@@ -31,6 +33,7 @@
#define DEFAULT_PRIORITY_4 SCREEN_REGION_FUNC #define DEFAULT_PRIORITY_4 SCREEN_REGION_FUNC
#define DEFAULT_PRIORITY_5 WINDOW_TITLE_FUNC #define DEFAULT_PRIORITY_5 WINDOW_TITLE_FUNC
#define DEFAULT_PRIORITY_6 MEDIA_FUNC #define DEFAULT_PRIORITY_6 MEDIA_FUNC
#define DEFAULT_PRIORITY_7 TIME_FUNC
using namespace std; using namespace std;
@@ -208,16 +211,39 @@ struct MediaSwitch {
uint64_t time; uint64_t time;
time_restriction restriction; time_restriction restriction;
bool matched; bool matched;
bool usePreviousScene;
inline MediaSwitch(OBSWeakSource scene_, OBSWeakSource source_, inline MediaSwitch(OBSWeakSource scene_, OBSWeakSource source_,
OBSWeakSource transition_, obs_media_state state_, OBSWeakSource transition_, obs_media_state state_,
time_restriction restriction_, uint64_t time_) time_restriction restriction_, uint64_t time_,
bool usePreviousScene_)
: scene(scene_), : scene(scene_),
source(source_), source(source_),
transition(transition_), transition(transition_),
state(state_), state(state_),
restriction(restriction_), restriction(restriction_),
time(time_) time(time_),
usePreviousScene(usePreviousScene_)
{
}
};
struct TimeSwitch {
OBSWeakSource scene;
OBSWeakSource transition;
QTime time;
bool matched;
bool usePreviousScene;
string timeSwitchStr;
inline TimeSwitch(OBSWeakSource scene_, OBSWeakSource transition_,
QTime time_, bool usePreviousScene_,
string timeSwitchStr_)
: scene(scene_),
transition(transition_),
time(time_),
usePreviousScene(usePreviousScene_),
timeSwitchStr(timeSwitchStr_)
{ {
} }
}; };
@@ -276,10 +302,24 @@ struct SwitcherData {
vector<MediaSwitch> mediaSwitches; vector<MediaSwitch> mediaSwitches;
vector<TimeSwitch> timeSwitches;
vector<int> functionNamesByPriority = vector<int>{ vector<int> functionNamesByPriority = vector<int>{
DEFAULT_PRIORITY_0, DEFAULT_PRIORITY_1, DEFAULT_PRIORITY_2, DEFAULT_PRIORITY_0, DEFAULT_PRIORITY_1, DEFAULT_PRIORITY_2,
DEFAULT_PRIORITY_3, DEFAULT_PRIORITY_4, DEFAULT_PRIORITY_5, DEFAULT_PRIORITY_3, DEFAULT_PRIORITY_4, DEFAULT_PRIORITY_5,
DEFAULT_PRIORITY_6}; DEFAULT_PRIORITY_6, DEFAULT_PRIORITY_7};
std::vector<std::string> threadPrioritiesNamesOrderdByPrio{
"Lowest", "Low", "Normal", "High", "Highest", "Time critical",
};
std::map<std::string, int> threadPriorities = {
{"Lowest", QThread::LowestPriority},
{"Low", QThread::LowPriority},
{"Normal", QThread::NormalPriority},
{"High", QThread::HighPriority},
{"Highest", QThread::HighestPriority},
{"Time critical", QThread::TimeCriticalPriority},
};
void Thread(); void Thread();
void Start(); void Start();
@@ -310,6 +350,8 @@ struct SwitcherData {
OBSWeakSource &transition, int &delay); OBSWeakSource &transition, int &delay);
void checkMediaSwitch(bool &match, OBSWeakSource &scene, void checkMediaSwitch(bool &match, OBSWeakSource &scene,
OBSWeakSource &transition); OBSWeakSource &transition);
void checkTimeSwitch(bool &match, OBSWeakSource &scene,
OBSWeakSource &transition);
void Prune() void Prune()
{ {
@@ -396,6 +438,13 @@ struct SwitcherData {
fileSwitches.erase(fileSwitches.begin() + i--); fileSwitches.erase(fileSwitches.begin() + i--);
} }
for (size_t i = 0; i < timeSwitches.size(); i++) {
TimeSwitch &s = timeSwitches[i];
if (!WeakSourceValid(s.scene) ||
!WeakSourceValid(s.transition))
timeSwitches.erase(timeSwitches.begin() + i--);
}
if (!idleData.usePreviousScene && if (!idleData.usePreviousScene &&
!WeakSourceValid(idleData.scene) || !WeakSourceValid(idleData.scene) ||
!WeakSourceValid(idleData.transition)) { !WeakSourceValid(idleData.transition)) {

View File

@@ -5,9 +5,9 @@
#include "switcher-data-structs.hpp" #include "switcher-data-structs.hpp"
using namespace std; using namespace std;
static inline bool WeakSourceValid(obs_weak_source_t* ws) static inline bool WeakSourceValid(obs_weak_source_t *ws)
{ {
obs_source_t* source = obs_weak_source_get_source(ws); obs_source_t *source = obs_weak_source_get_source(ws);
if (source) if (source)
obs_source_release(source); obs_source_release(source);
return !!source; return !!source;
@@ -107,7 +107,7 @@ static inline QString MakeFileSwitchName(const QString &scene,
return switchName; return switchName;
} }
typedef enum { typedef enum {
TIME_RESTRICTION_NONE, TIME_RESTRICTION_NONE,
TIME_RESTRICTION_SHORTER, TIME_RESTRICTION_SHORTER,
TIME_RESTRICTION_LONGER, TIME_RESTRICTION_LONGER,
@@ -159,6 +159,15 @@ MakeMediaSwitchName(const QString &source, const QString &scene,
return switchName; return switchName;
} }
static inline QString MakeTimeSwitchName(const QString &scene,
const QString &transition, QTime &time)
{
QString switchName = QStringLiteral("At ") + time.toString() +
QStringLiteral(" switch to ") + scene +
QStringLiteral(" using ") + transition;
return switchName;
}
static inline string GetWeakSourceName(obs_weak_source_t *weak_source) static inline string GetWeakSourceName(obs_weak_source_t *weak_source)
{ {
string name; string name;

View File

@@ -30,8 +30,9 @@ void SceneSwitcher::on_mediaAdd_clicked()
item->setData(Qt::UserRole, v); item->setData(Qt::UserRole, v);
lock_guard<mutex> lock(switcher->m); lock_guard<mutex> lock(switcher->m);
switcher->mediaSwitches.emplace_back(scene, source, transition, state, switcher->mediaSwitches.emplace_back(
restriction, time); scene, source, transition, state, restriction, time,
(sceneName == QString(PREVIOUS_SCENE_NAME)));
} }
void SceneSwitcher::on_mediaRemove_clicked() void SceneSwitcher::on_mediaRemove_clicked()
@@ -79,7 +80,9 @@ void SwitcherData::checkMediaSwitch(bool &match, OBSWeakSource &scene,
duration - time > mediaSwitch.time)); duration - time > mediaSwitch.time));
if (matched && !mediaSwitch.matched) { if (matched && !mediaSwitch.matched) {
match = true; match = true;
scene = mediaSwitch.scene; scene = (mediaSwitch.usePreviousScene)
? previousScene
: mediaSwitch.scene;
transition = mediaSwitch.transition; transition = mediaSwitch.transition;
} }
mediaSwitch.matched = matched; mediaSwitch.matched = matched;

View File

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

147
src/time-switch.cpp Normal file
View File

@@ -0,0 +1,147 @@
#include "headers/advanced-scene-switcher.hpp"
void SceneSwitcher::on_timeSwitches_currentRowChanged(int idx)
{
if (loading)
return;
if (idx == -1)
return;
QListWidgetItem *item = ui->timeSwitches->item(idx);
QString timeScenestr = item->data(Qt::UserRole).toString();
lock_guard<mutex> lock(switcher->m);
for (auto &s : switcher->timeSwitches) {
if (timeScenestr.compare(s.timeSwitchStr.c_str()) == 0) {
QString sceneName = GetWeakSourceName(s.scene).c_str();
QString transitionName =
GetWeakSourceName(s.transition).c_str();
ui->timeScenes->setCurrentText(sceneName);
ui->timeEdit->setTime(s.time);
ui->timeTransitions->setCurrentText(transitionName);
break;
}
}
}
int SceneSwitcher::timeFindByData(const QString &timeStr)
{
QRegExp rx("At " + timeStr + " switch to .*");
int count = ui->timeSwitches->count();
for (int i = 0; i < count; i++) {
QListWidgetItem *item = ui->timeSwitches->item(i);
QString str = item->data(Qt::UserRole).toString();
if (rx.exactMatch(str))
return i;
}
return -1;
}
void SceneSwitcher::on_timeAdd_clicked()
{
QString sceneName = ui->timeScenes->currentText();
QString transitionName = ui->timeTransitions->currentText();
QTime time = ui->timeEdit->time();
if (sceneName.isEmpty())
return;
OBSWeakSource source = GetWeakSourceByQString(sceneName);
OBSWeakSource transition = GetWeakTransitionByQString(transitionName);
QString text = MakeTimeSwitchName(sceneName, transitionName, time);
QVariant v = QVariant::fromValue(text);
int idx = timeFindByData(time.toString());
if (idx == -1) {
lock_guard<mutex> lock(switcher->m);
switcher->timeSwitches.emplace_back(
source, transition, time,
(sceneName == QString(PREVIOUS_SCENE_NAME)),
text.toUtf8().constData());
QListWidgetItem *item =
new QListWidgetItem(text, ui->timeSwitches);
item->setData(Qt::UserRole, v);
} else {
QListWidgetItem *item = ui->timeSwitches->item(idx);
item->setText(text);
{
lock_guard<mutex> lock(switcher->m);
for (auto &s : switcher->timeSwitches) {
if (s.time == time) {
s.scene = source;
s.transition = transition;
s.usePreviousScene =
(sceneName ==
QString(PREVIOUS_SCENE_NAME));
s.timeSwitchStr =
text.toUtf8().constData();
;
break;
}
}
}
ui->timeSwitches->sortItems();
}
}
void SceneSwitcher::on_timeRemove_clicked()
{
QListWidgetItem *item = ui->timeSwitches->currentItem();
if (!item)
return;
string text = item->data(Qt::UserRole).toString().toUtf8().constData();
{
lock_guard<mutex> lock(switcher->m);
auto &switches = switcher->timeSwitches;
for (auto it = switches.begin(); it != switches.end(); ++it) {
auto &s = *it;
if (s.timeSwitchStr == text) {
switches.erase(it);
break;
}
}
}
delete item;
}
void SwitcherData::checkTimeSwitch(bool &match, OBSWeakSource &scene,
OBSWeakSource &transition)
{
if (timeSwitches.size() == 0)
return;
QTime now = QTime::currentTime();
for (TimeSwitch &s : timeSwitches) {
QTime validSwitchTimeWindow = s.time.addMSecs(interval);
match = s.time <= now && now <= validSwitchTimeWindow;
if (!match &&
validSwitchTimeWindow.msecsSinceStartOfDay() < interval) {
// check for overflow
match = now >= s.time || now <= validSwitchTimeWindow;
}
if (match) {
scene = (s.usePreviousScene) ? previousScene : s.scene;
transition = s.transition;
match = true;
break;
}
}
}