mirror of
https://github.com/Palakis/obs-websocket.git
synced 2024-08-30 18:12:16 +00:00
general: convert indents to tabs
This commit is contained in:
parent
f2792c0b40
commit
85a52ab01f
9
.editorconfig
Normal file
9
.editorconfig
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
[*]
|
||||||
|
insert_final_newline = true
|
||||||
|
|
||||||
|
[*.{c,cpp,h,hpp}]
|
||||||
|
indent_style = tab
|
||||||
|
|
||||||
|
[*.{yml,yaml}]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
@ -5,10 +5,10 @@ set -ex
|
|||||||
|
|
||||||
mkdir -p build && cd build
|
mkdir -p build && cd build
|
||||||
cmake .. \
|
cmake .. \
|
||||||
-DQTDIR=/usr/local/opt/qt \
|
-DQTDIR=/usr/local/opt/qt \
|
||||||
-DLIBOBS_INCLUDE_DIR=../../obs-studio/libobs \
|
-DLIBOBS_INCLUDE_DIR=../../obs-studio/libobs \
|
||||||
-DLIBOBS_LIB=../../obs-studio/libobs \
|
-DLIBOBS_LIB=../../obs-studio/libobs \
|
||||||
-DOBS_FRONTEND_LIB="$(pwd)/../../obs-studio/build/UI/obs-frontend-api/libobs-frontend-api.dylib" \
|
-DOBS_FRONTEND_LIB="$(pwd)/../../obs-studio/build/UI/obs-frontend-api/libobs-frontend-api.dylib" \
|
||||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
|
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
|
||||||
-DCMAKE_INSTALL_PREFIX=/usr \
|
-DCMAKE_INSTALL_PREFIX=/usr \
|
||||||
&& make -j4
|
&& make -j4
|
||||||
|
@ -11,13 +11,13 @@ npm run build
|
|||||||
echo "-- Documentation successfully generated."
|
echo "-- Documentation successfully generated."
|
||||||
|
|
||||||
if git diff --quiet; then
|
if git diff --quiet; then
|
||||||
echo "-- No documentation changes to commit."
|
echo "-- No documentation changes to commit."
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$TRAVIS_PULL_REQUEST" != "false" -o "$TRAVIS_BRANCH" != "4.3-maintenance" ]; then
|
if [ "$TRAVIS_PULL_REQUEST" != "false" -o "$TRAVIS_BRANCH" != "4.3-maintenance" ]; then
|
||||||
echo "-- Skipping documentation deployment because this is either a pull request or a non-master branch."
|
echo "-- Skipping documentation deployment because this is either a pull request or a non-master branch."
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
REMOTE_URL="$(git config remote.origin.url)"
|
REMOTE_URL="$(git config remote.origin.url)"
|
||||||
|
@ -9,6 +9,6 @@ OBSLatestTag=$(git describe --tags --abbrev=0)
|
|||||||
git checkout $OBSLatestTag
|
git checkout $OBSLatestTag
|
||||||
mkdir build && cd build
|
mkdir build && cd build
|
||||||
cmake .. \
|
cmake .. \
|
||||||
-DDISABLE_PLUGINS=true \
|
-DDISABLE_PLUGINS=true \
|
||||||
-DCMAKE_PREFIX_PATH=/usr/local/opt/qt/lib/cmake \
|
-DCMAKE_PREFIX_PATH=/usr/local/opt/qt/lib/cmake \
|
||||||
&& make -j4
|
&& make -j4
|
||||||
|
@ -19,63 +19,63 @@ set "BuildOBS="
|
|||||||
|
|
||||||
REM Check the last tag successfully built by CI.
|
REM Check the last tag successfully built by CI.
|
||||||
if exist C:\projects\obs-studio-last-tag-built.txt (
|
if exist C:\projects\obs-studio-last-tag-built.txt (
|
||||||
set /p OBSLastTagBuilt=<C:\projects\obs-studio-last-tag-built.txt
|
set /p OBSLastTagBuilt=<C:\projects\obs-studio-last-tag-built.txt
|
||||||
) else (
|
) else (
|
||||||
set OBSLastTagBuilt=0
|
set OBSLastTagBuilt=0
|
||||||
)
|
)
|
||||||
|
|
||||||
REM If obs-studio directory exists, run git pull and get the latest tag number.
|
REM If obs-studio directory exists, run git pull and get the latest tag number.
|
||||||
if exist C:\projects\obs-studio\ (
|
if exist C:\projects\obs-studio\ (
|
||||||
echo obs-studio directory exists
|
echo obs-studio directory exists
|
||||||
echo Updating tag info
|
echo Updating tag info
|
||||||
cd C:\projects\obs-studio\
|
cd C:\projects\obs-studio\
|
||||||
git describe --tags --abbrev=0 > C:\projects\latest-obs-studio-tag-pre-pull.txt
|
git describe --tags --abbrev=0 > C:\projects\latest-obs-studio-tag-pre-pull.txt
|
||||||
set /p OBSLatestTagPrePull=<C:\projects\latest-obs-studio-tag-pre-pull.txt
|
set /p OBSLatestTagPrePull=<C:\projects\latest-obs-studio-tag-pre-pull.txt
|
||||||
git checkout master
|
git checkout master
|
||||||
git pull
|
git pull
|
||||||
git describe --tags --abbrev=0 > C:\projects\latest-obs-studio-tag-post-pull.txt
|
git describe --tags --abbrev=0 > C:\projects\latest-obs-studio-tag-post-pull.txt
|
||||||
set /p OBSLatestTagPostPull=<C:\projects\latest-obs-studio-tag-post-pull.txt
|
set /p OBSLatestTagPostPull=<C:\projects\latest-obs-studio-tag-post-pull.txt
|
||||||
set /p OBSLatestTag=<C:\projects\latest-obs-studio-tag-post-pull.txt
|
set /p OBSLatestTag=<C:\projects\latest-obs-studio-tag-post-pull.txt
|
||||||
echo %OBSLatestTagPostPull%> C:\projects\latest-obs-studio-tag.txt
|
echo %OBSLatestTagPostPull%> C:\projects\latest-obs-studio-tag.txt
|
||||||
)
|
)
|
||||||
|
|
||||||
REM Check the obs-studio tags for mismatches.
|
REM Check the obs-studio tags for mismatches.
|
||||||
REM If a new tag was pulled, set the build flag.
|
REM If a new tag was pulled, set the build flag.
|
||||||
if not %OBSLatestTagPrePull%==%OBSLatestTagPostPull% (
|
if not %OBSLatestTagPrePull%==%OBSLatestTagPostPull% (
|
||||||
echo Latest tag pre-pull: %OBSLatestTagPrePull%
|
echo Latest tag pre-pull: %OBSLatestTagPrePull%
|
||||||
echo Latest tag post-pull: %OBSLatestTagPostPull%
|
echo Latest tag post-pull: %OBSLatestTagPostPull%
|
||||||
echo Tags do not match. Need to rebuild OBS.
|
echo Tags do not match. Need to rebuild OBS.
|
||||||
set BuildOBS=true
|
set BuildOBS=true
|
||||||
)
|
)
|
||||||
|
|
||||||
REM If the latest git tag doesn't match the last built tag, set the build flag.
|
REM If the latest git tag doesn't match the last built tag, set the build flag.
|
||||||
if not %OBSLatestTagPostPull%==%OBSLastTagBuilt% (
|
if not %OBSLatestTagPostPull%==%OBSLastTagBuilt% (
|
||||||
echo Last built OBS tag: %OBSLastTagBuilt%
|
echo Last built OBS tag: %OBSLastTagBuilt%
|
||||||
echo Latest tag post-pull: %OBSLatestTagPostPull%
|
echo Latest tag post-pull: %OBSLatestTagPostPull%
|
||||||
echo Tags do not match. Need to rebuild OBS.
|
echo Tags do not match. Need to rebuild OBS.
|
||||||
set BuildOBS=true
|
set BuildOBS=true
|
||||||
)
|
)
|
||||||
|
|
||||||
REM If obs-studio directory does not exist, clone the git repo, get the latest
|
REM If obs-studio directory does not exist, clone the git repo, get the latest
|
||||||
REM tag number, and set the build flag.
|
REM tag number, and set the build flag.
|
||||||
if not exist C:\projects\obs-studio (
|
if not exist C:\projects\obs-studio (
|
||||||
echo obs-studio directory does not exist
|
echo obs-studio directory does not exist
|
||||||
git clone https://github.com/obsproject/obs-studio
|
git clone https://github.com/obsproject/obs-studio
|
||||||
cd C:\projects\obs-studio\
|
cd C:\projects\obs-studio\
|
||||||
git describe --tags --abbrev=0 > C:\projects\obs-studio-latest-tag.txt
|
git describe --tags --abbrev=0 > C:\projects\obs-studio-latest-tag.txt
|
||||||
set /p OBSLatestTag=<C:\projects\obs-studio-latest-tag.txt
|
set /p OBSLatestTag=<C:\projects\obs-studio-latest-tag.txt
|
||||||
set BuildOBS=true
|
set BuildOBS=true
|
||||||
)
|
)
|
||||||
|
|
||||||
REM If the needed obs-studio libs for this build_config do not exist,
|
REM If the needed obs-studio libs for this build_config do not exist,
|
||||||
REM set the build flag.
|
REM set the build flag.
|
||||||
if not exist C:\projects\obs-studio\build32\libobs\%build_config%\obs.lib (
|
if not exist C:\projects\obs-studio\build32\libobs\%build_config%\obs.lib (
|
||||||
echo obs-studio\build32\libobs\%build_config%\obs.lib does not exist
|
echo obs-studio\build32\libobs\%build_config%\obs.lib does not exist
|
||||||
set BuildOBS=true
|
set BuildOBS=true
|
||||||
)
|
)
|
||||||
if not exist C:\projects\obs-studio\build32\UI\obs-frontend-api\%build_config%\obs-frontend-api.lib (
|
if not exist C:\projects\obs-studio\build32\UI\obs-frontend-api\%build_config%\obs-frontend-api.lib (
|
||||||
echo obs-studio\build32\UI\obs-frontend-api\%build_config%\obs-frontend-api.lib does not exist
|
echo obs-studio\build32\UI\obs-frontend-api\%build_config%\obs-frontend-api.lib does not exist
|
||||||
set BuildOBS=true
|
set BuildOBS=true
|
||||||
)
|
)
|
||||||
|
|
||||||
REM Some debug info
|
REM Some debug info
|
||||||
@ -86,44 +86,44 @@ echo Latest tag: %OBSLatestTag%
|
|||||||
echo Last built OBS tag: %OBSLastTagBuilt%
|
echo Last built OBS tag: %OBSLastTagBuilt%
|
||||||
|
|
||||||
if defined BuildOBS (
|
if defined BuildOBS (
|
||||||
echo BuildOBS: true
|
echo BuildOBS: true
|
||||||
) else (
|
) else (
|
||||||
echo BuildOBS: false
|
echo BuildOBS: false
|
||||||
)
|
)
|
||||||
echo:
|
echo:
|
||||||
|
|
||||||
REM If the build flag is set, build obs-studio.
|
REM If the build flag is set, build obs-studio.
|
||||||
if defined BuildOBS (
|
if defined BuildOBS (
|
||||||
echo Building obs-studio...
|
echo Building obs-studio...
|
||||||
echo git checkout %OBSLatestTag%
|
echo git checkout %OBSLatestTag%
|
||||||
git checkout %OBSLatestTag%
|
git checkout %OBSLatestTag%
|
||||||
echo:
|
echo:
|
||||||
echo Removing previous build dirs...
|
echo Removing previous build dirs...
|
||||||
if exist build rmdir /s /q C:\projects\obs-studio\build
|
if exist build rmdir /s /q C:\projects\obs-studio\build
|
||||||
if exist build32 rmdir /s /q C:\projects\obs-studio\build32
|
if exist build32 rmdir /s /q C:\projects\obs-studio\build32
|
||||||
if exist build64 rmdir /s /q C:\projects\obs-studio\build64
|
if exist build64 rmdir /s /q C:\projects\obs-studio\build64
|
||||||
echo Making new build dirs...
|
echo Making new build dirs...
|
||||||
mkdir build
|
mkdir build
|
||||||
mkdir build32
|
mkdir build32
|
||||||
mkdir build64
|
mkdir build64
|
||||||
echo Running cmake for obs-studio %OBSLatestTag% 32-bit...
|
echo Running cmake for obs-studio %OBSLatestTag% 32-bit...
|
||||||
cd ./build32
|
cd ./build32
|
||||||
cmake -G "Visual Studio 15 2017" -DDISABLE_PLUGINS=true -DCOPIED_DEPENDENCIES=false -DCOPY_DEPENDENCIES=true ..
|
cmake -G "Visual Studio 15 2017" -DDISABLE_PLUGINS=true -DCOPIED_DEPENDENCIES=false -DCOPY_DEPENDENCIES=true ..
|
||||||
echo:
|
echo:
|
||||||
echo:
|
echo:
|
||||||
echo Running cmake for obs-studio %OBSLatestTag% 64-bit...
|
echo Running cmake for obs-studio %OBSLatestTag% 64-bit...
|
||||||
cd ../build64
|
cd ../build64
|
||||||
cmake -G "Visual Studio 15 2017 Win64" -DDISABLE_PLUGINS=true -DCOPIED_DEPENDENCIES=false -DCOPY_DEPENDENCIES=true ..
|
cmake -G "Visual Studio 15 2017 Win64" -DDISABLE_PLUGINS=true -DCOPIED_DEPENDENCIES=false -DCOPY_DEPENDENCIES=true ..
|
||||||
echo:
|
echo:
|
||||||
echo:
|
echo:
|
||||||
echo Building obs-studio %OBSLatestTag% 32-bit ^(Build Config: %build_config%^)...
|
echo Building obs-studio %OBSLatestTag% 32-bit ^(Build Config: %build_config%^)...
|
||||||
call msbuild /m /p:Configuration=%build_config% C:\projects\obs-studio\build32\obs-studio.sln /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
|
call msbuild /m /p:Configuration=%build_config% C:\projects\obs-studio\build32\obs-studio.sln /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
|
||||||
echo Building obs-studio %OBSLatestTag% 64-bit ^(Build Config: %build_config%^)...
|
echo Building obs-studio %OBSLatestTag% 64-bit ^(Build Config: %build_config%^)...
|
||||||
call msbuild /m /p:Configuration=%build_config% C:\projects\obs-studio\build64\obs-studio.sln /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
|
call msbuild /m /p:Configuration=%build_config% C:\projects\obs-studio\build64\obs-studio.sln /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
|
||||||
cd ..
|
cd ..
|
||||||
git describe --tags --abbrev=0 > C:\projects\obs-studio-last-tag-built.txt
|
git describe --tags --abbrev=0 > C:\projects\obs-studio-last-tag-built.txt
|
||||||
set /p OBSLastTagBuilt=<C:\projects\obs-studio-last-tag-built.txt
|
set /p OBSLastTagBuilt=<C:\projects\obs-studio-last-tag-built.txt
|
||||||
) else (
|
) else (
|
||||||
echo Last OBS tag built is: %OBSLastTagBuilt%
|
echo Last OBS tag built is: %OBSLastTagBuilt%
|
||||||
echo No need to rebuild OBS.
|
echo No need to rebuild OBS.
|
||||||
)
|
)
|
||||||
|
294
CI/macos/qt.rb
294
CI/macos/qt.rb
@ -1,175 +1,175 @@
|
|||||||
# Patches for Qt must be at the very least submitted to Qt's Gerrit codereview
|
# Patches for Qt must be at the very least submitted to Qt's Gerrit codereview
|
||||||
# rather than their bug-report Jira. The latter is rarely reviewed by Qt.
|
# rather than their bug-report Jira. The latter is rarely reviewed by Qt.
|
||||||
class Qt < Formula
|
class Qt < Formula
|
||||||
desc "Cross-platform application and UI framework"
|
desc "Cross-platform application and UI framework"
|
||||||
homepage "https://www.qt.io/"
|
homepage "https://www.qt.io/"
|
||||||
url "https://download.qt.io/official_releases/qt/5.10/5.10.0/single/qt-everywhere-src-5.10.0.tar.xz"
|
url "https://download.qt.io/official_releases/qt/5.10/5.10.0/single/qt-everywhere-src-5.10.0.tar.xz"
|
||||||
mirror "https://www.mirrorservice.org/sites/download.qt-project.org/official_releases/qt/5.10/5.10.0/single/qt-everywhere-opensource-src-5.10.0.tar.xz"
|
mirror "https://www.mirrorservice.org/sites/download.qt-project.org/official_releases/qt/5.10/5.10.0/single/qt-everywhere-opensource-src-5.10.0.tar.xz"
|
||||||
sha256 "936d4cf5d577298f4f9fdb220e85b008ae321554a5fcd38072dc327a7296230e"
|
sha256 "936d4cf5d577298f4f9fdb220e85b008ae321554a5fcd38072dc327a7296230e"
|
||||||
head "https://code.qt.io/qt/qt5.git", :branch => "5.10", :shallow => false
|
head "https://code.qt.io/qt/qt5.git", :branch => "5.10", :shallow => false
|
||||||
|
|
||||||
bottle do
|
bottle do
|
||||||
sha256 "332ab2f3eb7c13510f460c13d28a562db03297149a3615feb9e3d467fafde56c" => :high_sierra
|
sha256 "332ab2f3eb7c13510f460c13d28a562db03297149a3615feb9e3d467fafde56c" => :high_sierra
|
||||||
sha256 "c93cf6ead1774cfa7a369c92c7d6a69154bc0dd5b48a0e7ddf3a78202c4a3dc5" => :sierra
|
sha256 "c93cf6ead1774cfa7a369c92c7d6a69154bc0dd5b48a0e7ddf3a78202c4a3dc5" => :sierra
|
||||||
sha256 "44425e23d8b9c2b8b2f50d850ca94dcd411cd89e20e057c8d6505c9056d06328" => :el_capitan
|
sha256 "44425e23d8b9c2b8b2f50d850ca94dcd411cd89e20e057c8d6505c9056d06328" => :el_capitan
|
||||||
end
|
end
|
||||||
|
|
||||||
keg_only "Qt 5 has CMake issues when linked"
|
keg_only "Qt 5 has CMake issues when linked"
|
||||||
|
|
||||||
option "with-docs", "Build documentation"
|
option "with-docs", "Build documentation"
|
||||||
option "with-examples", "Build examples"
|
option "with-examples", "Build examples"
|
||||||
|
|
||||||
deprecated_option "with-mysql" => "with-mysql-client"
|
deprecated_option "with-mysql" => "with-mysql-client"
|
||||||
|
|
||||||
# OS X 10.7 Lion is still supported in Qt 5.5, but is no longer a reference
|
# OS X 10.7 Lion is still supported in Qt 5.5, but is no longer a reference
|
||||||
# configuration and thus untested in practice. Builds on OS X 10.7 have been
|
# configuration and thus untested in practice. Builds on OS X 10.7 have been
|
||||||
# reported to fail: <https://github.com/Homebrew/homebrew/issues/45284>.
|
# reported to fail: <https://github.com/Homebrew/homebrew/issues/45284>.
|
||||||
depends_on :macos => :mountain_lion
|
depends_on :macos => :mountain_lion
|
||||||
|
|
||||||
depends_on "pkg-config" => :build
|
depends_on "pkg-config" => :build
|
||||||
depends_on :xcode => :build
|
depends_on :xcode => :build
|
||||||
depends_on "mysql-client" => :optional
|
depends_on "mysql-client" => :optional
|
||||||
depends_on "postgresql" => :optional
|
depends_on "postgresql" => :optional
|
||||||
|
|
||||||
# Restore `.pc` files for framework-based build of Qt 5 on OS X. This
|
# Restore `.pc` files for framework-based build of Qt 5 on OS X. This
|
||||||
# partially reverts <https://codereview.qt-project.org/#/c/140954/> merged
|
# partially reverts <https://codereview.qt-project.org/#/c/140954/> merged
|
||||||
# between the 5.5.1 and 5.6.0 releases. (Remove this as soon as feasible!)
|
# between the 5.5.1 and 5.6.0 releases. (Remove this as soon as feasible!)
|
||||||
#
|
#
|
||||||
# Core formulae known to fail without this patch (as of 2016-10-15):
|
# Core formulae known to fail without this patch (as of 2016-10-15):
|
||||||
# * gnuplot (with `--with-qt` option)
|
# * gnuplot (with `--with-qt` option)
|
||||||
# * mkvtoolnix (with `--with-qt` option, silent build failure)
|
# * mkvtoolnix (with `--with-qt` option, silent build failure)
|
||||||
# * poppler (with `--with-qt` option)
|
# * poppler (with `--with-qt` option)
|
||||||
patch do
|
patch do
|
||||||
url "https://raw.githubusercontent.com/Homebrew/formula-patches/e8fe6567/qt5/restore-pc-files.patch"
|
url "https://raw.githubusercontent.com/Homebrew/formula-patches/e8fe6567/qt5/restore-pc-files.patch"
|
||||||
sha256 "48ff18be2f4050de7288bddbae7f47e949512ac4bcd126c2f504be2ac701158b"
|
sha256 "48ff18be2f4050de7288bddbae7f47e949512ac4bcd126c2f504be2ac701158b"
|
||||||
end
|
end
|
||||||
|
|
||||||
# Fix compile error on macOS 10.13 around QFixed:
|
# Fix compile error on macOS 10.13 around QFixed:
|
||||||
# https://github.com/Homebrew/homebrew-core/issues/27095
|
# https://github.com/Homebrew/homebrew-core/issues/27095
|
||||||
# https://bugreports.qt.io/browse/QTBUG-67545
|
# https://bugreports.qt.io/browse/QTBUG-67545
|
||||||
patch do
|
patch do
|
||||||
url "https://raw.githubusercontent.com/z00m1n/formula-patches/0de0e229/qt/QTBUG-67545.patch"
|
url "https://raw.githubusercontent.com/z00m1n/formula-patches/0de0e229/qt/QTBUG-67545.patch"
|
||||||
sha256 "4a115097c7582c7dce4207f5500d13feb8c990eb8a05a43f41953985976ebe6c"
|
sha256 "4a115097c7582c7dce4207f5500d13feb8c990eb8a05a43f41953985976ebe6c"
|
||||||
end
|
end
|
||||||
|
|
||||||
# Fix compile error on macOS 10.13 caused by qtlocation dependency
|
# Fix compile error on macOS 10.13 caused by qtlocation dependency
|
||||||
# mapbox-gl-native using Boost 1.62.0 does not build with C++ 17:
|
# mapbox-gl-native using Boost 1.62.0 does not build with C++ 17:
|
||||||
# https://github.com/Homebrew/homebrew-core/issues/27095
|
# https://github.com/Homebrew/homebrew-core/issues/27095
|
||||||
# https://bugreports.qt.io/browse/QTBUG-67810
|
# https://bugreports.qt.io/browse/QTBUG-67810
|
||||||
patch do
|
patch do
|
||||||
url "https://raw.githubusercontent.com/z00m1n/formula-patches/a1a1f0dd/qt/QTBUG-67810.patch"
|
url "https://raw.githubusercontent.com/z00m1n/formula-patches/a1a1f0dd/qt/QTBUG-67810.patch"
|
||||||
sha256 "8ee0bf71df1043f08ebae3aa35036be29c4d9ebff8a27e3b0411a6bd635e9382"
|
sha256 "8ee0bf71df1043f08ebae3aa35036be29c4d9ebff8a27e3b0411a6bd635e9382"
|
||||||
end
|
end
|
||||||
|
|
||||||
# Remove for > 5.10.0
|
# Remove for > 5.10.0
|
||||||
# Fix "error: 'loadFileURL:allowingReadAccessToURL:' is only available on
|
# Fix "error: 'loadFileURL:allowingReadAccessToURL:' is only available on
|
||||||
# macOS 10.11 or newer [-Werror,-Wunguarded-availability]"
|
# macOS 10.11 or newer [-Werror,-Wunguarded-availability]"
|
||||||
# Reported 8 Dec 2017 https://bugreports.qt.io/browse/QTBUG-65075
|
# Reported 8 Dec 2017 https://bugreports.qt.io/browse/QTBUG-65075
|
||||||
# Equivalent to upstream fix from 8 Dec 2017 https://codereview.qt-project.org/#/c/213993/
|
# Equivalent to upstream fix from 8 Dec 2017 https://codereview.qt-project.org/#/c/213993/
|
||||||
if MacOS::Xcode.version >= "9.0"
|
if MacOS::Xcode.version >= "9.0"
|
||||||
patch do
|
patch do
|
||||||
url "https://raw.githubusercontent.com/Homebrew/formula-patches/9c97726e2b153099049326ade23fe24b52b778fe/qt/QTBUG-65075.diff"
|
url "https://raw.githubusercontent.com/Homebrew/formula-patches/9c97726e2b153099049326ade23fe24b52b778fe/qt/QTBUG-65075.diff"
|
||||||
sha256 "a51595868c6173ab53463107e0ee3355576002c32ab80897587c3607589cfd22"
|
sha256 "a51595868c6173ab53463107e0ee3355576002c32ab80897587c3607589cfd22"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def install
|
def install
|
||||||
args = %W[
|
args = %W[
|
||||||
-verbose
|
-verbose
|
||||||
-prefix #{prefix}
|
-prefix #{prefix}
|
||||||
-release
|
-release
|
||||||
-opensource -confirm-license
|
-opensource -confirm-license
|
||||||
-system-zlib
|
-system-zlib
|
||||||
-qt-libpng
|
-qt-libpng
|
||||||
-qt-libjpeg
|
-qt-libjpeg
|
||||||
-qt-freetype
|
-qt-freetype
|
||||||
-qt-pcre
|
-qt-pcre
|
||||||
-nomake tests
|
-nomake tests
|
||||||
-no-rpath
|
-no-rpath
|
||||||
-pkg-config
|
-pkg-config
|
||||||
-dbus-runtime
|
-dbus-runtime
|
||||||
-no-assimp
|
-no-assimp
|
||||||
]
|
]
|
||||||
|
|
||||||
args << "-nomake" << "examples" if build.without? "examples"
|
args << "-nomake" << "examples" if build.without? "examples"
|
||||||
|
|
||||||
if build.with? "mysql-client"
|
if build.with? "mysql-client"
|
||||||
args << "-plugin-sql-mysql"
|
args << "-plugin-sql-mysql"
|
||||||
(buildpath/"brew_shim/mysql_config").write <<~EOS
|
(buildpath/"brew_shim/mysql_config").write <<~EOS
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
if [ x"$1" = x"--libs" ]; then
|
if [ x"$1" = x"--libs" ]; then
|
||||||
mysql_config --libs | sed "s/-lssl -lcrypto//"
|
mysql_config --libs | sed "s/-lssl -lcrypto//"
|
||||||
else
|
else
|
||||||
exec mysql_config "$@"
|
exec mysql_config "$@"
|
||||||
fi
|
fi
|
||||||
EOS
|
EOS
|
||||||
chmod 0755, "brew_shim/mysql_config"
|
chmod 0755, "brew_shim/mysql_config"
|
||||||
args << "-mysql_config" << buildpath/"brew_shim/mysql_config"
|
args << "-mysql_config" << buildpath/"brew_shim/mysql_config"
|
||||||
end
|
end
|
||||||
|
|
||||||
args << "-plugin-sql-psql" if build.with? "postgresql"
|
args << "-plugin-sql-psql" if build.with? "postgresql"
|
||||||
|
|
||||||
system "./configure", *args
|
system "./configure", *args
|
||||||
system "make"
|
system "make"
|
||||||
ENV.deparallelize
|
ENV.deparallelize
|
||||||
system "make", "install"
|
system "make", "install"
|
||||||
|
|
||||||
if build.with? "docs"
|
if build.with? "docs"
|
||||||
system "make", "docs"
|
system "make", "docs"
|
||||||
system "make", "install_docs"
|
system "make", "install_docs"
|
||||||
end
|
end
|
||||||
|
|
||||||
# Some config scripts will only find Qt in a "Frameworks" folder
|
# Some config scripts will only find Qt in a "Frameworks" folder
|
||||||
frameworks.install_symlink Dir["#{lib}/*.framework"]
|
frameworks.install_symlink Dir["#{lib}/*.framework"]
|
||||||
|
|
||||||
# The pkg-config files installed suggest that headers can be found in the
|
# The pkg-config files installed suggest that headers can be found in the
|
||||||
# `include` directory. Make this so by creating symlinks from `include` to
|
# `include` directory. Make this so by creating symlinks from `include` to
|
||||||
# the Frameworks' Headers folders.
|
# the Frameworks' Headers folders.
|
||||||
Pathname.glob("#{lib}/*.framework/Headers") do |path|
|
Pathname.glob("#{lib}/*.framework/Headers") do |path|
|
||||||
include.install_symlink path => path.parent.basename(".framework")
|
include.install_symlink path => path.parent.basename(".framework")
|
||||||
end
|
end
|
||||||
|
|
||||||
# Move `*.app` bundles into `libexec` to expose them to `brew linkapps` and
|
# Move `*.app` bundles into `libexec` to expose them to `brew linkapps` and
|
||||||
# because we don't like having them in `bin`.
|
# because we don't like having them in `bin`.
|
||||||
# (Note: This move breaks invocation of Assistant via the Help menu
|
# (Note: This move breaks invocation of Assistant via the Help menu
|
||||||
# of both Designer and Linguist as that relies on Assistant being in `bin`.)
|
# of both Designer and Linguist as that relies on Assistant being in `bin`.)
|
||||||
libexec.mkpath
|
libexec.mkpath
|
||||||
Pathname.glob("#{bin}/*.app") { |app| mv app, libexec }
|
Pathname.glob("#{bin}/*.app") { |app| mv app, libexec }
|
||||||
end
|
end
|
||||||
|
|
||||||
def caveats; <<~EOS
|
def caveats; <<~EOS
|
||||||
We agreed to the Qt opensource license for you.
|
We agreed to the Qt opensource license for you.
|
||||||
If this is unacceptable you should uninstall.
|
If this is unacceptable you should uninstall.
|
||||||
EOS
|
EOS
|
||||||
end
|
end
|
||||||
|
|
||||||
test do
|
test do
|
||||||
(testpath/"hello.pro").write <<~EOS
|
(testpath/"hello.pro").write <<~EOS
|
||||||
QT += core
|
QT += core
|
||||||
QT -= gui
|
QT -= gui
|
||||||
TARGET = hello
|
TARGET = hello
|
||||||
CONFIG += console
|
CONFIG += console
|
||||||
CONFIG -= app_bundle
|
CONFIG -= app_bundle
|
||||||
TEMPLATE = app
|
TEMPLATE = app
|
||||||
SOURCES += main.cpp
|
SOURCES += main.cpp
|
||||||
EOS
|
EOS
|
||||||
|
|
||||||
(testpath/"main.cpp").write <<~EOS
|
(testpath/"main.cpp").write <<~EOS
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
QCoreApplication a(argc, argv);
|
QCoreApplication a(argc, argv);
|
||||||
qDebug() << "Hello World!";
|
qDebug() << "Hello World!";
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
EOS
|
EOS
|
||||||
|
|
||||||
system bin/"qmake", testpath/"hello.pro"
|
system bin/"qmake", testpath/"hello.pro"
|
||||||
system "make"
|
system "make"
|
||||||
assert_predicate testpath/"hello", :exist?
|
assert_predicate testpath/"hello", :exist?
|
||||||
assert_predicate testpath/"main.o", :exist?
|
assert_predicate testpath/"main.o", :exist?
|
||||||
system "./hello"
|
system "./hello"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -42,13 +42,13 @@ Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "{uninstallexe}"
|
|||||||
// following function come from https://github.com/Xaymar/obs-studio_amf-encoder-plugin/blob/master/%23Resources/Installer.in.iss#L45
|
// following function come from https://github.com/Xaymar/obs-studio_amf-encoder-plugin/blob/master/%23Resources/Installer.in.iss#L45
|
||||||
function GetDirName(Value: string): string;
|
function GetDirName(Value: string): string;
|
||||||
var
|
var
|
||||||
InstallPath: string;
|
InstallPath: string;
|
||||||
begin
|
begin
|
||||||
// initialize default path, which will be returned when the following registry
|
// initialize default path, which will be returned when the following registry
|
||||||
// key queries fail due to missing keys or for some different reason
|
// key queries fail due to missing keys or for some different reason
|
||||||
Result := '{pf}\obs-studio';
|
Result := '{pf}\obs-studio';
|
||||||
// query the first registry value; if this succeeds, return the obtained value
|
// query the first registry value; if this succeeds, return the obtained value
|
||||||
if RegQueryStringValue(HKLM32, 'SOFTWARE\OBS Studio', '', InstallPath) then
|
if RegQueryStringValue(HKLM32, 'SOFTWARE\OBS Studio', '', InstallPath) then
|
||||||
Result := InstallPath
|
Result := InstallPath
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
216
src/Config.cpp
216
src/Config.cpp
@ -39,158 +39,158 @@ with this program. If not, see <https://www.gnu.org/licenses/>
|
|||||||
Config* Config::_instance = new Config();
|
Config* Config::_instance = new Config();
|
||||||
|
|
||||||
Config::Config() :
|
Config::Config() :
|
||||||
ServerEnabled(true),
|
ServerEnabled(true),
|
||||||
ServerPort(4444),
|
ServerPort(4444),
|
||||||
DebugEnabled(false),
|
DebugEnabled(false),
|
||||||
AlertsEnabled(true),
|
AlertsEnabled(true),
|
||||||
AuthRequired(false),
|
AuthRequired(false),
|
||||||
Secret(""),
|
Secret(""),
|
||||||
Salt(""),
|
Salt(""),
|
||||||
SettingsLoaded(false)
|
SettingsLoaded(false)
|
||||||
{
|
{
|
||||||
// OBS Config defaults
|
// OBS Config defaults
|
||||||
config_t* obsConfig = obs_frontend_get_global_config();
|
config_t* obsConfig = obs_frontend_get_global_config();
|
||||||
if (obsConfig) {
|
if (obsConfig) {
|
||||||
config_set_default_bool(obsConfig,
|
config_set_default_bool(obsConfig,
|
||||||
SECTION_NAME, PARAM_ENABLE, ServerEnabled);
|
SECTION_NAME, PARAM_ENABLE, ServerEnabled);
|
||||||
config_set_default_uint(obsConfig,
|
config_set_default_uint(obsConfig,
|
||||||
SECTION_NAME, PARAM_PORT, ServerPort);
|
SECTION_NAME, PARAM_PORT, ServerPort);
|
||||||
|
|
||||||
config_set_default_bool(obsConfig,
|
config_set_default_bool(obsConfig,
|
||||||
SECTION_NAME, PARAM_DEBUG, DebugEnabled);
|
SECTION_NAME, PARAM_DEBUG, DebugEnabled);
|
||||||
config_set_default_bool(obsConfig,
|
config_set_default_bool(obsConfig,
|
||||||
SECTION_NAME, PARAM_ALERT, AlertsEnabled);
|
SECTION_NAME, PARAM_ALERT, AlertsEnabled);
|
||||||
|
|
||||||
config_set_default_bool(obsConfig,
|
config_set_default_bool(obsConfig,
|
||||||
SECTION_NAME, PARAM_AUTHREQUIRED, AuthRequired);
|
SECTION_NAME, PARAM_AUTHREQUIRED, AuthRequired);
|
||||||
config_set_default_string(obsConfig,
|
config_set_default_string(obsConfig,
|
||||||
SECTION_NAME, PARAM_SECRET, QT_TO_UTF8(Secret));
|
SECTION_NAME, PARAM_SECRET, QT_TO_UTF8(Secret));
|
||||||
config_set_default_string(obsConfig,
|
config_set_default_string(obsConfig,
|
||||||
SECTION_NAME, PARAM_SALT, QT_TO_UTF8(Salt));
|
SECTION_NAME, PARAM_SALT, QT_TO_UTF8(Salt));
|
||||||
}
|
}
|
||||||
|
|
||||||
mbedtls_entropy_init(&entropy);
|
mbedtls_entropy_init(&entropy);
|
||||||
mbedtls_ctr_drbg_init(&rng);
|
mbedtls_ctr_drbg_init(&rng);
|
||||||
mbedtls_ctr_drbg_seed(&rng, mbedtls_entropy_func, &entropy, nullptr, 0);
|
mbedtls_ctr_drbg_seed(&rng, mbedtls_entropy_func, &entropy, nullptr, 0);
|
||||||
|
|
||||||
SessionChallenge = GenerateSalt();
|
SessionChallenge = GenerateSalt();
|
||||||
}
|
}
|
||||||
|
|
||||||
Config::~Config() {
|
Config::~Config() {
|
||||||
mbedtls_ctr_drbg_free(&rng);
|
mbedtls_ctr_drbg_free(&rng);
|
||||||
mbedtls_entropy_free(&entropy);
|
mbedtls_entropy_free(&entropy);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Config::Load() {
|
void Config::Load() {
|
||||||
config_t* obsConfig = obs_frontend_get_global_config();
|
config_t* obsConfig = obs_frontend_get_global_config();
|
||||||
|
|
||||||
ServerEnabled = config_get_bool(obsConfig, SECTION_NAME, PARAM_ENABLE);
|
ServerEnabled = config_get_bool(obsConfig, SECTION_NAME, PARAM_ENABLE);
|
||||||
ServerPort = config_get_uint(obsConfig, SECTION_NAME, PARAM_PORT);
|
ServerPort = config_get_uint(obsConfig, SECTION_NAME, PARAM_PORT);
|
||||||
|
|
||||||
DebugEnabled = config_get_bool(obsConfig, SECTION_NAME, PARAM_DEBUG);
|
DebugEnabled = config_get_bool(obsConfig, SECTION_NAME, PARAM_DEBUG);
|
||||||
AlertsEnabled = config_get_bool(obsConfig, SECTION_NAME, PARAM_ALERT);
|
AlertsEnabled = config_get_bool(obsConfig, SECTION_NAME, PARAM_ALERT);
|
||||||
|
|
||||||
AuthRequired = config_get_bool(obsConfig, SECTION_NAME, PARAM_AUTHREQUIRED);
|
AuthRequired = config_get_bool(obsConfig, SECTION_NAME, PARAM_AUTHREQUIRED);
|
||||||
Secret = config_get_string(obsConfig, SECTION_NAME, PARAM_SECRET);
|
Secret = config_get_string(obsConfig, SECTION_NAME, PARAM_SECRET);
|
||||||
Salt = config_get_string(obsConfig, SECTION_NAME, PARAM_SALT);
|
Salt = config_get_string(obsConfig, SECTION_NAME, PARAM_SALT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Config::Save() {
|
void Config::Save() {
|
||||||
config_t* obsConfig = obs_frontend_get_global_config();
|
config_t* obsConfig = obs_frontend_get_global_config();
|
||||||
|
|
||||||
config_set_bool(obsConfig, SECTION_NAME, PARAM_ENABLE, ServerEnabled);
|
config_set_bool(obsConfig, SECTION_NAME, PARAM_ENABLE, ServerEnabled);
|
||||||
config_set_uint(obsConfig, SECTION_NAME, PARAM_PORT, ServerPort);
|
config_set_uint(obsConfig, SECTION_NAME, PARAM_PORT, ServerPort);
|
||||||
|
|
||||||
config_set_bool(obsConfig, SECTION_NAME, PARAM_DEBUG, DebugEnabled);
|
config_set_bool(obsConfig, SECTION_NAME, PARAM_DEBUG, DebugEnabled);
|
||||||
config_set_bool(obsConfig, SECTION_NAME, PARAM_ALERT, AlertsEnabled);
|
config_set_bool(obsConfig, SECTION_NAME, PARAM_ALERT, AlertsEnabled);
|
||||||
|
|
||||||
config_set_bool(obsConfig, SECTION_NAME, PARAM_AUTHREQUIRED, AuthRequired);
|
config_set_bool(obsConfig, SECTION_NAME, PARAM_AUTHREQUIRED, AuthRequired);
|
||||||
config_set_string(obsConfig, SECTION_NAME, PARAM_SECRET,
|
config_set_string(obsConfig, SECTION_NAME, PARAM_SECRET,
|
||||||
QT_TO_UTF8(Secret));
|
QT_TO_UTF8(Secret));
|
||||||
config_set_string(obsConfig, SECTION_NAME, PARAM_SALT,
|
config_set_string(obsConfig, SECTION_NAME, PARAM_SALT,
|
||||||
QT_TO_UTF8(Salt));
|
QT_TO_UTF8(Salt));
|
||||||
|
|
||||||
config_save(obsConfig);
|
config_save(obsConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Config::GenerateSalt() {
|
QString Config::GenerateSalt() {
|
||||||
// Generate 32 random chars
|
// Generate 32 random chars
|
||||||
unsigned char* randomChars = (unsigned char*)bzalloc(32);
|
unsigned char* randomChars = (unsigned char*)bzalloc(32);
|
||||||
mbedtls_ctr_drbg_random(&rng, randomChars, 32);
|
mbedtls_ctr_drbg_random(&rng, randomChars, 32);
|
||||||
|
|
||||||
// Convert the 32 random chars to a base64 string
|
// Convert the 32 random chars to a base64 string
|
||||||
char* salt = (char*)bzalloc(64);
|
char* salt = (char*)bzalloc(64);
|
||||||
size_t saltBytes;
|
size_t saltBytes;
|
||||||
mbedtls_base64_encode(
|
mbedtls_base64_encode(
|
||||||
(unsigned char*)salt, 64, &saltBytes,
|
(unsigned char*)salt, 64, &saltBytes,
|
||||||
randomChars, 32);
|
randomChars, 32);
|
||||||
|
|
||||||
bfree(randomChars);
|
bfree(randomChars);
|
||||||
return salt;
|
return salt;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Config::GenerateSecret(QString password, QString salt) {
|
QString Config::GenerateSecret(QString password, QString salt) {
|
||||||
// Concatenate the password and the salt
|
// Concatenate the password and the salt
|
||||||
QString passAndSalt = "";
|
QString passAndSalt = "";
|
||||||
passAndSalt += password;
|
passAndSalt += password;
|
||||||
passAndSalt += salt;
|
passAndSalt += salt;
|
||||||
|
|
||||||
// Generate a SHA256 hash of the password
|
// Generate a SHA256 hash of the password
|
||||||
unsigned char* challengeHash = (unsigned char*)bzalloc(32);
|
unsigned char* challengeHash = (unsigned char*)bzalloc(32);
|
||||||
mbedtls_sha256(
|
mbedtls_sha256(
|
||||||
(unsigned char*)passAndSalt.toUtf8().constData(), passAndSalt.length(),
|
(unsigned char*)passAndSalt.toUtf8().constData(), passAndSalt.length(),
|
||||||
challengeHash, 0);
|
challengeHash, 0);
|
||||||
|
|
||||||
// Encode SHA256 hash to Base64
|
// Encode SHA256 hash to Base64
|
||||||
char* challenge = (char*)bzalloc(64);
|
char* challenge = (char*)bzalloc(64);
|
||||||
size_t challengeBytes = 0;
|
size_t challengeBytes = 0;
|
||||||
mbedtls_base64_encode(
|
mbedtls_base64_encode(
|
||||||
(unsigned char*)challenge, 64, &challengeBytes,
|
(unsigned char*)challenge, 64, &challengeBytes,
|
||||||
challengeHash, 32);
|
challengeHash, 32);
|
||||||
|
|
||||||
bfree(challengeHash);
|
bfree(challengeHash);
|
||||||
return challenge;
|
return challenge;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Config::SetPassword(QString password) {
|
void Config::SetPassword(QString password) {
|
||||||
QString newSalt = GenerateSalt();
|
QString newSalt = GenerateSalt();
|
||||||
QString newChallenge = GenerateSecret(password, newSalt);
|
QString newChallenge = GenerateSecret(password, newSalt);
|
||||||
|
|
||||||
this->Salt = newSalt;
|
this->Salt = newSalt;
|
||||||
this->Secret = newChallenge;
|
this->Secret = newChallenge;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Config::CheckAuth(QString response) {
|
bool Config::CheckAuth(QString response) {
|
||||||
// Concatenate auth secret with the challenge sent to the user
|
// Concatenate auth secret with the challenge sent to the user
|
||||||
QString challengeAndResponse = "";
|
QString challengeAndResponse = "";
|
||||||
challengeAndResponse += Secret;
|
challengeAndResponse += Secret;
|
||||||
challengeAndResponse += SessionChallenge;
|
challengeAndResponse += SessionChallenge;
|
||||||
|
|
||||||
// Generate a SHA256 hash of challengeAndResponse
|
// Generate a SHA256 hash of challengeAndResponse
|
||||||
unsigned char* hash = (unsigned char*)bzalloc(32);
|
unsigned char* hash = (unsigned char*)bzalloc(32);
|
||||||
mbedtls_sha256(
|
mbedtls_sha256(
|
||||||
(unsigned char*)challengeAndResponse.toUtf8().constData(),
|
(unsigned char*)challengeAndResponse.toUtf8().constData(),
|
||||||
challengeAndResponse.length(),
|
challengeAndResponse.length(),
|
||||||
hash, 0);
|
hash, 0);
|
||||||
|
|
||||||
// Encode the SHA256 hash to Base64
|
// Encode the SHA256 hash to Base64
|
||||||
char* expectedResponse = (char*)bzalloc(64);
|
char* expectedResponse = (char*)bzalloc(64);
|
||||||
size_t base64_size = 0;
|
size_t base64_size = 0;
|
||||||
mbedtls_base64_encode(
|
mbedtls_base64_encode(
|
||||||
(unsigned char*)expectedResponse, 64, &base64_size,
|
(unsigned char*)expectedResponse, 64, &base64_size,
|
||||||
hash, 32);
|
hash, 32);
|
||||||
|
|
||||||
bool authSuccess = false;
|
bool authSuccess = false;
|
||||||
if (response == QString(expectedResponse)) {
|
if (response == QString(expectedResponse)) {
|
||||||
SessionChallenge = GenerateSalt();
|
SessionChallenge = GenerateSalt();
|
||||||
authSuccess = true;
|
authSuccess = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bfree(hash);
|
bfree(hash);
|
||||||
bfree(expectedResponse);
|
bfree(expectedResponse);
|
||||||
return authSuccess;
|
return authSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
Config* Config::Current() {
|
Config* Config::Current() {
|
||||||
return _instance;
|
return _instance;
|
||||||
}
|
}
|
||||||
|
48
src/Config.h
48
src/Config.h
@ -25,36 +25,36 @@ with this program. If not, see <https://www.gnu.org/licenses/>
|
|||||||
#include <mbedtls/ctr_drbg.h>
|
#include <mbedtls/ctr_drbg.h>
|
||||||
|
|
||||||
class Config {
|
class Config {
|
||||||
public:
|
public:
|
||||||
Config();
|
Config();
|
||||||
~Config();
|
~Config();
|
||||||
void Load();
|
void Load();
|
||||||
void Save();
|
void Save();
|
||||||
|
|
||||||
void SetPassword(QString password);
|
void SetPassword(QString password);
|
||||||
bool CheckAuth(QString userChallenge);
|
bool CheckAuth(QString userChallenge);
|
||||||
QString GenerateSalt();
|
QString GenerateSalt();
|
||||||
static QString GenerateSecret(
|
static QString GenerateSecret(
|
||||||
QString password, QString salt);
|
QString password, QString salt);
|
||||||
|
|
||||||
bool ServerEnabled;
|
bool ServerEnabled;
|
||||||
uint64_t ServerPort;
|
uint64_t ServerPort;
|
||||||
|
|
||||||
bool DebugEnabled;
|
bool DebugEnabled;
|
||||||
bool AlertsEnabled;
|
bool AlertsEnabled;
|
||||||
|
|
||||||
bool AuthRequired;
|
bool AuthRequired;
|
||||||
QString Secret;
|
QString Secret;
|
||||||
QString Salt;
|
QString Salt;
|
||||||
QString SessionChallenge;
|
QString SessionChallenge;
|
||||||
bool SettingsLoaded;
|
bool SettingsLoaded;
|
||||||
|
|
||||||
static Config* Current();
|
static Config* Current();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static Config* _instance;
|
static Config* _instance;
|
||||||
mbedtls_entropy_context entropy;
|
mbedtls_entropy_context entropy;
|
||||||
mbedtls_ctr_drbg_context rng;
|
mbedtls_ctr_drbg_context rng;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CONFIG_H
|
#endif // CONFIG_H
|
646
src/Utils.cpp
646
src/Utils.cpp
@ -29,487 +29,487 @@ with this program. If not, see <https://www.gnu.org/licenses/>
|
|||||||
Q_DECLARE_METATYPE(OBSScene);
|
Q_DECLARE_METATYPE(OBSScene);
|
||||||
|
|
||||||
obs_data_array_t* Utils::StringListToArray(char** strings, char* key) {
|
obs_data_array_t* Utils::StringListToArray(char** strings, char* key) {
|
||||||
if (!strings)
|
if (!strings)
|
||||||
return obs_data_array_create();
|
return obs_data_array_create();
|
||||||
|
|
||||||
obs_data_array_t* list = obs_data_array_create();
|
obs_data_array_t* list = obs_data_array_create();
|
||||||
|
|
||||||
char* value = "";
|
char* value = "";
|
||||||
for (int i = 0; value != nullptr; i++) {
|
for (int i = 0; value != nullptr; i++) {
|
||||||
value = strings[i];
|
value = strings[i];
|
||||||
|
|
||||||
OBSDataAutoRelease item = obs_data_create();
|
OBSDataAutoRelease item = obs_data_create();
|
||||||
obs_data_set_string(item, key, value);
|
obs_data_set_string(item, key, value);
|
||||||
|
|
||||||
if (value)
|
if (value)
|
||||||
obs_data_array_push_back(list, item);
|
obs_data_array_push_back(list, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
obs_data_array_t* Utils::GetSceneItems(obs_source_t* source) {
|
obs_data_array_t* Utils::GetSceneItems(obs_source_t* source) {
|
||||||
obs_data_array_t* items = obs_data_array_create();
|
obs_data_array_t* items = obs_data_array_create();
|
||||||
OBSScene scene = obs_scene_from_source(source);
|
OBSScene scene = obs_scene_from_source(source);
|
||||||
|
|
||||||
if (!scene)
|
if (!scene)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
obs_scene_enum_items(scene, [](
|
obs_scene_enum_items(scene, [](
|
||||||
obs_scene_t* scene,
|
obs_scene_t* scene,
|
||||||
obs_sceneitem_t* currentItem,
|
obs_sceneitem_t* currentItem,
|
||||||
void* param)
|
void* param)
|
||||||
{
|
{
|
||||||
obs_data_array_t* data = static_cast<obs_data_array_t*>(param);
|
obs_data_array_t* data = static_cast<obs_data_array_t*>(param);
|
||||||
|
|
||||||
OBSDataAutoRelease itemData = GetSceneItemData(currentItem);
|
OBSDataAutoRelease itemData = GetSceneItemData(currentItem);
|
||||||
obs_data_array_insert(data, 0, itemData);
|
obs_data_array_insert(data, 0, itemData);
|
||||||
return true;
|
return true;
|
||||||
}, items);
|
}, items);
|
||||||
|
|
||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
|
|
||||||
obs_data_t* Utils::GetSceneItemData(obs_sceneitem_t* item) {
|
obs_data_t* Utils::GetSceneItemData(obs_sceneitem_t* item) {
|
||||||
if (!item)
|
if (!item)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
vec2 pos;
|
vec2 pos;
|
||||||
obs_sceneitem_get_pos(item, &pos);
|
obs_sceneitem_get_pos(item, &pos);
|
||||||
|
|
||||||
vec2 scale;
|
vec2 scale;
|
||||||
obs_sceneitem_get_scale(item, &scale);
|
obs_sceneitem_get_scale(item, &scale);
|
||||||
|
|
||||||
// obs_sceneitem_get_source doesn't increase the refcount
|
// obs_sceneitem_get_source doesn't increase the refcount
|
||||||
OBSSource itemSource = obs_sceneitem_get_source(item);
|
OBSSource itemSource = obs_sceneitem_get_source(item);
|
||||||
float item_width = float(obs_source_get_width(itemSource));
|
float item_width = float(obs_source_get_width(itemSource));
|
||||||
float item_height = float(obs_source_get_height(itemSource));
|
float item_height = float(obs_source_get_height(itemSource));
|
||||||
|
|
||||||
obs_data_t* data = obs_data_create();
|
obs_data_t* data = obs_data_create();
|
||||||
obs_data_set_string(data, "name",
|
obs_data_set_string(data, "name",
|
||||||
obs_source_get_name(obs_sceneitem_get_source(item)));
|
obs_source_get_name(obs_sceneitem_get_source(item)));
|
||||||
obs_data_set_string(data, "type",
|
obs_data_set_string(data, "type",
|
||||||
obs_source_get_id(obs_sceneitem_get_source(item)));
|
obs_source_get_id(obs_sceneitem_get_source(item)));
|
||||||
obs_data_set_double(data, "volume",
|
obs_data_set_double(data, "volume",
|
||||||
obs_source_get_volume(obs_sceneitem_get_source(item)));
|
obs_source_get_volume(obs_sceneitem_get_source(item)));
|
||||||
obs_data_set_double(data, "x", pos.x);
|
obs_data_set_double(data, "x", pos.x);
|
||||||
obs_data_set_double(data, "y", pos.y);
|
obs_data_set_double(data, "y", pos.y);
|
||||||
obs_data_set_int(data, "source_cx", (int)item_width);
|
obs_data_set_int(data, "source_cx", (int)item_width);
|
||||||
obs_data_set_int(data, "source_cy", (int)item_height);
|
obs_data_set_int(data, "source_cy", (int)item_height);
|
||||||
obs_data_set_double(data, "cx", item_width* scale.x);
|
obs_data_set_double(data, "cx", item_width* scale.x);
|
||||||
obs_data_set_double(data, "cy", item_height* scale.y);
|
obs_data_set_double(data, "cy", item_height* scale.y);
|
||||||
obs_data_set_bool(data, "render", obs_sceneitem_visible(item));
|
obs_data_set_bool(data, "render", obs_sceneitem_visible(item));
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
obs_sceneitem_t* Utils::GetSceneItemFromName(obs_source_t* source, QString name) {
|
obs_sceneitem_t* Utils::GetSceneItemFromName(obs_source_t* source, QString name) {
|
||||||
struct current_search {
|
struct current_search {
|
||||||
QString query;
|
QString query;
|
||||||
obs_sceneitem_t* result;
|
obs_sceneitem_t* result;
|
||||||
};
|
};
|
||||||
|
|
||||||
current_search search;
|
current_search search;
|
||||||
search.query = name;
|
search.query = name;
|
||||||
search.result = nullptr;
|
search.result = nullptr;
|
||||||
|
|
||||||
OBSScene scene = obs_scene_from_source(source);
|
OBSScene scene = obs_scene_from_source(source);
|
||||||
if (!scene)
|
if (!scene)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
obs_scene_enum_items(scene, [](
|
obs_scene_enum_items(scene, [](
|
||||||
obs_scene_t* scene,
|
obs_scene_t* scene,
|
||||||
obs_sceneitem_t* currentItem,
|
obs_sceneitem_t* currentItem,
|
||||||
void* param)
|
void* param)
|
||||||
{
|
{
|
||||||
current_search* search = static_cast<current_search*>(param);
|
current_search* search = static_cast<current_search*>(param);
|
||||||
|
|
||||||
QString currentItemName =
|
QString currentItemName =
|
||||||
obs_source_get_name(obs_sceneitem_get_source(currentItem));
|
obs_source_get_name(obs_sceneitem_get_source(currentItem));
|
||||||
|
|
||||||
if (currentItemName == search->query) {
|
if (currentItemName == search->query) {
|
||||||
search->result = currentItem;
|
search->result = currentItem;
|
||||||
obs_sceneitem_addref(search->result);
|
obs_sceneitem_addref(search->result);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}, &search);
|
}, &search);
|
||||||
|
|
||||||
return search.result;
|
return search.result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Utils::IsValidAlignment(const uint32_t alignment) {
|
bool Utils::IsValidAlignment(const uint32_t alignment) {
|
||||||
switch (alignment) {
|
switch (alignment) {
|
||||||
case OBS_ALIGN_CENTER:
|
case OBS_ALIGN_CENTER:
|
||||||
case OBS_ALIGN_LEFT:
|
case OBS_ALIGN_LEFT:
|
||||||
case OBS_ALIGN_RIGHT:
|
case OBS_ALIGN_RIGHT:
|
||||||
case OBS_ALIGN_TOP:
|
case OBS_ALIGN_TOP:
|
||||||
case OBS_ALIGN_BOTTOM:
|
case OBS_ALIGN_BOTTOM:
|
||||||
case OBS_ALIGN_TOP | OBS_ALIGN_LEFT:
|
case OBS_ALIGN_TOP | OBS_ALIGN_LEFT:
|
||||||
case OBS_ALIGN_TOP | OBS_ALIGN_RIGHT:
|
case OBS_ALIGN_TOP | OBS_ALIGN_RIGHT:
|
||||||
case OBS_ALIGN_BOTTOM | OBS_ALIGN_LEFT:
|
case OBS_ALIGN_BOTTOM | OBS_ALIGN_LEFT:
|
||||||
case OBS_ALIGN_BOTTOM | OBS_ALIGN_RIGHT: {
|
case OBS_ALIGN_BOTTOM | OBS_ALIGN_RIGHT: {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
obs_source_t* Utils::GetTransitionFromName(QString searchName) {
|
obs_source_t* Utils::GetTransitionFromName(QString searchName) {
|
||||||
obs_source_t* foundTransition = nullptr;
|
obs_source_t* foundTransition = nullptr;
|
||||||
|
|
||||||
obs_frontend_source_list transition_list = {};
|
obs_frontend_source_list transition_list = {};
|
||||||
obs_frontend_get_transitions(&transition_list);
|
obs_frontend_get_transitions(&transition_list);
|
||||||
|
|
||||||
for (size_t i = 0; i < transition_list.sources.num; i++) {
|
for (size_t i = 0; i < transition_list.sources.num; i++) {
|
||||||
obs_source_t* transition = transition_list.sources.array[i];
|
obs_source_t* transition = transition_list.sources.array[i];
|
||||||
QString transitionName = obs_source_get_name(transition);
|
QString transitionName = obs_source_get_name(transition);
|
||||||
|
|
||||||
if (transitionName == searchName) {
|
if (transitionName == searchName) {
|
||||||
foundTransition = transition;
|
foundTransition = transition;
|
||||||
obs_source_addref(foundTransition);
|
obs_source_addref(foundTransition);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
obs_frontend_source_list_free(&transition_list);
|
obs_frontend_source_list_free(&transition_list);
|
||||||
return foundTransition;
|
return foundTransition;
|
||||||
}
|
}
|
||||||
|
|
||||||
obs_source_t* Utils::GetSceneFromNameOrCurrent(QString sceneName) {
|
obs_source_t* Utils::GetSceneFromNameOrCurrent(QString sceneName) {
|
||||||
// Both obs_frontend_get_current_scene() and obs_get_source_by_name()
|
// Both obs_frontend_get_current_scene() and obs_get_source_by_name()
|
||||||
// do addref on the return source, so no need to use an OBSSource helper
|
// do addref on the return source, so no need to use an OBSSource helper
|
||||||
obs_source_t* scene = nullptr;
|
obs_source_t* scene = nullptr;
|
||||||
|
|
||||||
if (sceneName.isEmpty() || sceneName.isNull())
|
if (sceneName.isEmpty() || sceneName.isNull())
|
||||||
scene = obs_frontend_get_current_scene();
|
scene = obs_frontend_get_current_scene();
|
||||||
else
|
else
|
||||||
scene = obs_get_source_by_name(sceneName.toUtf8());
|
scene = obs_get_source_by_name(sceneName.toUtf8());
|
||||||
|
|
||||||
return scene;
|
return scene;
|
||||||
}
|
}
|
||||||
|
|
||||||
obs_data_array_t* Utils::GetScenes() {
|
obs_data_array_t* Utils::GetScenes() {
|
||||||
obs_frontend_source_list sceneList = {};
|
obs_frontend_source_list sceneList = {};
|
||||||
obs_frontend_get_scenes(&sceneList);
|
obs_frontend_get_scenes(&sceneList);
|
||||||
|
|
||||||
obs_data_array_t* scenes = obs_data_array_create();
|
obs_data_array_t* scenes = obs_data_array_create();
|
||||||
for (size_t i = 0; i < sceneList.sources.num; i++) {
|
for (size_t i = 0; i < sceneList.sources.num; i++) {
|
||||||
obs_source_t* scene = sceneList.sources.array[i];
|
obs_source_t* scene = sceneList.sources.array[i];
|
||||||
OBSDataAutoRelease sceneData = GetSceneData(scene);
|
OBSDataAutoRelease sceneData = GetSceneData(scene);
|
||||||
obs_data_array_push_back(scenes, sceneData);
|
obs_data_array_push_back(scenes, sceneData);
|
||||||
}
|
}
|
||||||
|
|
||||||
obs_frontend_source_list_free(&sceneList);
|
obs_frontend_source_list_free(&sceneList);
|
||||||
return scenes;
|
return scenes;
|
||||||
}
|
}
|
||||||
|
|
||||||
obs_data_t* Utils::GetSceneData(obs_source_t* source) {
|
obs_data_t* Utils::GetSceneData(obs_source_t* source) {
|
||||||
OBSDataArrayAutoRelease sceneItems = GetSceneItems(source);
|
OBSDataArrayAutoRelease sceneItems = GetSceneItems(source);
|
||||||
|
|
||||||
obs_data_t* sceneData = obs_data_create();
|
obs_data_t* sceneData = obs_data_create();
|
||||||
obs_data_set_string(sceneData, "name", obs_source_get_name(source));
|
obs_data_set_string(sceneData, "name", obs_source_get_name(source));
|
||||||
obs_data_set_array(sceneData, "sources", sceneItems);
|
obs_data_set_array(sceneData, "sources", sceneItems);
|
||||||
|
|
||||||
return sceneData;
|
return sceneData;
|
||||||
}
|
}
|
||||||
|
|
||||||
QSpinBox* Utils::GetTransitionDurationControl() {
|
QSpinBox* Utils::GetTransitionDurationControl() {
|
||||||
QMainWindow* window = (QMainWindow*)obs_frontend_get_main_window();
|
QMainWindow* window = (QMainWindow*)obs_frontend_get_main_window();
|
||||||
return window->findChild<QSpinBox*>("transitionDuration");
|
return window->findChild<QSpinBox*>("transitionDuration");
|
||||||
}
|
}
|
||||||
|
|
||||||
int Utils::GetTransitionDuration() {
|
int Utils::GetTransitionDuration() {
|
||||||
QSpinBox* control = GetTransitionDurationControl();
|
QSpinBox* control = GetTransitionDurationControl();
|
||||||
if (control)
|
if (control)
|
||||||
return control->value();
|
return control->value();
|
||||||
else
|
else
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Utils::SetTransitionDuration(int ms) {
|
void Utils::SetTransitionDuration(int ms) {
|
||||||
QSpinBox* control = GetTransitionDurationControl();
|
QSpinBox* control = GetTransitionDurationControl();
|
||||||
if (control && ms >= 0)
|
if (control && ms >= 0)
|
||||||
control->setValue(ms);
|
control->setValue(ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Utils::SetTransitionByName(QString transitionName) {
|
bool Utils::SetTransitionByName(QString transitionName) {
|
||||||
OBSSourceAutoRelease transition = GetTransitionFromName(transitionName);
|
OBSSourceAutoRelease transition = GetTransitionFromName(transitionName);
|
||||||
|
|
||||||
if (transition) {
|
if (transition) {
|
||||||
obs_frontend_set_current_transition(transition);
|
obs_frontend_set_current_transition(transition);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QPushButton* Utils::GetPreviewModeButtonControl() {
|
QPushButton* Utils::GetPreviewModeButtonControl() {
|
||||||
QMainWindow* main = (QMainWindow*)obs_frontend_get_main_window();
|
QMainWindow* main = (QMainWindow*)obs_frontend_get_main_window();
|
||||||
return main->findChild<QPushButton*>("modeSwitch");
|
return main->findChild<QPushButton*>("modeSwitch");
|
||||||
}
|
}
|
||||||
|
|
||||||
QListWidget* Utils::GetSceneListControl() {
|
QListWidget* Utils::GetSceneListControl() {
|
||||||
QMainWindow* main = (QMainWindow*)obs_frontend_get_main_window();
|
QMainWindow* main = (QMainWindow*)obs_frontend_get_main_window();
|
||||||
return main->findChild<QListWidget*>("scenes");
|
return main->findChild<QListWidget*>("scenes");
|
||||||
}
|
}
|
||||||
|
|
||||||
obs_scene_t* Utils::SceneListItemToScene(QListWidgetItem* item) {
|
obs_scene_t* Utils::SceneListItemToScene(QListWidgetItem* item) {
|
||||||
if (!item)
|
if (!item)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
QVariant itemData = item->data(static_cast<int>(Qt::UserRole));
|
QVariant itemData = item->data(static_cast<int>(Qt::UserRole));
|
||||||
return itemData.value<OBSScene>();
|
return itemData.value<OBSScene>();
|
||||||
}
|
}
|
||||||
|
|
||||||
QLayout* Utils::GetPreviewLayout() {
|
QLayout* Utils::GetPreviewLayout() {
|
||||||
QMainWindow* main = (QMainWindow*)obs_frontend_get_main_window();
|
QMainWindow* main = (QMainWindow*)obs_frontend_get_main_window();
|
||||||
return main->findChild<QLayout*>("previewLayout");
|
return main->findChild<QLayout*>("previewLayout");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Utils::TransitionToProgram() {
|
void Utils::TransitionToProgram() {
|
||||||
if (!obs_frontend_preview_program_mode_active())
|
if (!obs_frontend_preview_program_mode_active())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// WARNING : if the layout created in OBS' CreateProgramOptions() changes
|
// WARNING : if the layout created in OBS' CreateProgramOptions() changes
|
||||||
// then this won't work as expected
|
// then this won't work as expected
|
||||||
|
|
||||||
QMainWindow* main = (QMainWindow*)obs_frontend_get_main_window();
|
QMainWindow* main = (QMainWindow*)obs_frontend_get_main_window();
|
||||||
|
|
||||||
// The program options widget is the second item in the left-to-right layout
|
// The program options widget is the second item in the left-to-right layout
|
||||||
QWidget* programOptions = GetPreviewLayout()->itemAt(1)->widget();
|
QWidget* programOptions = GetPreviewLayout()->itemAt(1)->widget();
|
||||||
|
|
||||||
// The "Transition" button lies in the mainButtonLayout
|
// The "Transition" button lies in the mainButtonLayout
|
||||||
// which is the first itemin the program options' layout
|
// which is the first itemin the program options' layout
|
||||||
QLayout* mainButtonLayout = programOptions->layout()->itemAt(1)->layout();
|
QLayout* mainButtonLayout = programOptions->layout()->itemAt(1)->layout();
|
||||||
QWidget* transitionBtnWidget = mainButtonLayout->itemAt(0)->widget();
|
QWidget* transitionBtnWidget = mainButtonLayout->itemAt(0)->widget();
|
||||||
|
|
||||||
// Try to cast that widget into a button
|
// Try to cast that widget into a button
|
||||||
QPushButton* transitionBtn = qobject_cast<QPushButton*>(transitionBtnWidget);
|
QPushButton* transitionBtn = qobject_cast<QPushButton*>(transitionBtnWidget);
|
||||||
|
|
||||||
// Perform a click on that button
|
// Perform a click on that button
|
||||||
transitionBtn->click();
|
transitionBtn->click();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Utils::OBSVersionString() {
|
QString Utils::OBSVersionString() {
|
||||||
uint32_t version = obs_get_version();
|
uint32_t version = obs_get_version();
|
||||||
|
|
||||||
uint8_t major, minor, patch;
|
uint8_t major, minor, patch;
|
||||||
major = (version >> 24) & 0xFF;
|
major = (version >> 24) & 0xFF;
|
||||||
minor = (version >> 16) & 0xFF;
|
minor = (version >> 16) & 0xFF;
|
||||||
patch = version & 0xFF;
|
patch = version & 0xFF;
|
||||||
|
|
||||||
QString result = QString("%1.%2.%3")
|
QString result = QString("%1.%2.%3")
|
||||||
.arg(major).arg(minor).arg(patch);
|
.arg(major).arg(minor).arg(patch);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
QSystemTrayIcon* Utils::GetTrayIcon() {
|
QSystemTrayIcon* Utils::GetTrayIcon() {
|
||||||
QMainWindow* main = (QMainWindow*)obs_frontend_get_main_window();
|
QMainWindow* main = (QMainWindow*)obs_frontend_get_main_window();
|
||||||
if (!main) return nullptr;
|
if (!main) return nullptr;
|
||||||
|
|
||||||
return main->findChildren<QSystemTrayIcon*>().first();
|
return main->findChildren<QSystemTrayIcon*>().first();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Utils::SysTrayNotify(QString &text,
|
void Utils::SysTrayNotify(QString &text,
|
||||||
QSystemTrayIcon::MessageIcon icon, QString title) {
|
QSystemTrayIcon::MessageIcon icon, QString title) {
|
||||||
if (!Config::Current()->AlertsEnabled ||
|
if (!Config::Current()->AlertsEnabled ||
|
||||||
!QSystemTrayIcon::isSystemTrayAvailable() ||
|
!QSystemTrayIcon::isSystemTrayAvailable() ||
|
||||||
!QSystemTrayIcon::supportsMessages())
|
!QSystemTrayIcon::supportsMessages())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QSystemTrayIcon* trayIcon = GetTrayIcon();
|
QSystemTrayIcon* trayIcon = GetTrayIcon();
|
||||||
if (trayIcon)
|
if (trayIcon)
|
||||||
trayIcon->showMessage(title, text, icon);
|
trayIcon->showMessage(title, text, icon);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Utils::FormatIPAddress(QHostAddress &addr) {
|
QString Utils::FormatIPAddress(QHostAddress &addr) {
|
||||||
QRegExp v4regex("(::ffff:)(((\\d).){3})", Qt::CaseInsensitive);
|
QRegExp v4regex("(::ffff:)(((\\d).){3})", Qt::CaseInsensitive);
|
||||||
QString addrString = addr.toString();
|
QString addrString = addr.toString();
|
||||||
if (addrString.contains(v4regex)) {
|
if (addrString.contains(v4regex)) {
|
||||||
addrString = QHostAddress(addr.toIPv4Address()).toString();
|
addrString = QHostAddress(addr.toIPv4Address()).toString();
|
||||||
}
|
}
|
||||||
return addrString;
|
return addrString;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* Utils::GetRecordingFolder() {
|
const char* Utils::GetRecordingFolder() {
|
||||||
config_t* profile = obs_frontend_get_profile_config();
|
config_t* profile = obs_frontend_get_profile_config();
|
||||||
QString outputMode = config_get_string(profile, "Output", "Mode");
|
QString outputMode = config_get_string(profile, "Output", "Mode");
|
||||||
|
|
||||||
if (outputMode == "Advanced") {
|
if (outputMode == "Advanced") {
|
||||||
// Advanced mode
|
// Advanced mode
|
||||||
return config_get_string(profile, "AdvOut", "RecFilePath");
|
return config_get_string(profile, "AdvOut", "RecFilePath");
|
||||||
} else {
|
} else {
|
||||||
// Simple mode
|
// Simple mode
|
||||||
return config_get_string(profile, "SimpleOutput", "FilePath");
|
return config_get_string(profile, "SimpleOutput", "FilePath");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Utils::SetRecordingFolder(const char* path) {
|
bool Utils::SetRecordingFolder(const char* path) {
|
||||||
QDir dir(path);
|
QDir dir(path);
|
||||||
if (!dir.exists())
|
if (!dir.exists())
|
||||||
dir.mkpath(".");
|
dir.mkpath(".");
|
||||||
|
|
||||||
config_t* profile = obs_frontend_get_profile_config();
|
config_t* profile = obs_frontend_get_profile_config();
|
||||||
QString outputMode = config_get_string(profile, "Output", "Mode");
|
QString outputMode = config_get_string(profile, "Output", "Mode");
|
||||||
|
|
||||||
if (outputMode == "Advanced") {
|
if (outputMode == "Advanced") {
|
||||||
config_set_string(profile, "AdvOut", "RecFilePath", path);
|
config_set_string(profile, "AdvOut", "RecFilePath", path);
|
||||||
} else {
|
} else {
|
||||||
config_set_string(profile, "SimpleOutput", "FilePath", path);
|
config_set_string(profile, "SimpleOutput", "FilePath", path);
|
||||||
}
|
}
|
||||||
|
|
||||||
config_save(profile);
|
config_save(profile);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Utils::ParseDataToQueryString(obs_data_t* data) {
|
QString Utils::ParseDataToQueryString(obs_data_t* data) {
|
||||||
if (!data)
|
if (!data)
|
||||||
return QString();
|
return QString();
|
||||||
|
|
||||||
QString query;
|
QString query;
|
||||||
|
|
||||||
obs_data_item_t* item = obs_data_first(data);
|
obs_data_item_t* item = obs_data_first(data);
|
||||||
if (item) {
|
if (item) {
|
||||||
bool isFirst = true;
|
bool isFirst = true;
|
||||||
do {
|
do {
|
||||||
if (!obs_data_item_has_user_value(item))
|
if (!obs_data_item_has_user_value(item))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!isFirst)
|
if (!isFirst)
|
||||||
query += "&";
|
query += "&";
|
||||||
else
|
else
|
||||||
isFirst = false;
|
isFirst = false;
|
||||||
|
|
||||||
QString attrName = obs_data_item_get_name(item);
|
QString attrName = obs_data_item_get_name(item);
|
||||||
query += (attrName + "=");
|
query += (attrName + "=");
|
||||||
|
|
||||||
switch (obs_data_item_gettype(item)) {
|
switch (obs_data_item_gettype(item)) {
|
||||||
case OBS_DATA_BOOLEAN:
|
case OBS_DATA_BOOLEAN:
|
||||||
query += (obs_data_item_get_bool(item) ? "true" : "false");
|
query += (obs_data_item_get_bool(item) ? "true" : "false");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OBS_DATA_NUMBER:
|
case OBS_DATA_NUMBER:
|
||||||
switch (obs_data_item_numtype(item)) {
|
switch (obs_data_item_numtype(item)) {
|
||||||
case OBS_DATA_NUM_DOUBLE:
|
case OBS_DATA_NUM_DOUBLE:
|
||||||
query +=
|
query +=
|
||||||
QString::number(obs_data_item_get_double(item));
|
QString::number(obs_data_item_get_double(item));
|
||||||
break;
|
break;
|
||||||
case OBS_DATA_NUM_INT:
|
case OBS_DATA_NUM_INT:
|
||||||
query +=
|
query +=
|
||||||
QString::number(obs_data_item_get_int(item));
|
QString::number(obs_data_item_get_int(item));
|
||||||
break;
|
break;
|
||||||
case OBS_DATA_NUM_INVALID:
|
case OBS_DATA_NUM_INVALID:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OBS_DATA_STRING:
|
case OBS_DATA_STRING:
|
||||||
query +=
|
query +=
|
||||||
QUrl::toPercentEncoding(
|
QUrl::toPercentEncoding(
|
||||||
QString(obs_data_item_get_string(item)));
|
QString(obs_data_item_get_string(item)));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
//other types are not supported
|
//other types are not supported
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} while (obs_data_item_next(&item));
|
} while (obs_data_item_next(&item));
|
||||||
}
|
}
|
||||||
|
|
||||||
return query;
|
return query;
|
||||||
}
|
}
|
||||||
|
|
||||||
obs_hotkey_t* Utils::FindHotkeyByName(QString name) {
|
obs_hotkey_t* Utils::FindHotkeyByName(QString name) {
|
||||||
struct current_search {
|
struct current_search {
|
||||||
QString query;
|
QString query;
|
||||||
obs_hotkey_t* result;
|
obs_hotkey_t* result;
|
||||||
};
|
};
|
||||||
|
|
||||||
current_search search;
|
current_search search;
|
||||||
search.query = name;
|
search.query = name;
|
||||||
search.result = nullptr;
|
search.result = nullptr;
|
||||||
|
|
||||||
obs_enum_hotkeys([](void* data, obs_hotkey_id id, obs_hotkey_t* hotkey) {
|
obs_enum_hotkeys([](void* data, obs_hotkey_id id, obs_hotkey_t* hotkey) {
|
||||||
current_search* search = static_cast<current_search*>(data);
|
current_search* search = static_cast<current_search*>(data);
|
||||||
|
|
||||||
const char* hk_name = obs_hotkey_get_name(hotkey);
|
const char* hk_name = obs_hotkey_get_name(hotkey);
|
||||||
if (hk_name == search->query) {
|
if (hk_name == search->query) {
|
||||||
search->result = hotkey;
|
search->result = hotkey;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}, &search);
|
}, &search);
|
||||||
|
|
||||||
return search.result;
|
return search.result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Utils::ReplayBufferEnabled() {
|
bool Utils::ReplayBufferEnabled() {
|
||||||
config_t* profile = obs_frontend_get_profile_config();
|
config_t* profile = obs_frontend_get_profile_config();
|
||||||
QString outputMode = config_get_string(profile, "Output", "Mode");
|
QString outputMode = config_get_string(profile, "Output", "Mode");
|
||||||
|
|
||||||
if (outputMode == "Simple") {
|
if (outputMode == "Simple") {
|
||||||
return config_get_bool(profile, "SimpleOutput", "RecRB");
|
return config_get_bool(profile, "SimpleOutput", "RecRB");
|
||||||
}
|
}
|
||||||
else if (outputMode == "Advanced") {
|
else if (outputMode == "Advanced") {
|
||||||
return config_get_bool(profile, "AdvOut", "RecRB");
|
return config_get_bool(profile, "AdvOut", "RecRB");
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Utils::StartReplayBuffer() {
|
void Utils::StartReplayBuffer() {
|
||||||
if (obs_frontend_replay_buffer_active())
|
if (obs_frontend_replay_buffer_active())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!IsRPHotkeySet()) {
|
if (!IsRPHotkeySet()) {
|
||||||
obs_output_t* rpOutput = obs_frontend_get_replay_buffer_output();
|
obs_output_t* rpOutput = obs_frontend_get_replay_buffer_output();
|
||||||
OBSData outputHotkeys = obs_hotkeys_save_output(rpOutput);
|
OBSData outputHotkeys = obs_hotkeys_save_output(rpOutput);
|
||||||
|
|
||||||
OBSData dummyBinding = obs_data_create();
|
OBSData dummyBinding = obs_data_create();
|
||||||
obs_data_set_bool(dummyBinding, "control", true);
|
obs_data_set_bool(dummyBinding, "control", true);
|
||||||
obs_data_set_bool(dummyBinding, "alt", true);
|
obs_data_set_bool(dummyBinding, "alt", true);
|
||||||
obs_data_set_bool(dummyBinding, "shift", true);
|
obs_data_set_bool(dummyBinding, "shift", true);
|
||||||
obs_data_set_bool(dummyBinding, "command", true);
|
obs_data_set_bool(dummyBinding, "command", true);
|
||||||
obs_data_set_string(dummyBinding, "key", "OBS_KEY_0");
|
obs_data_set_string(dummyBinding, "key", "OBS_KEY_0");
|
||||||
|
|
||||||
OBSDataArray rpSaveHotkey = obs_data_get_array(
|
OBSDataArray rpSaveHotkey = obs_data_get_array(
|
||||||
outputHotkeys, "ReplayBuffer.Save");
|
outputHotkeys, "ReplayBuffer.Save");
|
||||||
obs_data_array_push_back(rpSaveHotkey, dummyBinding);
|
obs_data_array_push_back(rpSaveHotkey, dummyBinding);
|
||||||
|
|
||||||
obs_hotkeys_load_output(rpOutput, outputHotkeys);
|
obs_hotkeys_load_output(rpOutput, outputHotkeys);
|
||||||
obs_frontend_replay_buffer_start();
|
obs_frontend_replay_buffer_start();
|
||||||
|
|
||||||
obs_output_release(rpOutput);
|
obs_output_release(rpOutput);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
obs_frontend_replay_buffer_start();
|
obs_frontend_replay_buffer_start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Utils::IsRPHotkeySet() {
|
bool Utils::IsRPHotkeySet() {
|
||||||
OBSOutputAutoRelease rpOutput = obs_frontend_get_replay_buffer_output();
|
OBSOutputAutoRelease rpOutput = obs_frontend_get_replay_buffer_output();
|
||||||
OBSDataAutoRelease hotkeys = obs_hotkeys_save_output(rpOutput);
|
OBSDataAutoRelease hotkeys = obs_hotkeys_save_output(rpOutput);
|
||||||
OBSDataArrayAutoRelease bindings = obs_data_get_array(hotkeys,
|
OBSDataArrayAutoRelease bindings = obs_data_get_array(hotkeys,
|
||||||
"ReplayBuffer.Save");
|
"ReplayBuffer.Save");
|
||||||
|
|
||||||
size_t count = obs_data_array_count(bindings);
|
size_t count = obs_data_array_count(bindings);
|
||||||
return (count > 0);
|
return (count > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* Utils::GetFilenameFormatting() {
|
const char* Utils::GetFilenameFormatting() {
|
||||||
config_t* profile = obs_frontend_get_profile_config();
|
config_t* profile = obs_frontend_get_profile_config();
|
||||||
return config_get_string(profile, "Output", "FilenameFormatting");
|
return config_get_string(profile, "Output", "FilenameFormatting");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Utils::SetFilenameFormatting(const char* filenameFormatting) {
|
bool Utils::SetFilenameFormatting(const char* filenameFormatting) {
|
||||||
config_t* profile = obs_frontend_get_profile_config();
|
config_t* profile = obs_frontend_get_profile_config();
|
||||||
config_set_string(profile, "Output", "FilenameFormatting", filenameFormatting);
|
config_set_string(profile, "Output", "FilenameFormatting", filenameFormatting);
|
||||||
config_save(profile);
|
config_save(profile);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
70
src/Utils.h
70
src/Utils.h
@ -34,52 +34,52 @@ with this program. If not, see <https://www.gnu.org/licenses/>
|
|||||||
|
|
||||||
class Utils {
|
class Utils {
|
||||||
public:
|
public:
|
||||||
static obs_data_array_t* StringListToArray(char** strings, char* key);
|
static obs_data_array_t* StringListToArray(char** strings, char* key);
|
||||||
static obs_data_array_t* GetSceneItems(obs_source_t* source);
|
static obs_data_array_t* GetSceneItems(obs_source_t* source);
|
||||||
static obs_data_t* GetSceneItemData(obs_sceneitem_t* item);
|
static obs_data_t* GetSceneItemData(obs_sceneitem_t* item);
|
||||||
static obs_sceneitem_t* GetSceneItemFromName(
|
static obs_sceneitem_t* GetSceneItemFromName(
|
||||||
obs_source_t* source, QString name);
|
obs_source_t* source, QString name);
|
||||||
static obs_source_t* GetTransitionFromName(QString transitionName);
|
static obs_source_t* GetTransitionFromName(QString transitionName);
|
||||||
static obs_source_t* GetSceneFromNameOrCurrent(QString sceneName);
|
static obs_source_t* GetSceneFromNameOrCurrent(QString sceneName);
|
||||||
|
|
||||||
static bool IsValidAlignment(const uint32_t alignment);
|
static bool IsValidAlignment(const uint32_t alignment);
|
||||||
|
|
||||||
static obs_data_array_t* GetScenes();
|
static obs_data_array_t* GetScenes();
|
||||||
static obs_data_t* GetSceneData(obs_source_t* source);
|
static obs_data_t* GetSceneData(obs_source_t* source);
|
||||||
|
|
||||||
static QSpinBox* GetTransitionDurationControl();
|
static QSpinBox* GetTransitionDurationControl();
|
||||||
static int GetTransitionDuration();
|
static int GetTransitionDuration();
|
||||||
static void SetTransitionDuration(int ms);
|
static void SetTransitionDuration(int ms);
|
||||||
|
|
||||||
static bool SetTransitionByName(QString transitionName);
|
static bool SetTransitionByName(QString transitionName);
|
||||||
|
|
||||||
static QPushButton* GetPreviewModeButtonControl();
|
static QPushButton* GetPreviewModeButtonControl();
|
||||||
static QLayout* GetPreviewLayout();
|
static QLayout* GetPreviewLayout();
|
||||||
static QListWidget* GetSceneListControl();
|
static QListWidget* GetSceneListControl();
|
||||||
static obs_scene_t* SceneListItemToScene(QListWidgetItem* item);
|
static obs_scene_t* SceneListItemToScene(QListWidgetItem* item);
|
||||||
|
|
||||||
static void TransitionToProgram();
|
static void TransitionToProgram();
|
||||||
|
|
||||||
static QString OBSVersionString();
|
static QString OBSVersionString();
|
||||||
|
|
||||||
static QSystemTrayIcon* GetTrayIcon();
|
static QSystemTrayIcon* GetTrayIcon();
|
||||||
static void SysTrayNotify(
|
static void SysTrayNotify(
|
||||||
QString &text,
|
QString &text,
|
||||||
QSystemTrayIcon::MessageIcon n,
|
QSystemTrayIcon::MessageIcon n,
|
||||||
QString title = QString("obs-websocket"));
|
QString title = QString("obs-websocket"));
|
||||||
|
|
||||||
static QString FormatIPAddress(QHostAddress &addr);
|
static QString FormatIPAddress(QHostAddress &addr);
|
||||||
|
|
||||||
static const char* GetRecordingFolder();
|
static const char* GetRecordingFolder();
|
||||||
static bool SetRecordingFolder(const char* path);
|
static bool SetRecordingFolder(const char* path);
|
||||||
|
|
||||||
static QString ParseDataToQueryString(obs_data_t* data);
|
static QString ParseDataToQueryString(obs_data_t* data);
|
||||||
static obs_hotkey_t* FindHotkeyByName(QString name);
|
static obs_hotkey_t* FindHotkeyByName(QString name);
|
||||||
static bool ReplayBufferEnabled();
|
static bool ReplayBufferEnabled();
|
||||||
static void StartReplayBuffer();
|
static void StartReplayBuffer();
|
||||||
static bool IsRPHotkeySet();
|
static bool IsRPHotkeySet();
|
||||||
static const char* GetFilenameFormatting();
|
static const char* GetFilenameFormatting();
|
||||||
static bool SetFilenameFormatting(const char* filenameFormatting);
|
static bool SetFilenameFormatting(const char* filenameFormatting);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // UTILS_H
|
#endif // UTILS_H
|
||||||
|
708
src/WSEvents.cpp
708
src/WSEvents.cpp
File diff suppressed because it is too large
Load Diff
108
src/WSEvents.h
108
src/WSEvents.h
@ -28,83 +28,83 @@ with this program. If not, see <https://www.gnu.org/licenses/>
|
|||||||
class WSEvents : public QObject {
|
class WSEvents : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit WSEvents(WSServer* srv);
|
explicit WSEvents(WSServer* srv);
|
||||||
~WSEvents();
|
~WSEvents();
|
||||||
static void FrontendEventHandler(
|
static void FrontendEventHandler(
|
||||||
enum obs_frontend_event event, void* privateData);
|
enum obs_frontend_event event, void* privateData);
|
||||||
static WSEvents* Instance;
|
static WSEvents* Instance;
|
||||||
void connectSceneSignals(obs_source_t* scene);
|
void connectSceneSignals(obs_source_t* scene);
|
||||||
|
|
||||||
void hookTransitionBeginEvent();
|
void hookTransitionBeginEvent();
|
||||||
|
|
||||||
uint64_t GetStreamingTime();
|
uint64_t GetStreamingTime();
|
||||||
const char* GetStreamingTimecode();
|
const char* GetStreamingTimecode();
|
||||||
uint64_t GetRecordingTime();
|
uint64_t GetRecordingTime();
|
||||||
const char* GetRecordingTimecode();
|
const char* GetRecordingTimecode();
|
||||||
|
|
||||||
bool HeartbeatIsActive;
|
bool HeartbeatIsActive;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void deferredInitOperations();
|
void deferredInitOperations();
|
||||||
void StreamStatus();
|
void StreamStatus();
|
||||||
void Heartbeat();
|
void Heartbeat();
|
||||||
void TransitionDurationChanged(int ms);
|
void TransitionDurationChanged(int ms);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
WSServer* _srv;
|
WSServer* _srv;
|
||||||
OBSSource currentScene;
|
OBSSource currentScene;
|
||||||
|
|
||||||
bool pulse;
|
bool pulse;
|
||||||
|
|
||||||
bool _streamingActive;
|
bool _streamingActive;
|
||||||
bool _recordingActive;
|
bool _recordingActive;
|
||||||
|
|
||||||
uint64_t _streamStarttime;
|
uint64_t _streamStarttime;
|
||||||
uint64_t _recStarttime;
|
uint64_t _recStarttime;
|
||||||
|
|
||||||
uint64_t _lastBytesSent;
|
uint64_t _lastBytesSent;
|
||||||
uint64_t _lastBytesSentTime;
|
uint64_t _lastBytesSentTime;
|
||||||
|
|
||||||
void broadcastUpdate(const char* updateType,
|
void broadcastUpdate(const char* updateType,
|
||||||
obs_data_t* additionalFields);
|
obs_data_t* additionalFields);
|
||||||
|
|
||||||
void OnSceneChange();
|
void OnSceneChange();
|
||||||
void OnSceneListChange();
|
void OnSceneListChange();
|
||||||
void OnSceneCollectionChange();
|
void OnSceneCollectionChange();
|
||||||
void OnSceneCollectionListChange();
|
void OnSceneCollectionListChange();
|
||||||
|
|
||||||
void OnTransitionChange();
|
void OnTransitionChange();
|
||||||
void OnTransitionListChange();
|
void OnTransitionListChange();
|
||||||
|
|
||||||
void OnProfileChange();
|
void OnProfileChange();
|
||||||
void OnProfileListChange();
|
void OnProfileListChange();
|
||||||
|
|
||||||
void OnStreamStarting();
|
void OnStreamStarting();
|
||||||
void OnStreamStarted();
|
void OnStreamStarted();
|
||||||
void OnStreamStopping();
|
void OnStreamStopping();
|
||||||
void OnStreamStopped();
|
void OnStreamStopped();
|
||||||
|
|
||||||
void OnRecordingStarting();
|
void OnRecordingStarting();
|
||||||
void OnRecordingStarted();
|
void OnRecordingStarted();
|
||||||
void OnRecordingStopping();
|
void OnRecordingStopping();
|
||||||
void OnRecordingStopped();
|
void OnRecordingStopped();
|
||||||
|
|
||||||
void OnReplayStarting();
|
void OnReplayStarting();
|
||||||
void OnReplayStarted();
|
void OnReplayStarted();
|
||||||
void OnReplayStopping();
|
void OnReplayStopping();
|
||||||
void OnReplayStopped();
|
void OnReplayStopped();
|
||||||
|
|
||||||
void OnStudioModeSwitched(bool enabled);
|
void OnStudioModeSwitched(bool enabled);
|
||||||
void OnPreviewSceneChanged();
|
void OnPreviewSceneChanged();
|
||||||
|
|
||||||
void OnExit();
|
void OnExit();
|
||||||
|
|
||||||
static void OnTransitionBegin(void* param, calldata_t* data);
|
static void OnTransitionBegin(void* param, calldata_t* data);
|
||||||
|
|
||||||
static void OnSceneReordered(void* param, calldata_t* data);
|
static void OnSceneReordered(void* param, calldata_t* data);
|
||||||
static void OnSceneItemAdd(void* param, calldata_t* data);
|
static void OnSceneItemAdd(void* param, calldata_t* data);
|
||||||
static void OnSceneItemDelete(void* param, calldata_t* data);
|
static void OnSceneItemDelete(void* param, calldata_t* data);
|
||||||
static void OnSceneItemVisibilityChanged(void* param, calldata_t* data);
|
static void OnSceneItemVisibilityChanged(void* param, calldata_t* data);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // WSEVENTS_H
|
#endif // WSEVENTS_H
|
@ -25,62 +25,62 @@
|
|||||||
#include "WSRequestHandler.h"
|
#include "WSRequestHandler.h"
|
||||||
|
|
||||||
QHash<QString, void(*)(WSRequestHandler*)> WSRequestHandler::messageMap {
|
QHash<QString, void(*)(WSRequestHandler*)> WSRequestHandler::messageMap {
|
||||||
{ "GetVersion", WSRequestHandler::HandleGetVersion },
|
{ "GetVersion", WSRequestHandler::HandleGetVersion },
|
||||||
{ "GetAuthRequired", WSRequestHandler::HandleGetAuthRequired },
|
{ "GetAuthRequired", WSRequestHandler::HandleGetAuthRequired },
|
||||||
{ "Authenticate", WSRequestHandler::HandleAuthenticate },
|
{ "Authenticate", WSRequestHandler::HandleAuthenticate },
|
||||||
|
|
||||||
{ "SetHeartbeat", WSRequestHandler::HandleSetHeartbeat },
|
{ "SetHeartbeat", WSRequestHandler::HandleSetHeartbeat },
|
||||||
|
|
||||||
{ "SetFilenameFormatting", WSRequestHandler::HandleSetFilenameFormatting },
|
{ "SetFilenameFormatting", WSRequestHandler::HandleSetFilenameFormatting },
|
||||||
{ "GetFilenameFormatting", WSRequestHandler::HandleGetFilenameFormatting },
|
{ "GetFilenameFormatting", WSRequestHandler::HandleGetFilenameFormatting },
|
||||||
|
|
||||||
{ "SetCurrentScene", WSRequestHandler::HandleSetCurrentScene },
|
{ "SetCurrentScene", WSRequestHandler::HandleSetCurrentScene },
|
||||||
{ "GetCurrentScene", WSRequestHandler::HandleGetCurrentScene },
|
{ "GetCurrentScene", WSRequestHandler::HandleGetCurrentScene },
|
||||||
{ "GetSceneList", WSRequestHandler::HandleGetSceneList },
|
{ "GetSceneList", WSRequestHandler::HandleGetSceneList },
|
||||||
|
|
||||||
{ "SetSourceRender", WSRequestHandler::HandleSetSceneItemRender }, // Retrocompat
|
{ "SetSourceRender", WSRequestHandler::HandleSetSceneItemRender }, // Retrocompat
|
||||||
{ "SetSceneItemRender", WSRequestHandler::HandleSetSceneItemRender },
|
{ "SetSceneItemRender", WSRequestHandler::HandleSetSceneItemRender },
|
||||||
{ "SetSceneItemPosition", WSRequestHandler::HandleSetSceneItemPosition },
|
{ "SetSceneItemPosition", WSRequestHandler::HandleSetSceneItemPosition },
|
||||||
{ "SetSceneItemTransform", WSRequestHandler::HandleSetSceneItemTransform },
|
{ "SetSceneItemTransform", WSRequestHandler::HandleSetSceneItemTransform },
|
||||||
{ "SetSceneItemCrop", WSRequestHandler::HandleSetSceneItemCrop },
|
{ "SetSceneItemCrop", WSRequestHandler::HandleSetSceneItemCrop },
|
||||||
{ "GetSceneItemProperties", WSRequestHandler::HandleGetSceneItemProperties },
|
{ "GetSceneItemProperties", WSRequestHandler::HandleGetSceneItemProperties },
|
||||||
{ "SetSceneItemProperties", WSRequestHandler::HandleSetSceneItemProperties },
|
{ "SetSceneItemProperties", WSRequestHandler::HandleSetSceneItemProperties },
|
||||||
{ "ResetSceneItem", WSRequestHandler::HandleResetSceneItem },
|
{ "ResetSceneItem", WSRequestHandler::HandleResetSceneItem },
|
||||||
|
|
||||||
{ "GetStreamingStatus", WSRequestHandler::HandleGetStreamingStatus },
|
{ "GetStreamingStatus", WSRequestHandler::HandleGetStreamingStatus },
|
||||||
{ "StartStopStreaming", WSRequestHandler::HandleStartStopStreaming },
|
{ "StartStopStreaming", WSRequestHandler::HandleStartStopStreaming },
|
||||||
{ "StartStopRecording", WSRequestHandler::HandleStartStopRecording },
|
{ "StartStopRecording", WSRequestHandler::HandleStartStopRecording },
|
||||||
{ "StartStreaming", WSRequestHandler::HandleStartStreaming },
|
{ "StartStreaming", WSRequestHandler::HandleStartStreaming },
|
||||||
{ "StopStreaming", WSRequestHandler::HandleStopStreaming },
|
{ "StopStreaming", WSRequestHandler::HandleStopStreaming },
|
||||||
{ "StartRecording", WSRequestHandler::HandleStartRecording },
|
{ "StartRecording", WSRequestHandler::HandleStartRecording },
|
||||||
{ "StopRecording", WSRequestHandler::HandleStopRecording },
|
{ "StopRecording", WSRequestHandler::HandleStopRecording },
|
||||||
|
|
||||||
{ "StartStopReplayBuffer", WSRequestHandler::HandleStartStopReplayBuffer },
|
{ "StartStopReplayBuffer", WSRequestHandler::HandleStartStopReplayBuffer },
|
||||||
{ "StartReplayBuffer", WSRequestHandler::HandleStartReplayBuffer },
|
{ "StartReplayBuffer", WSRequestHandler::HandleStartReplayBuffer },
|
||||||
{ "StopReplayBuffer", WSRequestHandler::HandleStopReplayBuffer },
|
{ "StopReplayBuffer", WSRequestHandler::HandleStopReplayBuffer },
|
||||||
{ "SaveReplayBuffer", WSRequestHandler::HandleSaveReplayBuffer },
|
{ "SaveReplayBuffer", WSRequestHandler::HandleSaveReplayBuffer },
|
||||||
|
|
||||||
{ "SetRecordingFolder", WSRequestHandler::HandleSetRecordingFolder },
|
{ "SetRecordingFolder", WSRequestHandler::HandleSetRecordingFolder },
|
||||||
{ "GetRecordingFolder", WSRequestHandler::HandleGetRecordingFolder },
|
{ "GetRecordingFolder", WSRequestHandler::HandleGetRecordingFolder },
|
||||||
|
|
||||||
{ "GetTransitionList", WSRequestHandler::HandleGetTransitionList },
|
{ "GetTransitionList", WSRequestHandler::HandleGetTransitionList },
|
||||||
{ "GetCurrentTransition", WSRequestHandler::HandleGetCurrentTransition },
|
{ "GetCurrentTransition", WSRequestHandler::HandleGetCurrentTransition },
|
||||||
{ "SetCurrentTransition", WSRequestHandler::HandleSetCurrentTransition },
|
{ "SetCurrentTransition", WSRequestHandler::HandleSetCurrentTransition },
|
||||||
{ "SetTransitionDuration", WSRequestHandler::HandleSetTransitionDuration },
|
{ "SetTransitionDuration", WSRequestHandler::HandleSetTransitionDuration },
|
||||||
{ "GetTransitionDuration", WSRequestHandler::HandleGetTransitionDuration },
|
{ "GetTransitionDuration", WSRequestHandler::HandleGetTransitionDuration },
|
||||||
|
|
||||||
{ "SetVolume", WSRequestHandler::HandleSetVolume },
|
{ "SetVolume", WSRequestHandler::HandleSetVolume },
|
||||||
{ "GetVolume", WSRequestHandler::HandleGetVolume },
|
{ "GetVolume", WSRequestHandler::HandleGetVolume },
|
||||||
{ "ToggleMute", WSRequestHandler::HandleToggleMute },
|
{ "ToggleMute", WSRequestHandler::HandleToggleMute },
|
||||||
{ "SetMute", WSRequestHandler::HandleSetMute },
|
{ "SetMute", WSRequestHandler::HandleSetMute },
|
||||||
{ "GetMute", WSRequestHandler::HandleGetMute },
|
{ "GetMute", WSRequestHandler::HandleGetMute },
|
||||||
{ "SetSyncOffset", WSRequestHandler::HandleSetSyncOffset },
|
{ "SetSyncOffset", WSRequestHandler::HandleSetSyncOffset },
|
||||||
{ "GetSyncOffset", WSRequestHandler::HandleGetSyncOffset },
|
{ "GetSyncOffset", WSRequestHandler::HandleGetSyncOffset },
|
||||||
{ "GetSpecialSources", WSRequestHandler::HandleGetSpecialSources },
|
{ "GetSpecialSources", WSRequestHandler::HandleGetSpecialSources },
|
||||||
{ "GetSourcesList", WSRequestHandler::HandleGetSourcesList },
|
{ "GetSourcesList", WSRequestHandler::HandleGetSourcesList },
|
||||||
{ "GetSourceTypesList", WSRequestHandler::HandleGetSourceTypesList },
|
{ "GetSourceTypesList", WSRequestHandler::HandleGetSourceTypesList },
|
||||||
{ "GetSourceSettings", WSRequestHandler::HandleGetSourceSettings },
|
{ "GetSourceSettings", WSRequestHandler::HandleGetSourceSettings },
|
||||||
{ "SetSourceSettings", WSRequestHandler::HandleSetSourceSettings },
|
{ "SetSourceSettings", WSRequestHandler::HandleSetSourceSettings },
|
||||||
|
|
||||||
{ "GetSourceFilters", WSRequestHandler::HandleGetSourceFilters },
|
{ "GetSourceFilters", WSRequestHandler::HandleGetSourceFilters },
|
||||||
{ "AddFilterToSource", WSRequestHandler::HandleAddFilterToSource },
|
{ "AddFilterToSource", WSRequestHandler::HandleAddFilterToSource },
|
||||||
@ -89,136 +89,136 @@ QHash<QString, void(*)(WSRequestHandler*)> WSRequestHandler::messageMap {
|
|||||||
{ "MoveSourceFilter", WSRequestHandler::HandleMoveSourceFilter },
|
{ "MoveSourceFilter", WSRequestHandler::HandleMoveSourceFilter },
|
||||||
{ "SetSourceFilterSettings", WSRequestHandler::HandleSetSourceFilterSettings },
|
{ "SetSourceFilterSettings", WSRequestHandler::HandleSetSourceFilterSettings },
|
||||||
|
|
||||||
{ "SetCurrentSceneCollection", WSRequestHandler::HandleSetCurrentSceneCollection },
|
{ "SetCurrentSceneCollection", WSRequestHandler::HandleSetCurrentSceneCollection },
|
||||||
{ "GetCurrentSceneCollection", WSRequestHandler::HandleGetCurrentSceneCollection },
|
{ "GetCurrentSceneCollection", WSRequestHandler::HandleGetCurrentSceneCollection },
|
||||||
{ "ListSceneCollections", WSRequestHandler::HandleListSceneCollections },
|
{ "ListSceneCollections", WSRequestHandler::HandleListSceneCollections },
|
||||||
|
|
||||||
{ "SetCurrentProfile", WSRequestHandler::HandleSetCurrentProfile },
|
{ "SetCurrentProfile", WSRequestHandler::HandleSetCurrentProfile },
|
||||||
{ "GetCurrentProfile", WSRequestHandler::HandleGetCurrentProfile },
|
{ "GetCurrentProfile", WSRequestHandler::HandleGetCurrentProfile },
|
||||||
{ "ListProfiles", WSRequestHandler::HandleListProfiles },
|
{ "ListProfiles", WSRequestHandler::HandleListProfiles },
|
||||||
|
|
||||||
{ "SetStreamSettings", WSRequestHandler::HandleSetStreamSettings },
|
{ "SetStreamSettings", WSRequestHandler::HandleSetStreamSettings },
|
||||||
{ "GetStreamSettings", WSRequestHandler::HandleGetStreamSettings },
|
{ "GetStreamSettings", WSRequestHandler::HandleGetStreamSettings },
|
||||||
{ "SaveStreamSettings", WSRequestHandler::HandleSaveStreamSettings },
|
{ "SaveStreamSettings", WSRequestHandler::HandleSaveStreamSettings },
|
||||||
|
|
||||||
{ "GetStudioModeStatus", WSRequestHandler::HandleGetStudioModeStatus },
|
{ "GetStudioModeStatus", WSRequestHandler::HandleGetStudioModeStatus },
|
||||||
{ "GetPreviewScene", WSRequestHandler::HandleGetPreviewScene },
|
{ "GetPreviewScene", WSRequestHandler::HandleGetPreviewScene },
|
||||||
{ "SetPreviewScene", WSRequestHandler::HandleSetPreviewScene },
|
{ "SetPreviewScene", WSRequestHandler::HandleSetPreviewScene },
|
||||||
{ "TransitionToProgram", WSRequestHandler::HandleTransitionToProgram },
|
{ "TransitionToProgram", WSRequestHandler::HandleTransitionToProgram },
|
||||||
{ "EnableStudioMode", WSRequestHandler::HandleEnableStudioMode },
|
{ "EnableStudioMode", WSRequestHandler::HandleEnableStudioMode },
|
||||||
{ "DisableStudioMode", WSRequestHandler::HandleDisableStudioMode },
|
{ "DisableStudioMode", WSRequestHandler::HandleDisableStudioMode },
|
||||||
{ "ToggleStudioMode", WSRequestHandler::HandleToggleStudioMode },
|
{ "ToggleStudioMode", WSRequestHandler::HandleToggleStudioMode },
|
||||||
|
|
||||||
{ "SetTextGDIPlusProperties", WSRequestHandler::HandleSetTextGDIPlusProperties },
|
{ "SetTextGDIPlusProperties", WSRequestHandler::HandleSetTextGDIPlusProperties },
|
||||||
{ "GetTextGDIPlusProperties", WSRequestHandler::HandleGetTextGDIPlusProperties },
|
{ "GetTextGDIPlusProperties", WSRequestHandler::HandleGetTextGDIPlusProperties },
|
||||||
|
|
||||||
{ "GetBrowserSourceProperties", WSRequestHandler::HandleGetBrowserSourceProperties },
|
{ "GetBrowserSourceProperties", WSRequestHandler::HandleGetBrowserSourceProperties },
|
||||||
{ "SetBrowserSourceProperties", WSRequestHandler::HandleSetBrowserSourceProperties }
|
{ "SetBrowserSourceProperties", WSRequestHandler::HandleSetBrowserSourceProperties }
|
||||||
};
|
};
|
||||||
|
|
||||||
QSet<QString> WSRequestHandler::authNotRequired {
|
QSet<QString> WSRequestHandler::authNotRequired {
|
||||||
"GetVersion",
|
"GetVersion",
|
||||||
"GetAuthRequired",
|
"GetAuthRequired",
|
||||||
"Authenticate"
|
"Authenticate"
|
||||||
};
|
};
|
||||||
|
|
||||||
WSRequestHandler::WSRequestHandler(QWebSocket* client) :
|
WSRequestHandler::WSRequestHandler(QWebSocket* client) :
|
||||||
_messageId(0),
|
_messageId(0),
|
||||||
_requestType(""),
|
_requestType(""),
|
||||||
data(nullptr),
|
data(nullptr),
|
||||||
_client(client)
|
_client(client)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void WSRequestHandler::processIncomingMessage(QString textMessage) {
|
void WSRequestHandler::processIncomingMessage(QString textMessage) {
|
||||||
QByteArray msgData = textMessage.toUtf8();
|
QByteArray msgData = textMessage.toUtf8();
|
||||||
const char* msg = msgData.constData();
|
const char* msg = msgData.constData();
|
||||||
|
|
||||||
data = obs_data_create_from_json(msg);
|
data = obs_data_create_from_json(msg);
|
||||||
if (!data) {
|
if (!data) {
|
||||||
if (!msg)
|
if (!msg)
|
||||||
msg = "<null pointer>";
|
msg = "<null pointer>";
|
||||||
|
|
||||||
blog(LOG_ERROR, "invalid JSON payload received for '%s'", msg);
|
blog(LOG_ERROR, "invalid JSON payload received for '%s'", msg);
|
||||||
SendErrorResponse("invalid JSON payload");
|
SendErrorResponse("invalid JSON payload");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Config::Current()->DebugEnabled) {
|
if (Config::Current()->DebugEnabled) {
|
||||||
blog(LOG_DEBUG, "Request >> '%s'", msg);
|
blog(LOG_DEBUG, "Request >> '%s'", msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!hasField("request-type")
|
if (!hasField("request-type")
|
||||||
|| !hasField("message-id"))
|
|| !hasField("message-id"))
|
||||||
{
|
{
|
||||||
SendErrorResponse("missing request parameters");
|
SendErrorResponse("missing request parameters");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_requestType = obs_data_get_string(data, "request-type");
|
_requestType = obs_data_get_string(data, "request-type");
|
||||||
_messageId = obs_data_get_string(data, "message-id");
|
_messageId = obs_data_get_string(data, "message-id");
|
||||||
|
|
||||||
if (Config::Current()->AuthRequired
|
if (Config::Current()->AuthRequired
|
||||||
&& (_client->property(PROP_AUTHENTICATED).toBool() == false)
|
&& (_client->property(PROP_AUTHENTICATED).toBool() == false)
|
||||||
&& (authNotRequired.find(_requestType) == authNotRequired.end()))
|
&& (authNotRequired.find(_requestType) == authNotRequired.end()))
|
||||||
{
|
{
|
||||||
SendErrorResponse("Not Authenticated");
|
SendErrorResponse("Not Authenticated");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void (*handlerFunc)(WSRequestHandler*) = (messageMap[_requestType]);
|
void (*handlerFunc)(WSRequestHandler*) = (messageMap[_requestType]);
|
||||||
|
|
||||||
if (handlerFunc != nullptr)
|
if (handlerFunc != nullptr)
|
||||||
handlerFunc(this);
|
handlerFunc(this);
|
||||||
else
|
else
|
||||||
SendErrorResponse("invalid request type");
|
SendErrorResponse("invalid request type");
|
||||||
}
|
}
|
||||||
|
|
||||||
WSRequestHandler::~WSRequestHandler() {
|
WSRequestHandler::~WSRequestHandler() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void WSRequestHandler::SendOKResponse(obs_data_t* additionalFields) {
|
void WSRequestHandler::SendOKResponse(obs_data_t* additionalFields) {
|
||||||
OBSDataAutoRelease response = obs_data_create();
|
OBSDataAutoRelease response = obs_data_create();
|
||||||
obs_data_set_string(response, "status", "ok");
|
obs_data_set_string(response, "status", "ok");
|
||||||
obs_data_set_string(response, "message-id", _messageId);
|
obs_data_set_string(response, "message-id", _messageId);
|
||||||
|
|
||||||
if (additionalFields)
|
if (additionalFields)
|
||||||
obs_data_apply(response, additionalFields);
|
obs_data_apply(response, additionalFields);
|
||||||
|
|
||||||
SendResponse(response);
|
SendResponse(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WSRequestHandler::SendErrorResponse(const char* errorMessage) {
|
void WSRequestHandler::SendErrorResponse(const char* errorMessage) {
|
||||||
OBSDataAutoRelease response = obs_data_create();
|
OBSDataAutoRelease response = obs_data_create();
|
||||||
obs_data_set_string(response, "status", "error");
|
obs_data_set_string(response, "status", "error");
|
||||||
obs_data_set_string(response, "error", errorMessage);
|
obs_data_set_string(response, "error", errorMessage);
|
||||||
obs_data_set_string(response, "message-id", _messageId);
|
obs_data_set_string(response, "message-id", _messageId);
|
||||||
|
|
||||||
SendResponse(response);
|
SendResponse(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WSRequestHandler::SendErrorResponse(obs_data_t* additionalFields) {
|
void WSRequestHandler::SendErrorResponse(obs_data_t* additionalFields) {
|
||||||
OBSDataAutoRelease response = obs_data_create();
|
OBSDataAutoRelease response = obs_data_create();
|
||||||
obs_data_set_string(response, "status", "error");
|
obs_data_set_string(response, "status", "error");
|
||||||
obs_data_set_string(response, "message-id", _messageId);
|
obs_data_set_string(response, "message-id", _messageId);
|
||||||
|
|
||||||
if (additionalFields)
|
if (additionalFields)
|
||||||
obs_data_set_obj(response, "error", additionalFields);
|
obs_data_set_obj(response, "error", additionalFields);
|
||||||
|
|
||||||
SendResponse(response);
|
SendResponse(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WSRequestHandler::SendResponse(obs_data_t* response) {
|
void WSRequestHandler::SendResponse(obs_data_t* response) {
|
||||||
QString json = obs_data_get_json(response);
|
QString json = obs_data_get_json(response);
|
||||||
_client->sendTextMessage(json);
|
_client->sendTextMessage(json);
|
||||||
|
|
||||||
if (Config::Current()->DebugEnabled)
|
if (Config::Current()->DebugEnabled)
|
||||||
blog(LOG_DEBUG, "Response << '%s'", json.toUtf8().constData());
|
blog(LOG_DEBUG, "Response << '%s'", json.toUtf8().constData());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WSRequestHandler::hasField(QString name) {
|
bool WSRequestHandler::hasField(QString name) {
|
||||||
if (!data || name.isEmpty() || name.isNull())
|
if (!data || name.isEmpty() || name.isNull())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return obs_data_has_user_value(data, name.toUtf8());
|
return obs_data_has_user_value(data, name.toUtf8());
|
||||||
}
|
}
|
||||||
|
@ -31,81 +31,81 @@ with this program. If not, see <https://www.gnu.org/licenses/>
|
|||||||
#include "obs-websocket.h"
|
#include "obs-websocket.h"
|
||||||
|
|
||||||
class WSRequestHandler : public QObject {
|
class WSRequestHandler : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit WSRequestHandler(QWebSocket* client);
|
explicit WSRequestHandler(QWebSocket* client);
|
||||||
~WSRequestHandler();
|
~WSRequestHandler();
|
||||||
void processIncomingMessage(QString textMessage);
|
void processIncomingMessage(QString textMessage);
|
||||||
bool hasField(QString name);
|
bool hasField(QString name);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QWebSocket* _client;
|
QWebSocket* _client;
|
||||||
const char* _messageId;
|
const char* _messageId;
|
||||||
const char* _requestType;
|
const char* _requestType;
|
||||||
OBSDataAutoRelease data;
|
OBSDataAutoRelease data;
|
||||||
|
|
||||||
void SendOKResponse(obs_data_t* additionalFields = NULL);
|
void SendOKResponse(obs_data_t* additionalFields = NULL);
|
||||||
void SendErrorResponse(const char* errorMessage);
|
void SendErrorResponse(const char* errorMessage);
|
||||||
void SendErrorResponse(obs_data_t* additionalFields = NULL);
|
void SendErrorResponse(obs_data_t* additionalFields = NULL);
|
||||||
void SendResponse(obs_data_t* response);
|
void SendResponse(obs_data_t* response);
|
||||||
|
|
||||||
static QHash<QString, void(*)(WSRequestHandler*)> messageMap;
|
static QHash<QString, void(*)(WSRequestHandler*)> messageMap;
|
||||||
static QSet<QString> authNotRequired;
|
static QSet<QString> authNotRequired;
|
||||||
|
|
||||||
static void HandleGetVersion(WSRequestHandler* req);
|
static void HandleGetVersion(WSRequestHandler* req);
|
||||||
static void HandleGetAuthRequired(WSRequestHandler* req);
|
static void HandleGetAuthRequired(WSRequestHandler* req);
|
||||||
static void HandleAuthenticate(WSRequestHandler* req);
|
static void HandleAuthenticate(WSRequestHandler* req);
|
||||||
|
|
||||||
static void HandleSetHeartbeat(WSRequestHandler* req);
|
static void HandleSetHeartbeat(WSRequestHandler* req);
|
||||||
|
|
||||||
static void HandleSetFilenameFormatting(WSRequestHandler* req);
|
static void HandleSetFilenameFormatting(WSRequestHandler* req);
|
||||||
static void HandleGetFilenameFormatting(WSRequestHandler* req);
|
static void HandleGetFilenameFormatting(WSRequestHandler* req);
|
||||||
|
|
||||||
static void HandleSetCurrentScene(WSRequestHandler* req);
|
static void HandleSetCurrentScene(WSRequestHandler* req);
|
||||||
static void HandleGetCurrentScene(WSRequestHandler* req);
|
static void HandleGetCurrentScene(WSRequestHandler* req);
|
||||||
static void HandleGetSceneList(WSRequestHandler* req);
|
static void HandleGetSceneList(WSRequestHandler* req);
|
||||||
|
|
||||||
static void HandleSetSceneItemRender(WSRequestHandler* req);
|
static void HandleSetSceneItemRender(WSRequestHandler* req);
|
||||||
static void HandleSetSceneItemPosition(WSRequestHandler* req);
|
static void HandleSetSceneItemPosition(WSRequestHandler* req);
|
||||||
static void HandleSetSceneItemTransform(WSRequestHandler* req);
|
static void HandleSetSceneItemTransform(WSRequestHandler* req);
|
||||||
static void HandleSetSceneItemCrop(WSRequestHandler* req);
|
static void HandleSetSceneItemCrop(WSRequestHandler* req);
|
||||||
static void HandleGetSceneItemProperties(WSRequestHandler* req);
|
static void HandleGetSceneItemProperties(WSRequestHandler* req);
|
||||||
static void HandleSetSceneItemProperties(WSRequestHandler* req);
|
static void HandleSetSceneItemProperties(WSRequestHandler* req);
|
||||||
static void HandleResetSceneItem(WSRequestHandler* req);
|
static void HandleResetSceneItem(WSRequestHandler* req);
|
||||||
|
|
||||||
static void HandleGetStreamingStatus(WSRequestHandler* req);
|
static void HandleGetStreamingStatus(WSRequestHandler* req);
|
||||||
static void HandleStartStopStreaming(WSRequestHandler* req);
|
static void HandleStartStopStreaming(WSRequestHandler* req);
|
||||||
static void HandleStartStopRecording(WSRequestHandler* req);
|
static void HandleStartStopRecording(WSRequestHandler* req);
|
||||||
static void HandleStartStreaming(WSRequestHandler* req);
|
static void HandleStartStreaming(WSRequestHandler* req);
|
||||||
static void HandleStopStreaming(WSRequestHandler* req);
|
static void HandleStopStreaming(WSRequestHandler* req);
|
||||||
static void HandleStartRecording(WSRequestHandler* req);
|
static void HandleStartRecording(WSRequestHandler* req);
|
||||||
static void HandleStopRecording(WSRequestHandler* req);
|
static void HandleStopRecording(WSRequestHandler* req);
|
||||||
|
|
||||||
static void HandleStartStopReplayBuffer(WSRequestHandler* req);
|
static void HandleStartStopReplayBuffer(WSRequestHandler* req);
|
||||||
static void HandleStartReplayBuffer(WSRequestHandler* req);
|
static void HandleStartReplayBuffer(WSRequestHandler* req);
|
||||||
static void HandleStopReplayBuffer(WSRequestHandler* req);
|
static void HandleStopReplayBuffer(WSRequestHandler* req);
|
||||||
static void HandleSaveReplayBuffer(WSRequestHandler* req);
|
static void HandleSaveReplayBuffer(WSRequestHandler* req);
|
||||||
|
|
||||||
static void HandleSetRecordingFolder(WSRequestHandler* req);
|
static void HandleSetRecordingFolder(WSRequestHandler* req);
|
||||||
static void HandleGetRecordingFolder(WSRequestHandler* req);
|
static void HandleGetRecordingFolder(WSRequestHandler* req);
|
||||||
|
|
||||||
static void HandleGetTransitionList(WSRequestHandler* req);
|
static void HandleGetTransitionList(WSRequestHandler* req);
|
||||||
static void HandleGetCurrentTransition(WSRequestHandler* req);
|
static void HandleGetCurrentTransition(WSRequestHandler* req);
|
||||||
static void HandleSetCurrentTransition(WSRequestHandler* req);
|
static void HandleSetCurrentTransition(WSRequestHandler* req);
|
||||||
|
|
||||||
static void HandleSetVolume(WSRequestHandler* req);
|
static void HandleSetVolume(WSRequestHandler* req);
|
||||||
static void HandleGetVolume(WSRequestHandler* req);
|
static void HandleGetVolume(WSRequestHandler* req);
|
||||||
static void HandleToggleMute(WSRequestHandler* req);
|
static void HandleToggleMute(WSRequestHandler* req);
|
||||||
static void HandleSetMute(WSRequestHandler* req);
|
static void HandleSetMute(WSRequestHandler* req);
|
||||||
static void HandleGetMute(WSRequestHandler* req);
|
static void HandleGetMute(WSRequestHandler* req);
|
||||||
static void HandleSetSyncOffset(WSRequestHandler* req);
|
static void HandleSetSyncOffset(WSRequestHandler* req);
|
||||||
static void HandleGetSyncOffset(WSRequestHandler* req);
|
static void HandleGetSyncOffset(WSRequestHandler* req);
|
||||||
static void HandleGetSpecialSources(WSRequestHandler* req);
|
static void HandleGetSpecialSources(WSRequestHandler* req);
|
||||||
static void HandleGetSourcesList(WSRequestHandler* req);
|
static void HandleGetSourcesList(WSRequestHandler* req);
|
||||||
static void HandleGetSourceTypesList(WSRequestHandler* req);
|
static void HandleGetSourceTypesList(WSRequestHandler* req);
|
||||||
static void HandleGetSourceSettings(WSRequestHandler* req);
|
static void HandleGetSourceSettings(WSRequestHandler* req);
|
||||||
static void HandleSetSourceSettings(WSRequestHandler* req);
|
static void HandleSetSourceSettings(WSRequestHandler* req);
|
||||||
|
|
||||||
static void HandleGetSourceFilters(WSRequestHandler* req);
|
static void HandleGetSourceFilters(WSRequestHandler* req);
|
||||||
static void HandleAddFilterToSource(WSRequestHandler* req);
|
static void HandleAddFilterToSource(WSRequestHandler* req);
|
||||||
@ -114,33 +114,33 @@ class WSRequestHandler : public QObject {
|
|||||||
static void HandleMoveSourceFilter(WSRequestHandler* req);
|
static void HandleMoveSourceFilter(WSRequestHandler* req);
|
||||||
static void HandleSetSourceFilterSettings(WSRequestHandler* req);
|
static void HandleSetSourceFilterSettings(WSRequestHandler* req);
|
||||||
|
|
||||||
static void HandleSetCurrentSceneCollection(WSRequestHandler* req);
|
static void HandleSetCurrentSceneCollection(WSRequestHandler* req);
|
||||||
static void HandleGetCurrentSceneCollection(WSRequestHandler* req);
|
static void HandleGetCurrentSceneCollection(WSRequestHandler* req);
|
||||||
static void HandleListSceneCollections(WSRequestHandler* req);
|
static void HandleListSceneCollections(WSRequestHandler* req);
|
||||||
|
|
||||||
static void HandleSetCurrentProfile(WSRequestHandler* req);
|
static void HandleSetCurrentProfile(WSRequestHandler* req);
|
||||||
static void HandleGetCurrentProfile(WSRequestHandler* req);
|
static void HandleGetCurrentProfile(WSRequestHandler* req);
|
||||||
static void HandleListProfiles(WSRequestHandler* req);
|
static void HandleListProfiles(WSRequestHandler* req);
|
||||||
|
|
||||||
static void HandleSetStreamSettings(WSRequestHandler* req);
|
static void HandleSetStreamSettings(WSRequestHandler* req);
|
||||||
static void HandleGetStreamSettings(WSRequestHandler* req);
|
static void HandleGetStreamSettings(WSRequestHandler* req);
|
||||||
static void HandleSaveStreamSettings(WSRequestHandler* req);
|
static void HandleSaveStreamSettings(WSRequestHandler* req);
|
||||||
|
|
||||||
static void HandleSetTransitionDuration(WSRequestHandler* req);
|
static void HandleSetTransitionDuration(WSRequestHandler* req);
|
||||||
static void HandleGetTransitionDuration(WSRequestHandler* req);
|
static void HandleGetTransitionDuration(WSRequestHandler* req);
|
||||||
|
|
||||||
static void HandleGetStudioModeStatus(WSRequestHandler* req);
|
static void HandleGetStudioModeStatus(WSRequestHandler* req);
|
||||||
static void HandleGetPreviewScene(WSRequestHandler* req);
|
static void HandleGetPreviewScene(WSRequestHandler* req);
|
||||||
static void HandleSetPreviewScene(WSRequestHandler* req);
|
static void HandleSetPreviewScene(WSRequestHandler* req);
|
||||||
static void HandleTransitionToProgram(WSRequestHandler* req);
|
static void HandleTransitionToProgram(WSRequestHandler* req);
|
||||||
static void HandleEnableStudioMode(WSRequestHandler* req);
|
static void HandleEnableStudioMode(WSRequestHandler* req);
|
||||||
static void HandleDisableStudioMode(WSRequestHandler* req);
|
static void HandleDisableStudioMode(WSRequestHandler* req);
|
||||||
static void HandleToggleStudioMode(WSRequestHandler* req);
|
static void HandleToggleStudioMode(WSRequestHandler* req);
|
||||||
|
|
||||||
static void HandleSetTextGDIPlusProperties(WSRequestHandler* req);
|
static void HandleSetTextGDIPlusProperties(WSRequestHandler* req);
|
||||||
static void HandleGetTextGDIPlusProperties(WSRequestHandler* req);
|
static void HandleGetTextGDIPlusProperties(WSRequestHandler* req);
|
||||||
static void HandleSetBrowserSourceProperties(WSRequestHandler* req);
|
static void HandleSetBrowserSourceProperties(WSRequestHandler* req);
|
||||||
static void HandleGetBrowserSourceProperties(WSRequestHandler* req);
|
static void HandleGetBrowserSourceProperties(WSRequestHandler* req);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // WSPROTOCOL_H
|
#endif // WSPROTOCOL_H
|
||||||
|
@ -20,24 +20,24 @@
|
|||||||
* @since 0.3
|
* @since 0.3
|
||||||
*/
|
*/
|
||||||
void WSRequestHandler::HandleGetVersion(WSRequestHandler* req) {
|
void WSRequestHandler::HandleGetVersion(WSRequestHandler* req) {
|
||||||
QString obsVersion = Utils::OBSVersionString();
|
QString obsVersion = Utils::OBSVersionString();
|
||||||
|
|
||||||
QList<QString> names = req->messageMap.keys();
|
QList<QString> names = req->messageMap.keys();
|
||||||
names.sort(Qt::CaseInsensitive);
|
names.sort(Qt::CaseInsensitive);
|
||||||
|
|
||||||
// (Palakis) OBS' data arrays only support object arrays, so I improvised.
|
// (Palakis) OBS' data arrays only support object arrays, so I improvised.
|
||||||
QString requests;
|
QString requests;
|
||||||
requests += names.takeFirst();
|
requests += names.takeFirst();
|
||||||
for (QString reqName : names) {
|
for (QString reqName : names) {
|
||||||
requests += ("," + reqName);
|
requests += ("," + reqName);
|
||||||
}
|
}
|
||||||
|
|
||||||
OBSDataAutoRelease data = obs_data_create();
|
OBSDataAutoRelease data = obs_data_create();
|
||||||
obs_data_set_string(data, "obs-websocket-version", OBS_WEBSOCKET_VERSION);
|
obs_data_set_string(data, "obs-websocket-version", OBS_WEBSOCKET_VERSION);
|
||||||
obs_data_set_string(data, "obs-studio-version", obsVersion.toUtf8());
|
obs_data_set_string(data, "obs-studio-version", obsVersion.toUtf8());
|
||||||
obs_data_set_string(data, "available-requests", requests.toUtf8());
|
obs_data_set_string(data, "available-requests", requests.toUtf8());
|
||||||
|
|
||||||
req->SendOKResponse(data);
|
req->SendOKResponse(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -54,19 +54,19 @@
|
|||||||
* @since 0.3
|
* @since 0.3
|
||||||
*/
|
*/
|
||||||
void WSRequestHandler::HandleGetAuthRequired(WSRequestHandler* req) {
|
void WSRequestHandler::HandleGetAuthRequired(WSRequestHandler* req) {
|
||||||
bool authRequired = Config::Current()->AuthRequired;
|
bool authRequired = Config::Current()->AuthRequired;
|
||||||
|
|
||||||
OBSDataAutoRelease data = obs_data_create();
|
OBSDataAutoRelease data = obs_data_create();
|
||||||
obs_data_set_bool(data, "authRequired", authRequired);
|
obs_data_set_bool(data, "authRequired", authRequired);
|
||||||
|
|
||||||
if (authRequired) {
|
if (authRequired) {
|
||||||
obs_data_set_string(data, "challenge",
|
obs_data_set_string(data, "challenge",
|
||||||
Config::Current()->SessionChallenge.toUtf8());
|
Config::Current()->SessionChallenge.toUtf8());
|
||||||
obs_data_set_string(data, "salt",
|
obs_data_set_string(data, "salt",
|
||||||
Config::Current()->Salt.toUtf8());
|
Config::Current()->Salt.toUtf8());
|
||||||
}
|
}
|
||||||
|
|
||||||
req->SendOKResponse(data);
|
req->SendOKResponse(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -80,25 +80,25 @@ void WSRequestHandler::HandleGetAuthRequired(WSRequestHandler* req) {
|
|||||||
* @since 0.3
|
* @since 0.3
|
||||||
*/
|
*/
|
||||||
void WSRequestHandler::HandleAuthenticate(WSRequestHandler* req) {
|
void WSRequestHandler::HandleAuthenticate(WSRequestHandler* req) {
|
||||||
if (!req->hasField("auth")) {
|
if (!req->hasField("auth")) {
|
||||||
req->SendErrorResponse("missing request parameters");
|
req->SendErrorResponse("missing request parameters");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString auth = obs_data_get_string(req->data, "auth");
|
QString auth = obs_data_get_string(req->data, "auth");
|
||||||
if (auth.isEmpty()) {
|
if (auth.isEmpty()) {
|
||||||
req->SendErrorResponse("auth not specified!");
|
req->SendErrorResponse("auth not specified!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((req->_client->property(PROP_AUTHENTICATED).toBool() == false)
|
if ((req->_client->property(PROP_AUTHENTICATED).toBool() == false)
|
||||||
&& Config::Current()->CheckAuth(auth))
|
&& Config::Current()->CheckAuth(auth))
|
||||||
{
|
{
|
||||||
req->_client->setProperty(PROP_AUTHENTICATED, true);
|
req->_client->setProperty(PROP_AUTHENTICATED, true);
|
||||||
req->SendOKResponse();
|
req->SendOKResponse();
|
||||||
} else {
|
} else {
|
||||||
req->SendErrorResponse("Authentication Failed.");
|
req->SendErrorResponse("Authentication Failed.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -112,18 +112,18 @@ void WSRequestHandler::HandleAuthenticate(WSRequestHandler* req) {
|
|||||||
* @since 4.3.0
|
* @since 4.3.0
|
||||||
*/
|
*/
|
||||||
void WSRequestHandler::HandleSetHeartbeat(WSRequestHandler* req) {
|
void WSRequestHandler::HandleSetHeartbeat(WSRequestHandler* req) {
|
||||||
if (!req->hasField("enable")) {
|
if (!req->hasField("enable")) {
|
||||||
req->SendErrorResponse("Heartbeat <enable> parameter missing");
|
req->SendErrorResponse("Heartbeat <enable> parameter missing");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
WSEvents::Instance->HeartbeatIsActive =
|
WSEvents::Instance->HeartbeatIsActive =
|
||||||
obs_data_get_bool(req->data, "enable");
|
obs_data_get_bool(req->data, "enable");
|
||||||
|
|
||||||
OBSDataAutoRelease response = obs_data_create();
|
OBSDataAutoRelease response = obs_data_create();
|
||||||
obs_data_set_bool(response, "enable",
|
obs_data_set_bool(response, "enable",
|
||||||
WSEvents::Instance->HeartbeatIsActive);
|
WSEvents::Instance->HeartbeatIsActive);
|
||||||
req->SendOKResponse(response);
|
req->SendOKResponse(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -137,18 +137,18 @@ void WSRequestHandler::HandleAuthenticate(WSRequestHandler* req) {
|
|||||||
* @since 4.3.0
|
* @since 4.3.0
|
||||||
*/
|
*/
|
||||||
void WSRequestHandler::HandleSetFilenameFormatting(WSRequestHandler* req) {
|
void WSRequestHandler::HandleSetFilenameFormatting(WSRequestHandler* req) {
|
||||||
if (!req->hasField("filename-formatting")) {
|
if (!req->hasField("filename-formatting")) {
|
||||||
req->SendErrorResponse("<filename-formatting> parameter missing");
|
req->SendErrorResponse("<filename-formatting> parameter missing");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString filenameFormatting = obs_data_get_string(req->data, "filename-formatting");
|
QString filenameFormatting = obs_data_get_string(req->data, "filename-formatting");
|
||||||
if (!filenameFormatting.isEmpty()) {
|
if (!filenameFormatting.isEmpty()) {
|
||||||
Utils::SetFilenameFormatting(filenameFormatting.toUtf8());
|
Utils::SetFilenameFormatting(filenameFormatting.toUtf8());
|
||||||
req->SendOKResponse();
|
req->SendOKResponse();
|
||||||
} else {
|
} else {
|
||||||
req->SendErrorResponse("invalid request parameters");
|
req->SendErrorResponse("invalid request parameters");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -162,7 +162,7 @@ void WSRequestHandler::HandleSetFilenameFormatting(WSRequestHandler* req) {
|
|||||||
* @since 4.3.0
|
* @since 4.3.0
|
||||||
*/
|
*/
|
||||||
void WSRequestHandler::HandleGetFilenameFormatting(WSRequestHandler* req) {
|
void WSRequestHandler::HandleGetFilenameFormatting(WSRequestHandler* req) {
|
||||||
OBSDataAutoRelease response = obs_data_create();
|
OBSDataAutoRelease response = obs_data_create();
|
||||||
obs_data_set_string(response, "filename-formatting", Utils::GetFilenameFormatting());
|
obs_data_set_string(response, "filename-formatting", Utils::GetFilenameFormatting());
|
||||||
req->SendOKResponse(response);
|
req->SendOKResponse(response);
|
||||||
}
|
}
|
||||||
|
@ -14,19 +14,19 @@
|
|||||||
* @since 4.0.0
|
* @since 4.0.0
|
||||||
*/
|
*/
|
||||||
void WSRequestHandler::HandleSetCurrentProfile(WSRequestHandler* req) {
|
void WSRequestHandler::HandleSetCurrentProfile(WSRequestHandler* req) {
|
||||||
if (!req->hasField("profile-name")) {
|
if (!req->hasField("profile-name")) {
|
||||||
req->SendErrorResponse("missing request parameters");
|
req->SendErrorResponse("missing request parameters");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString profileName = obs_data_get_string(req->data, "profile-name");
|
QString profileName = obs_data_get_string(req->data, "profile-name");
|
||||||
if (!profileName.isEmpty()) {
|
if (!profileName.isEmpty()) {
|
||||||
// TODO : check if profile exists
|
// TODO : check if profile exists
|
||||||
obs_frontend_set_current_profile(profileName.toUtf8());
|
obs_frontend_set_current_profile(profileName.toUtf8());
|
||||||
req->SendOKResponse();
|
req->SendOKResponse();
|
||||||
} else {
|
} else {
|
||||||
req->SendErrorResponse("invalid request parameters");
|
req->SendErrorResponse("invalid request parameters");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -40,11 +40,11 @@
|
|||||||
* @since 4.0.0
|
* @since 4.0.0
|
||||||
*/
|
*/
|
||||||
void WSRequestHandler::HandleGetCurrentProfile(WSRequestHandler* req) {
|
void WSRequestHandler::HandleGetCurrentProfile(WSRequestHandler* req) {
|
||||||
OBSDataAutoRelease response = obs_data_create();
|
OBSDataAutoRelease response = obs_data_create();
|
||||||
obs_data_set_string(response, "profile-name",
|
obs_data_set_string(response, "profile-name",
|
||||||
obs_frontend_get_current_profile());
|
obs_frontend_get_current_profile());
|
||||||
|
|
||||||
req->SendOKResponse(response);
|
req->SendOKResponse(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -58,13 +58,13 @@ void WSRequestHandler::HandleGetCurrentProfile(WSRequestHandler* req) {
|
|||||||
* @since 4.0.0
|
* @since 4.0.0
|
||||||
*/
|
*/
|
||||||
void WSRequestHandler::HandleListProfiles(WSRequestHandler* req) {
|
void WSRequestHandler::HandleListProfiles(WSRequestHandler* req) {
|
||||||
char** profiles = obs_frontend_get_profiles();
|
char** profiles = obs_frontend_get_profiles();
|
||||||
OBSDataArrayAutoRelease list =
|
OBSDataArrayAutoRelease list =
|
||||||
Utils::StringListToArray(profiles, "profile-name");
|
Utils::StringListToArray(profiles, "profile-name");
|
||||||
bfree(profiles);
|
bfree(profiles);
|
||||||
|
|
||||||
OBSDataAutoRelease response = obs_data_create();
|
OBSDataAutoRelease response = obs_data_create();
|
||||||
obs_data_set_array(response, "profiles", list);
|
obs_data_set_array(response, "profiles", list);
|
||||||
|
|
||||||
req->SendOKResponse(response);
|
req->SendOKResponse(response);
|
||||||
}
|
}
|
||||||
|
@ -12,12 +12,12 @@
|
|||||||
* @since 0.3
|
* @since 0.3
|
||||||
*/
|
*/
|
||||||
void WSRequestHandler::HandleStartStopRecording(WSRequestHandler* req) {
|
void WSRequestHandler::HandleStartStopRecording(WSRequestHandler* req) {
|
||||||
if (obs_frontend_recording_active())
|
if (obs_frontend_recording_active())
|
||||||
obs_frontend_recording_stop();
|
obs_frontend_recording_stop();
|
||||||
else
|
else
|
||||||
obs_frontend_recording_start();
|
obs_frontend_recording_start();
|
||||||
|
|
||||||
req->SendOKResponse();
|
req->SendOKResponse();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -30,12 +30,12 @@
|
|||||||
* @since 4.1.0
|
* @since 4.1.0
|
||||||
*/
|
*/
|
||||||
void WSRequestHandler::HandleStartRecording(WSRequestHandler* req) {
|
void WSRequestHandler::HandleStartRecording(WSRequestHandler* req) {
|
||||||
if (obs_frontend_recording_active() == false) {
|
if (obs_frontend_recording_active() == false) {
|
||||||
obs_frontend_recording_start();
|
obs_frontend_recording_start();
|
||||||
req->SendOKResponse();
|
req->SendOKResponse();
|
||||||
} else {
|
} else {
|
||||||
req->SendErrorResponse("recording already active");
|
req->SendErrorResponse("recording already active");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -48,12 +48,12 @@
|
|||||||
* @since 4.1.0
|
* @since 4.1.0
|
||||||
*/
|
*/
|
||||||
void WSRequestHandler::HandleStopRecording(WSRequestHandler* req) {
|
void WSRequestHandler::HandleStopRecording(WSRequestHandler* req) {
|
||||||
if (obs_frontend_recording_active() == true) {
|
if (obs_frontend_recording_active() == true) {
|
||||||
obs_frontend_recording_stop();
|
obs_frontend_recording_stop();
|
||||||
req->SendOKResponse();
|
req->SendOKResponse();
|
||||||
} else {
|
} else {
|
||||||
req->SendErrorResponse("recording not active");
|
req->SendErrorResponse("recording not active");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -67,17 +67,17 @@ void WSRequestHandler::HandleStopRecording(WSRequestHandler* req) {
|
|||||||
* @since 4.1.0
|
* @since 4.1.0
|
||||||
*/
|
*/
|
||||||
void WSRequestHandler::HandleSetRecordingFolder(WSRequestHandler* req) {
|
void WSRequestHandler::HandleSetRecordingFolder(WSRequestHandler* req) {
|
||||||
if (!req->hasField("rec-folder")) {
|
if (!req->hasField("rec-folder")) {
|
||||||
req->SendErrorResponse("missing request parameters");
|
req->SendErrorResponse("missing request parameters");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* newRecFolder = obs_data_get_string(req->data, "rec-folder");
|
const char* newRecFolder = obs_data_get_string(req->data, "rec-folder");
|
||||||
bool success = Utils::SetRecordingFolder(newRecFolder);
|
bool success = Utils::SetRecordingFolder(newRecFolder);
|
||||||
if (success)
|
if (success)
|
||||||
req->SendOKResponse();
|
req->SendOKResponse();
|
||||||
else
|
else
|
||||||
req->SendErrorResponse("invalid request parameters");
|
req->SendErrorResponse("invalid request parameters");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -91,10 +91,10 @@ void WSRequestHandler::HandleStopRecording(WSRequestHandler* req) {
|
|||||||
* @since 4.1.0
|
* @since 4.1.0
|
||||||
*/
|
*/
|
||||||
void WSRequestHandler::HandleGetRecordingFolder(WSRequestHandler* req) {
|
void WSRequestHandler::HandleGetRecordingFolder(WSRequestHandler* req) {
|
||||||
const char* recFolder = Utils::GetRecordingFolder();
|
const char* recFolder = Utils::GetRecordingFolder();
|
||||||
|
|
||||||
OBSDataAutoRelease response = obs_data_create();
|
OBSDataAutoRelease response = obs_data_create();
|
||||||
obs_data_set_string(response, "rec-folder", recFolder);
|
obs_data_set_string(response, "rec-folder", recFolder);
|
||||||
|
|
||||||
req->SendOKResponse(response);
|
req->SendOKResponse(response);
|
||||||
}
|
}
|
||||||
|
@ -12,12 +12,12 @@
|
|||||||
* @since 4.2.0
|
* @since 4.2.0
|
||||||
*/
|
*/
|
||||||
void WSRequestHandler::HandleStartStopReplayBuffer(WSRequestHandler* req) {
|
void WSRequestHandler::HandleStartStopReplayBuffer(WSRequestHandler* req) {
|
||||||
if (obs_frontend_replay_buffer_active()) {
|
if (obs_frontend_replay_buffer_active()) {
|
||||||
obs_frontend_replay_buffer_stop();
|
obs_frontend_replay_buffer_stop();
|
||||||
} else {
|
} else {
|
||||||
Utils::StartReplayBuffer();
|
Utils::StartReplayBuffer();
|
||||||
}
|
}
|
||||||
req->SendOKResponse();
|
req->SendOKResponse();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -33,18 +33,18 @@ void WSRequestHandler::HandleStartStopReplayBuffer(WSRequestHandler* req) {
|
|||||||
* @since 4.2.0
|
* @since 4.2.0
|
||||||
*/
|
*/
|
||||||
void WSRequestHandler::HandleStartReplayBuffer(WSRequestHandler* req) {
|
void WSRequestHandler::HandleStartReplayBuffer(WSRequestHandler* req) {
|
||||||
if (!Utils::ReplayBufferEnabled()) {
|
if (!Utils::ReplayBufferEnabled()) {
|
||||||
req->SendErrorResponse("replay buffer disabled in settings");
|
req->SendErrorResponse("replay buffer disabled in settings");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obs_frontend_replay_buffer_active() == true) {
|
if (obs_frontend_replay_buffer_active() == true) {
|
||||||
req->SendErrorResponse("replay buffer already active");
|
req->SendErrorResponse("replay buffer already active");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Utils::StartReplayBuffer();
|
Utils::StartReplayBuffer();
|
||||||
req->SendOKResponse();
|
req->SendOKResponse();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -57,12 +57,12 @@ void WSRequestHandler::HandleStartReplayBuffer(WSRequestHandler* req) {
|
|||||||
* @since 4.2.0
|
* @since 4.2.0
|
||||||
*/
|
*/
|
||||||
void WSRequestHandler::HandleStopReplayBuffer(WSRequestHandler* req) {
|
void WSRequestHandler::HandleStopReplayBuffer(WSRequestHandler* req) {
|
||||||
if (obs_frontend_replay_buffer_active() == true) {
|
if (obs_frontend_replay_buffer_active() == true) {
|
||||||
obs_frontend_replay_buffer_stop();
|
obs_frontend_replay_buffer_stop();
|
||||||
req->SendOKResponse();
|
req->SendOKResponse();
|
||||||
} else {
|
} else {
|
||||||
req->SendErrorResponse("replay buffer not active");
|
req->SendErrorResponse("replay buffer not active");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -76,17 +76,17 @@ void WSRequestHandler::HandleStopReplayBuffer(WSRequestHandler* req) {
|
|||||||
* @since 4.2.0
|
* @since 4.2.0
|
||||||
*/
|
*/
|
||||||
void WSRequestHandler::HandleSaveReplayBuffer(WSRequestHandler* req) {
|
void WSRequestHandler::HandleSaveReplayBuffer(WSRequestHandler* req) {
|
||||||
if (!obs_frontend_replay_buffer_active()) {
|
if (!obs_frontend_replay_buffer_active()) {
|
||||||
req->SendErrorResponse("replay buffer not active");
|
req->SendErrorResponse("replay buffer not active");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
OBSOutputAutoRelease replayOutput = obs_frontend_get_replay_buffer_output();
|
OBSOutputAutoRelease replayOutput = obs_frontend_get_replay_buffer_output();
|
||||||
|
|
||||||
calldata_t cd = { 0 };
|
calldata_t cd = { 0 };
|
||||||
proc_handler_t* ph = obs_output_get_proc_handler(replayOutput);
|
proc_handler_t* ph = obs_output_get_proc_handler(replayOutput);
|
||||||
proc_handler_call(ph, "save", &cd);
|
proc_handler_call(ph, "save", &cd);
|
||||||
calldata_free(&cd);
|
calldata_free(&cd);
|
||||||
|
|
||||||
req->SendOKResponse();
|
req->SendOKResponse();
|
||||||
}
|
}
|
||||||
|
@ -14,19 +14,19 @@
|
|||||||
* @since 4.0.0
|
* @since 4.0.0
|
||||||
*/
|
*/
|
||||||
void WSRequestHandler::HandleSetCurrentSceneCollection(WSRequestHandler* req) {
|
void WSRequestHandler::HandleSetCurrentSceneCollection(WSRequestHandler* req) {
|
||||||
if (!req->hasField("sc-name")) {
|
if (!req->hasField("sc-name")) {
|
||||||
req->SendErrorResponse("missing request parameters");
|
req->SendErrorResponse("missing request parameters");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString sceneCollection = obs_data_get_string(req->data, "sc-name");
|
QString sceneCollection = obs_data_get_string(req->data, "sc-name");
|
||||||
if (!sceneCollection.isEmpty()) {
|
if (!sceneCollection.isEmpty()) {
|
||||||
// TODO : Check if specified profile exists and if changing is allowed
|
// TODO : Check if specified profile exists and if changing is allowed
|
||||||
obs_frontend_set_current_scene_collection(sceneCollection.toUtf8());
|
obs_frontend_set_current_scene_collection(sceneCollection.toUtf8());
|
||||||
req->SendOKResponse();
|
req->SendOKResponse();
|
||||||
} else {
|
} else {
|
||||||
req->SendErrorResponse("invalid request parameters");
|
req->SendErrorResponse("invalid request parameters");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -40,11 +40,11 @@
|
|||||||
* @since 4.0.0
|
* @since 4.0.0
|
||||||
*/
|
*/
|
||||||
void WSRequestHandler::HandleGetCurrentSceneCollection(WSRequestHandler* req) {
|
void WSRequestHandler::HandleGetCurrentSceneCollection(WSRequestHandler* req) {
|
||||||
OBSDataAutoRelease response = obs_data_create();
|
OBSDataAutoRelease response = obs_data_create();
|
||||||
obs_data_set_string(response, "sc-name",
|
obs_data_set_string(response, "sc-name",
|
||||||
obs_frontend_get_current_scene_collection());
|
obs_frontend_get_current_scene_collection());
|
||||||
|
|
||||||
req->SendOKResponse(response);
|
req->SendOKResponse(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -59,13 +59,13 @@ void WSRequestHandler::HandleGetCurrentSceneCollection(WSRequestHandler* req) {
|
|||||||
* @since 4.0.0
|
* @since 4.0.0
|
||||||
*/
|
*/
|
||||||
void WSRequestHandler::HandleListSceneCollections(WSRequestHandler* req) {
|
void WSRequestHandler::HandleListSceneCollections(WSRequestHandler* req) {
|
||||||
char** sceneCollections = obs_frontend_get_scene_collections();
|
char** sceneCollections = obs_frontend_get_scene_collections();
|
||||||
OBSDataArrayAutoRelease list =
|
OBSDataArrayAutoRelease list =
|
||||||
Utils::StringListToArray(sceneCollections, "sc-name");
|
Utils::StringListToArray(sceneCollections, "sc-name");
|
||||||
bfree(sceneCollections);
|
bfree(sceneCollections);
|
||||||
|
|
||||||
OBSDataAutoRelease response = obs_data_create();
|
OBSDataAutoRelease response = obs_data_create();
|
||||||
obs_data_set_array(response, "scene-collections", list);
|
obs_data_set_array(response, "scene-collections", list);
|
||||||
|
|
||||||
req->SendOKResponse(response);
|
req->SendOKResponse(response);
|
||||||
}
|
}
|
||||||
|
@ -14,20 +14,20 @@
|
|||||||
* @since 0.3
|
* @since 0.3
|
||||||
*/
|
*/
|
||||||
void WSRequestHandler::HandleSetCurrentScene(WSRequestHandler* req) {
|
void WSRequestHandler::HandleSetCurrentScene(WSRequestHandler* req) {
|
||||||
if (!req->hasField("scene-name")) {
|
if (!req->hasField("scene-name")) {
|
||||||
req->SendErrorResponse("missing request parameters");
|
req->SendErrorResponse("missing request parameters");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* sceneName = obs_data_get_string(req->data, "scene-name");
|
const char* sceneName = obs_data_get_string(req->data, "scene-name");
|
||||||
OBSSourceAutoRelease source = obs_get_source_by_name(sceneName);
|
OBSSourceAutoRelease source = obs_get_source_by_name(sceneName);
|
||||||
|
|
||||||
if (source) {
|
if (source) {
|
||||||
obs_frontend_set_current_scene(source);
|
obs_frontend_set_current_scene(source);
|
||||||
req->SendOKResponse();
|
req->SendOKResponse();
|
||||||
} else {
|
} else {
|
||||||
req->SendErrorResponse("requested scene does not exist");
|
req->SendErrorResponse("requested scene does not exist");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -42,14 +42,14 @@
|
|||||||
* @since 0.3
|
* @since 0.3
|
||||||
*/
|
*/
|
||||||
void WSRequestHandler::HandleGetCurrentScene(WSRequestHandler* req) {
|
void WSRequestHandler::HandleGetCurrentScene(WSRequestHandler* req) {
|
||||||
OBSSourceAutoRelease currentScene = obs_frontend_get_current_scene();
|
OBSSourceAutoRelease currentScene = obs_frontend_get_current_scene();
|
||||||
OBSDataArrayAutoRelease sceneItems = Utils::GetSceneItems(currentScene);
|
OBSDataArrayAutoRelease sceneItems = Utils::GetSceneItems(currentScene);
|
||||||
|
|
||||||
OBSDataAutoRelease data = obs_data_create();
|
OBSDataAutoRelease data = obs_data_create();
|
||||||
obs_data_set_string(data, "name", obs_source_get_name(currentScene));
|
obs_data_set_string(data, "name", obs_source_get_name(currentScene));
|
||||||
obs_data_set_array(data, "sources", sceneItems);
|
obs_data_set_array(data, "sources", sceneItems);
|
||||||
|
|
||||||
req->SendOKResponse(data);
|
req->SendOKResponse(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -64,13 +64,13 @@ void WSRequestHandler::HandleGetCurrentScene(WSRequestHandler* req) {
|
|||||||
* @since 0.3
|
* @since 0.3
|
||||||
*/
|
*/
|
||||||
void WSRequestHandler::HandleGetSceneList(WSRequestHandler* req) {
|
void WSRequestHandler::HandleGetSceneList(WSRequestHandler* req) {
|
||||||
OBSSourceAutoRelease currentScene = obs_frontend_get_current_scene();
|
OBSSourceAutoRelease currentScene = obs_frontend_get_current_scene();
|
||||||
OBSDataArrayAutoRelease scenes = Utils::GetScenes();
|
OBSDataArrayAutoRelease scenes = Utils::GetScenes();
|
||||||
|
|
||||||
OBSDataAutoRelease data = obs_data_create();
|
OBSDataAutoRelease data = obs_data_create();
|
||||||
obs_data_set_string(data, "current-scene",
|
obs_data_set_string(data, "current-scene",
|
||||||
obs_source_get_name(currentScene));
|
obs_source_get_name(currentScene));
|
||||||
obs_data_set_array(data, "scenes", scenes);
|
obs_data_set_array(data, "scenes", scenes);
|
||||||
|
|
||||||
req->SendOKResponse(data);
|
req->SendOKResponse(data);
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -21,25 +21,25 @@
|
|||||||
* @since 0.3
|
* @since 0.3
|
||||||
*/
|
*/
|
||||||
void WSRequestHandler::HandleGetStreamingStatus(WSRequestHandler* req) {
|
void WSRequestHandler::HandleGetStreamingStatus(WSRequestHandler* req) {
|
||||||
OBSDataAutoRelease data = obs_data_create();
|
OBSDataAutoRelease data = obs_data_create();
|
||||||
obs_data_set_bool(data, "streaming", obs_frontend_streaming_active());
|
obs_data_set_bool(data, "streaming", obs_frontend_streaming_active());
|
||||||
obs_data_set_bool(data, "recording", obs_frontend_recording_active());
|
obs_data_set_bool(data, "recording", obs_frontend_recording_active());
|
||||||
obs_data_set_bool(data, "preview-only", false);
|
obs_data_set_bool(data, "preview-only", false);
|
||||||
|
|
||||||
const char* tc = nullptr;
|
const char* tc = nullptr;
|
||||||
if (obs_frontend_streaming_active()) {
|
if (obs_frontend_streaming_active()) {
|
||||||
tc = WSEvents::Instance->GetStreamingTimecode();
|
tc = WSEvents::Instance->GetStreamingTimecode();
|
||||||
obs_data_set_string(data, "stream-timecode", tc);
|
obs_data_set_string(data, "stream-timecode", tc);
|
||||||
bfree((void*)tc);
|
bfree((void*)tc);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obs_frontend_recording_active()) {
|
if (obs_frontend_recording_active()) {
|
||||||
tc = WSEvents::Instance->GetRecordingTimecode();
|
tc = WSEvents::Instance->GetRecordingTimecode();
|
||||||
obs_data_set_string(data, "rec-timecode", tc);
|
obs_data_set_string(data, "rec-timecode", tc);
|
||||||
bfree((void*)tc);
|
bfree((void*)tc);
|
||||||
}
|
}
|
||||||
|
|
||||||
req->SendOKResponse(data);
|
req->SendOKResponse(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -51,10 +51,10 @@
|
|||||||
* @since 0.3
|
* @since 0.3
|
||||||
*/
|
*/
|
||||||
void WSRequestHandler::HandleStartStopStreaming(WSRequestHandler* req) {
|
void WSRequestHandler::HandleStartStopStreaming(WSRequestHandler* req) {
|
||||||
if (obs_frontend_streaming_active())
|
if (obs_frontend_streaming_active())
|
||||||
HandleStopStreaming(req);
|
HandleStopStreaming(req);
|
||||||
else
|
else
|
||||||
HandleStartStreaming(req);
|
HandleStartStreaming(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -77,90 +77,90 @@
|
|||||||
* @since 4.1.0
|
* @since 4.1.0
|
||||||
*/
|
*/
|
||||||
void WSRequestHandler::HandleStartStreaming(WSRequestHandler* req) {
|
void WSRequestHandler::HandleStartStreaming(WSRequestHandler* req) {
|
||||||
if (obs_frontend_streaming_active() == false) {
|
if (obs_frontend_streaming_active() == false) {
|
||||||
OBSService configuredService = obs_frontend_get_streaming_service();
|
OBSService configuredService = obs_frontend_get_streaming_service();
|
||||||
OBSService newService = nullptr;
|
OBSService newService = nullptr;
|
||||||
|
|
||||||
// TODO: fix service memory leak
|
// TODO: fix service memory leak
|
||||||
|
|
||||||
if (req->hasField("stream")) {
|
if (req->hasField("stream")) {
|
||||||
OBSDataAutoRelease streamData = obs_data_get_obj(req->data, "stream");
|
OBSDataAutoRelease streamData = obs_data_get_obj(req->data, "stream");
|
||||||
OBSDataAutoRelease newSettings = obs_data_get_obj(streamData, "settings");
|
OBSDataAutoRelease newSettings = obs_data_get_obj(streamData, "settings");
|
||||||
OBSDataAutoRelease newMetadata = obs_data_get_obj(streamData, "metadata");
|
OBSDataAutoRelease newMetadata = obs_data_get_obj(streamData, "metadata");
|
||||||
|
|
||||||
OBSDataAutoRelease csHotkeys =
|
OBSDataAutoRelease csHotkeys =
|
||||||
obs_hotkeys_save_service(configuredService);
|
obs_hotkeys_save_service(configuredService);
|
||||||
|
|
||||||
QString currentType = obs_service_get_type(configuredService);
|
QString currentType = obs_service_get_type(configuredService);
|
||||||
QString newType = obs_data_get_string(streamData, "type");
|
QString newType = obs_data_get_string(streamData, "type");
|
||||||
if (newType.isEmpty() || newType.isNull()) {
|
if (newType.isEmpty() || newType.isNull()) {
|
||||||
newType = currentType;
|
newType = currentType;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Supporting adding metadata parameters to key query string
|
//Supporting adding metadata parameters to key query string
|
||||||
QString query = Utils::ParseDataToQueryString(newMetadata);
|
QString query = Utils::ParseDataToQueryString(newMetadata);
|
||||||
if (!query.isEmpty()
|
if (!query.isEmpty()
|
||||||
&& obs_data_has_user_value(newSettings, "key"))
|
&& obs_data_has_user_value(newSettings, "key"))
|
||||||
{
|
{
|
||||||
const char* key = obs_data_get_string(newSettings, "key");
|
const char* key = obs_data_get_string(newSettings, "key");
|
||||||
int keylen = strlen(key);
|
int keylen = strlen(key);
|
||||||
|
|
||||||
bool hasQuestionMark = false;
|
bool hasQuestionMark = false;
|
||||||
for (int i = 0; i < keylen; i++) {
|
for (int i = 0; i < keylen; i++) {
|
||||||
if (key[i] == '?') {
|
if (key[i] == '?') {
|
||||||
hasQuestionMark = true;
|
hasQuestionMark = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasQuestionMark) {
|
if (hasQuestionMark) {
|
||||||
query.prepend('&');
|
query.prepend('&');
|
||||||
} else {
|
} else {
|
||||||
query.prepend('?');
|
query.prepend('?');
|
||||||
}
|
}
|
||||||
|
|
||||||
query.prepend(key);
|
query.prepend(key);
|
||||||
obs_data_set_string(newSettings, "key", query.toUtf8());
|
obs_data_set_string(newSettings, "key", query.toUtf8());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newType == currentType) {
|
if (newType == currentType) {
|
||||||
// Service type doesn't change: apply settings to current service
|
// Service type doesn't change: apply settings to current service
|
||||||
|
|
||||||
// By doing this, you can send a request to the websocket
|
// By doing this, you can send a request to the websocket
|
||||||
// that only contains settings you want to change, instead of
|
// that only contains settings you want to change, instead of
|
||||||
// having to do a get and then change them
|
// having to do a get and then change them
|
||||||
|
|
||||||
OBSDataAutoRelease currentSettings = obs_service_get_settings(configuredService);
|
OBSDataAutoRelease currentSettings = obs_service_get_settings(configuredService);
|
||||||
OBSDataAutoRelease updatedSettings = obs_data_create();
|
OBSDataAutoRelease updatedSettings = obs_data_create();
|
||||||
|
|
||||||
obs_data_apply(updatedSettings, currentSettings); //first apply the existing settings
|
obs_data_apply(updatedSettings, currentSettings); //first apply the existing settings
|
||||||
obs_data_apply(updatedSettings, newSettings); //then apply the settings from the request should they exist
|
obs_data_apply(updatedSettings, newSettings); //then apply the settings from the request should they exist
|
||||||
|
|
||||||
newService = obs_service_create(
|
newService = obs_service_create(
|
||||||
newType.toUtf8(), STREAM_SERVICE_ID,
|
newType.toUtf8(), STREAM_SERVICE_ID,
|
||||||
updatedSettings, csHotkeys);
|
updatedSettings, csHotkeys);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Service type changed: override service settings
|
// Service type changed: override service settings
|
||||||
newService = obs_service_create(
|
newService = obs_service_create(
|
||||||
newType.toUtf8(), STREAM_SERVICE_ID,
|
newType.toUtf8(), STREAM_SERVICE_ID,
|
||||||
newSettings, csHotkeys);
|
newSettings, csHotkeys);
|
||||||
}
|
}
|
||||||
|
|
||||||
obs_frontend_set_streaming_service(newService);
|
obs_frontend_set_streaming_service(newService);
|
||||||
}
|
}
|
||||||
|
|
||||||
obs_frontend_streaming_start();
|
obs_frontend_streaming_start();
|
||||||
|
|
||||||
// Stream settings provided in StartStreaming are not persisted to disk
|
// Stream settings provided in StartStreaming are not persisted to disk
|
||||||
if (newService != nullptr) {
|
if (newService != nullptr) {
|
||||||
obs_frontend_set_streaming_service(configuredService);
|
obs_frontend_set_streaming_service(configuredService);
|
||||||
}
|
}
|
||||||
|
|
||||||
req->SendOKResponse();
|
req->SendOKResponse();
|
||||||
} else {
|
} else {
|
||||||
req->SendErrorResponse("streaming already active");
|
req->SendErrorResponse("streaming already active");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -173,12 +173,12 @@
|
|||||||
* @since 4.1.0
|
* @since 4.1.0
|
||||||
*/
|
*/
|
||||||
void WSRequestHandler::HandleStopStreaming(WSRequestHandler* req) {
|
void WSRequestHandler::HandleStopStreaming(WSRequestHandler* req) {
|
||||||
if (obs_frontend_streaming_active() == true) {
|
if (obs_frontend_streaming_active() == true) {
|
||||||
obs_frontend_streaming_stop();
|
obs_frontend_streaming_stop();
|
||||||
req->SendOKResponse();
|
req->SendOKResponse();
|
||||||
} else {
|
} else {
|
||||||
req->SendErrorResponse("streaming not active");
|
req->SendErrorResponse("streaming not active");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -199,50 +199,50 @@ void WSRequestHandler::HandleStopStreaming(WSRequestHandler* req) {
|
|||||||
* @since 4.1.0
|
* @since 4.1.0
|
||||||
*/
|
*/
|
||||||
void WSRequestHandler::HandleSetStreamSettings(WSRequestHandler* req) {
|
void WSRequestHandler::HandleSetStreamSettings(WSRequestHandler* req) {
|
||||||
OBSService service = obs_frontend_get_streaming_service();
|
OBSService service = obs_frontend_get_streaming_service();
|
||||||
|
|
||||||
OBSDataAutoRelease requestSettings = obs_data_get_obj(req->data, "settings");
|
OBSDataAutoRelease requestSettings = obs_data_get_obj(req->data, "settings");
|
||||||
if (!requestSettings) {
|
if (!requestSettings) {
|
||||||
req->SendErrorResponse("'settings' are required'");
|
req->SendErrorResponse("'settings' are required'");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString serviceType = obs_service_get_type(service);
|
QString serviceType = obs_service_get_type(service);
|
||||||
QString requestedType = obs_data_get_string(req->data, "type");
|
QString requestedType = obs_data_get_string(req->data, "type");
|
||||||
|
|
||||||
if (requestedType != nullptr && requestedType != serviceType) {
|
if (requestedType != nullptr && requestedType != serviceType) {
|
||||||
OBSDataAutoRelease hotkeys = obs_hotkeys_save_service(service);
|
OBSDataAutoRelease hotkeys = obs_hotkeys_save_service(service);
|
||||||
service = obs_service_create(
|
service = obs_service_create(
|
||||||
requestedType.toUtf8(), STREAM_SERVICE_ID, requestSettings, hotkeys);
|
requestedType.toUtf8(), STREAM_SERVICE_ID, requestSettings, hotkeys);
|
||||||
} else {
|
} else {
|
||||||
// If type isn't changing, we should overlay the settings we got
|
// If type isn't changing, we should overlay the settings we got
|
||||||
// to the existing settings. By doing so, you can send a request that
|
// to the existing settings. By doing so, you can send a request that
|
||||||
// only contains the settings you want to change, instead of having to
|
// only contains the settings you want to change, instead of having to
|
||||||
// do a get and then change them
|
// do a get and then change them
|
||||||
|
|
||||||
OBSDataAutoRelease existingSettings = obs_service_get_settings(service);
|
OBSDataAutoRelease existingSettings = obs_service_get_settings(service);
|
||||||
OBSDataAutoRelease newSettings = obs_data_create();
|
OBSDataAutoRelease newSettings = obs_data_create();
|
||||||
|
|
||||||
// Apply existing settings
|
// Apply existing settings
|
||||||
obs_data_apply(newSettings, existingSettings);
|
obs_data_apply(newSettings, existingSettings);
|
||||||
// Then apply the settings from the request
|
// Then apply the settings from the request
|
||||||
obs_data_apply(newSettings, requestSettings);
|
obs_data_apply(newSettings, requestSettings);
|
||||||
|
|
||||||
obs_service_update(service, newSettings);
|
obs_service_update(service, newSettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
//if save is specified we should immediately save the streaming service
|
//if save is specified we should immediately save the streaming service
|
||||||
if (obs_data_get_bool(req->data, "save")) {
|
if (obs_data_get_bool(req->data, "save")) {
|
||||||
obs_frontend_save_streaming_service();
|
obs_frontend_save_streaming_service();
|
||||||
}
|
}
|
||||||
|
|
||||||
OBSDataAutoRelease serviceSettings = obs_service_get_settings(service);
|
OBSDataAutoRelease serviceSettings = obs_service_get_settings(service);
|
||||||
|
|
||||||
OBSDataAutoRelease response = obs_data_create();
|
OBSDataAutoRelease response = obs_data_create();
|
||||||
obs_data_set_string(response, "type", requestedType.toUtf8());
|
obs_data_set_string(response, "type", requestedType.toUtf8());
|
||||||
obs_data_set_obj(response, "settings", serviceSettings);
|
obs_data_set_obj(response, "settings", serviceSettings);
|
||||||
|
|
||||||
req->SendOKResponse(response);
|
req->SendOKResponse(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -262,16 +262,16 @@ void WSRequestHandler::HandleStopStreaming(WSRequestHandler* req) {
|
|||||||
* @since 4.1.0
|
* @since 4.1.0
|
||||||
*/
|
*/
|
||||||
void WSRequestHandler::HandleGetStreamSettings(WSRequestHandler* req) {
|
void WSRequestHandler::HandleGetStreamSettings(WSRequestHandler* req) {
|
||||||
OBSService service = obs_frontend_get_streaming_service();
|
OBSService service = obs_frontend_get_streaming_service();
|
||||||
|
|
||||||
const char* serviceType = obs_service_get_type(service);
|
const char* serviceType = obs_service_get_type(service);
|
||||||
OBSDataAutoRelease settings = obs_service_get_settings(service);
|
OBSDataAutoRelease settings = obs_service_get_settings(service);
|
||||||
|
|
||||||
OBSDataAutoRelease response = obs_data_create();
|
OBSDataAutoRelease response = obs_data_create();
|
||||||
obs_data_set_string(response, "type", serviceType);
|
obs_data_set_string(response, "type", serviceType);
|
||||||
obs_data_set_obj(response, "settings", settings);
|
obs_data_set_obj(response, "settings", settings);
|
||||||
|
|
||||||
req->SendOKResponse(response);
|
req->SendOKResponse(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -283,6 +283,6 @@ void WSRequestHandler::HandleGetStreamSettings(WSRequestHandler* req) {
|
|||||||
* @since 4.1.0
|
* @since 4.1.0
|
||||||
*/
|
*/
|
||||||
void WSRequestHandler::HandleSaveStreamSettings(WSRequestHandler* req) {
|
void WSRequestHandler::HandleSaveStreamSettings(WSRequestHandler* req) {
|
||||||
obs_frontend_save_streaming_service();
|
obs_frontend_save_streaming_service();
|
||||||
req->SendOKResponse();
|
req->SendOKResponse();
|
||||||
}
|
}
|
||||||
|
@ -14,12 +14,12 @@
|
|||||||
* @since 4.1.0
|
* @since 4.1.0
|
||||||
*/
|
*/
|
||||||
void WSRequestHandler::HandleGetStudioModeStatus(WSRequestHandler* req) {
|
void WSRequestHandler::HandleGetStudioModeStatus(WSRequestHandler* req) {
|
||||||
bool previewActive = obs_frontend_preview_program_mode_active();
|
bool previewActive = obs_frontend_preview_program_mode_active();
|
||||||
|
|
||||||
OBSDataAutoRelease response = obs_data_create();
|
OBSDataAutoRelease response = obs_data_create();
|
||||||
obs_data_set_bool(response, "studio-mode", previewActive);
|
obs_data_set_bool(response, "studio-mode", previewActive);
|
||||||
|
|
||||||
req->SendOKResponse(response);
|
req->SendOKResponse(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -35,19 +35,19 @@
|
|||||||
* @since 4.1.0
|
* @since 4.1.0
|
||||||
*/
|
*/
|
||||||
void WSRequestHandler::HandleGetPreviewScene(WSRequestHandler* req) {
|
void WSRequestHandler::HandleGetPreviewScene(WSRequestHandler* req) {
|
||||||
if (!obs_frontend_preview_program_mode_active()) {
|
if (!obs_frontend_preview_program_mode_active()) {
|
||||||
req->SendErrorResponse("studio mode not enabled");
|
req->SendErrorResponse("studio mode not enabled");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
OBSSourceAutoRelease scene = obs_frontend_get_current_preview_scene();
|
OBSSourceAutoRelease scene = obs_frontend_get_current_preview_scene();
|
||||||
OBSDataArrayAutoRelease sceneItems = Utils::GetSceneItems(scene);
|
OBSDataArrayAutoRelease sceneItems = Utils::GetSceneItems(scene);
|
||||||
|
|
||||||
OBSDataAutoRelease data = obs_data_create();
|
OBSDataAutoRelease data = obs_data_create();
|
||||||
obs_data_set_string(data, "name", obs_source_get_name(scene));
|
obs_data_set_string(data, "name", obs_source_get_name(scene));
|
||||||
obs_data_set_array(data, "sources", sceneItems);
|
obs_data_set_array(data, "sources", sceneItems);
|
||||||
|
|
||||||
req->SendOKResponse(data);
|
req->SendOKResponse(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -62,25 +62,25 @@ void WSRequestHandler::HandleGetPreviewScene(WSRequestHandler* req) {
|
|||||||
* @since 4.1.0
|
* @since 4.1.0
|
||||||
*/
|
*/
|
||||||
void WSRequestHandler::HandleSetPreviewScene(WSRequestHandler* req) {
|
void WSRequestHandler::HandleSetPreviewScene(WSRequestHandler* req) {
|
||||||
if (!obs_frontend_preview_program_mode_active()) {
|
if (!obs_frontend_preview_program_mode_active()) {
|
||||||
req->SendErrorResponse("studio mode not enabled");
|
req->SendErrorResponse("studio mode not enabled");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!req->hasField("scene-name")) {
|
if (!req->hasField("scene-name")) {
|
||||||
req->SendErrorResponse("missing request parameters");
|
req->SendErrorResponse("missing request parameters");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* scene_name = obs_data_get_string(req->data, "scene-name");
|
const char* scene_name = obs_data_get_string(req->data, "scene-name");
|
||||||
OBSSourceAutoRelease scene = Utils::GetSceneFromNameOrCurrent(scene_name);
|
OBSSourceAutoRelease scene = Utils::GetSceneFromNameOrCurrent(scene_name);
|
||||||
|
|
||||||
if (scene) {
|
if (scene) {
|
||||||
obs_frontend_set_current_preview_scene(scene);
|
obs_frontend_set_current_preview_scene(scene);
|
||||||
req->SendOKResponse();
|
req->SendOKResponse();
|
||||||
} else {
|
} else {
|
||||||
req->SendErrorResponse("specified scene doesn't exist");
|
req->SendErrorResponse("specified scene doesn't exist");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -97,39 +97,39 @@ void WSRequestHandler::HandleSetPreviewScene(WSRequestHandler* req) {
|
|||||||
* @since 4.1.0
|
* @since 4.1.0
|
||||||
*/
|
*/
|
||||||
void WSRequestHandler::HandleTransitionToProgram(WSRequestHandler* req) {
|
void WSRequestHandler::HandleTransitionToProgram(WSRequestHandler* req) {
|
||||||
if (!obs_frontend_preview_program_mode_active()) {
|
if (!obs_frontend_preview_program_mode_active()) {
|
||||||
req->SendErrorResponse("studio mode not enabled");
|
req->SendErrorResponse("studio mode not enabled");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (req->hasField("with-transition")) {
|
if (req->hasField("with-transition")) {
|
||||||
OBSDataAutoRelease transitionInfo =
|
OBSDataAutoRelease transitionInfo =
|
||||||
obs_data_get_obj(req->data, "with-transition");
|
obs_data_get_obj(req->data, "with-transition");
|
||||||
|
|
||||||
if (obs_data_has_user_value(transitionInfo, "name")) {
|
if (obs_data_has_user_value(transitionInfo, "name")) {
|
||||||
QString transitionName =
|
QString transitionName =
|
||||||
obs_data_get_string(transitionInfo, "name");
|
obs_data_get_string(transitionInfo, "name");
|
||||||
if (transitionName.isEmpty()) {
|
if (transitionName.isEmpty()) {
|
||||||
req->SendErrorResponse("invalid request parameters");
|
req->SendErrorResponse("invalid request parameters");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool success = Utils::SetTransitionByName(transitionName);
|
bool success = Utils::SetTransitionByName(transitionName);
|
||||||
if (!success) {
|
if (!success) {
|
||||||
req->SendErrorResponse("specified transition doesn't exist");
|
req->SendErrorResponse("specified transition doesn't exist");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obs_data_has_user_value(transitionInfo, "duration")) {
|
if (obs_data_has_user_value(transitionInfo, "duration")) {
|
||||||
int transitionDuration =
|
int transitionDuration =
|
||||||
obs_data_get_int(transitionInfo, "duration");
|
obs_data_get_int(transitionInfo, "duration");
|
||||||
Utils::SetTransitionDuration(transitionDuration);
|
Utils::SetTransitionDuration(transitionDuration);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Utils::TransitionToProgram();
|
Utils::TransitionToProgram();
|
||||||
req->SendOKResponse();
|
req->SendOKResponse();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -141,8 +141,8 @@ void WSRequestHandler::HandleTransitionToProgram(WSRequestHandler* req) {
|
|||||||
* @since 4.1.0
|
* @since 4.1.0
|
||||||
*/
|
*/
|
||||||
void WSRequestHandler::HandleEnableStudioMode(WSRequestHandler* req) {
|
void WSRequestHandler::HandleEnableStudioMode(WSRequestHandler* req) {
|
||||||
obs_frontend_set_preview_program_mode(true);
|
obs_frontend_set_preview_program_mode(true);
|
||||||
req->SendOKResponse();
|
req->SendOKResponse();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -154,8 +154,8 @@ void WSRequestHandler::HandleEnableStudioMode(WSRequestHandler* req) {
|
|||||||
* @since 4.1.0
|
* @since 4.1.0
|
||||||
*/
|
*/
|
||||||
void WSRequestHandler::HandleDisableStudioMode(WSRequestHandler* req) {
|
void WSRequestHandler::HandleDisableStudioMode(WSRequestHandler* req) {
|
||||||
obs_frontend_set_preview_program_mode(false);
|
obs_frontend_set_preview_program_mode(false);
|
||||||
req->SendOKResponse();
|
req->SendOKResponse();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -167,7 +167,7 @@ void WSRequestHandler::HandleDisableStudioMode(WSRequestHandler* req) {
|
|||||||
* @since 4.1.0
|
* @since 4.1.0
|
||||||
*/
|
*/
|
||||||
void WSRequestHandler::HandleToggleStudioMode(WSRequestHandler* req) {
|
void WSRequestHandler::HandleToggleStudioMode(WSRequestHandler* req) {
|
||||||
bool previewProgramMode = obs_frontend_preview_program_mode_active();
|
bool previewProgramMode = obs_frontend_preview_program_mode_active();
|
||||||
obs_frontend_set_preview_program_mode(!previewProgramMode);
|
obs_frontend_set_preview_program_mode(!previewProgramMode);
|
||||||
req->SendOKResponse();
|
req->SendOKResponse();
|
||||||
}
|
}
|
||||||
|
@ -16,26 +16,26 @@
|
|||||||
* @since 4.1.0
|
* @since 4.1.0
|
||||||
*/
|
*/
|
||||||
void WSRequestHandler::HandleGetTransitionList(WSRequestHandler* req) {
|
void WSRequestHandler::HandleGetTransitionList(WSRequestHandler* req) {
|
||||||
OBSSourceAutoRelease currentTransition = obs_frontend_get_current_transition();
|
OBSSourceAutoRelease currentTransition = obs_frontend_get_current_transition();
|
||||||
obs_frontend_source_list transitionList = {};
|
obs_frontend_source_list transitionList = {};
|
||||||
obs_frontend_get_transitions(&transitionList);
|
obs_frontend_get_transitions(&transitionList);
|
||||||
|
|
||||||
OBSDataArrayAutoRelease transitions = obs_data_array_create();
|
OBSDataArrayAutoRelease transitions = obs_data_array_create();
|
||||||
for (size_t i = 0; i < transitionList.sources.num; i++) {
|
for (size_t i = 0; i < transitionList.sources.num; i++) {
|
||||||
OBSSource transition = transitionList.sources.array[i];
|
OBSSource transition = transitionList.sources.array[i];
|
||||||
|
|
||||||
OBSDataAutoRelease obj = obs_data_create();
|
OBSDataAutoRelease obj = obs_data_create();
|
||||||
obs_data_set_string(obj, "name", obs_source_get_name(transition));
|
obs_data_set_string(obj, "name", obs_source_get_name(transition));
|
||||||
obs_data_array_push_back(transitions, obj);
|
obs_data_array_push_back(transitions, obj);
|
||||||
}
|
}
|
||||||
obs_frontend_source_list_free(&transitionList);
|
obs_frontend_source_list_free(&transitionList);
|
||||||
|
|
||||||
OBSDataAutoRelease response = obs_data_create();
|
OBSDataAutoRelease response = obs_data_create();
|
||||||
obs_data_set_string(response, "current-transition",
|
obs_data_set_string(response, "current-transition",
|
||||||
obs_source_get_name(currentTransition));
|
obs_source_get_name(currentTransition));
|
||||||
obs_data_set_array(response, "transitions", transitions);
|
obs_data_set_array(response, "transitions", transitions);
|
||||||
|
|
||||||
req->SendOKResponse(response);
|
req->SendOKResponse(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -50,16 +50,16 @@
|
|||||||
* @since 0.3
|
* @since 0.3
|
||||||
*/
|
*/
|
||||||
void WSRequestHandler::HandleGetCurrentTransition(WSRequestHandler* req) {
|
void WSRequestHandler::HandleGetCurrentTransition(WSRequestHandler* req) {
|
||||||
OBSSourceAutoRelease currentTransition = obs_frontend_get_current_transition();
|
OBSSourceAutoRelease currentTransition = obs_frontend_get_current_transition();
|
||||||
|
|
||||||
OBSDataAutoRelease response = obs_data_create();
|
OBSDataAutoRelease response = obs_data_create();
|
||||||
obs_data_set_string(response, "name",
|
obs_data_set_string(response, "name",
|
||||||
obs_source_get_name(currentTransition));
|
obs_source_get_name(currentTransition));
|
||||||
|
|
||||||
if (!obs_transition_fixed(currentTransition))
|
if (!obs_transition_fixed(currentTransition))
|
||||||
obs_data_set_int(response, "duration", Utils::GetTransitionDuration());
|
obs_data_set_int(response, "duration", Utils::GetTransitionDuration());
|
||||||
|
|
||||||
req->SendOKResponse(response);
|
req->SendOKResponse(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -73,17 +73,17 @@ void WSRequestHandler::HandleGetCurrentTransition(WSRequestHandler* req) {
|
|||||||
* @since 0.3
|
* @since 0.3
|
||||||
*/
|
*/
|
||||||
void WSRequestHandler::HandleSetCurrentTransition(WSRequestHandler* req) {
|
void WSRequestHandler::HandleSetCurrentTransition(WSRequestHandler* req) {
|
||||||
if (!req->hasField("transition-name")) {
|
if (!req->hasField("transition-name")) {
|
||||||
req->SendErrorResponse("missing request parameters");
|
req->SendErrorResponse("missing request parameters");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString name = obs_data_get_string(req->data, "transition-name");
|
QString name = obs_data_get_string(req->data, "transition-name");
|
||||||
bool success = Utils::SetTransitionByName(name);
|
bool success = Utils::SetTransitionByName(name);
|
||||||
if (success)
|
if (success)
|
||||||
req->SendOKResponse();
|
req->SendOKResponse();
|
||||||
else
|
else
|
||||||
req->SendErrorResponse("requested transition does not exist");
|
req->SendErrorResponse("requested transition does not exist");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -97,14 +97,14 @@ void WSRequestHandler::HandleSetCurrentTransition(WSRequestHandler* req) {
|
|||||||
* @since 4.0.0
|
* @since 4.0.0
|
||||||
*/
|
*/
|
||||||
void WSRequestHandler::HandleSetTransitionDuration(WSRequestHandler* req) {
|
void WSRequestHandler::HandleSetTransitionDuration(WSRequestHandler* req) {
|
||||||
if (!req->hasField("duration")) {
|
if (!req->hasField("duration")) {
|
||||||
req->SendErrorResponse("missing request parameters");
|
req->SendErrorResponse("missing request parameters");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ms = obs_data_get_int(req->data, "duration");
|
int ms = obs_data_get_int(req->data, "duration");
|
||||||
Utils::SetTransitionDuration(ms);
|
Utils::SetTransitionDuration(ms);
|
||||||
req->SendOKResponse();
|
req->SendOKResponse();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -118,9 +118,9 @@ void WSRequestHandler::HandleSetTransitionDuration(WSRequestHandler* req) {
|
|||||||
* @since 4.1.0
|
* @since 4.1.0
|
||||||
*/
|
*/
|
||||||
void WSRequestHandler::HandleGetTransitionDuration(WSRequestHandler* req) {
|
void WSRequestHandler::HandleGetTransitionDuration(WSRequestHandler* req) {
|
||||||
OBSDataAutoRelease response = obs_data_create();
|
OBSDataAutoRelease response = obs_data_create();
|
||||||
obs_data_set_int(response, "transition-duration",
|
obs_data_set_int(response, "transition-duration",
|
||||||
Utils::GetTransitionDuration());
|
Utils::GetTransitionDuration());
|
||||||
|
|
||||||
req->SendOKResponse(response);
|
req->SendOKResponse(response);
|
||||||
}
|
}
|
||||||
|
180
src/WSServer.cpp
180
src/WSServer.cpp
@ -33,136 +33,136 @@ QT_USE_NAMESPACE
|
|||||||
WSServer* WSServer::Instance = nullptr;
|
WSServer* WSServer::Instance = nullptr;
|
||||||
|
|
||||||
WSServer::WSServer(QObject* parent)
|
WSServer::WSServer(QObject* parent)
|
||||||
: QObject(parent),
|
: QObject(parent),
|
||||||
_wsServer(Q_NULLPTR),
|
_wsServer(Q_NULLPTR),
|
||||||
_clients(),
|
_clients(),
|
||||||
_clMutex(QMutex::Recursive)
|
_clMutex(QMutex::Recursive)
|
||||||
{
|
{
|
||||||
_wsServer = new QWebSocketServer(
|
_wsServer = new QWebSocketServer(
|
||||||
QStringLiteral("obs-websocket"),
|
QStringLiteral("obs-websocket"),
|
||||||
QWebSocketServer::NonSecureMode);
|
QWebSocketServer::NonSecureMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
WSServer::~WSServer() {
|
WSServer::~WSServer() {
|
||||||
Stop();
|
Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WSServer::Start(quint16 port) {
|
void WSServer::Start(quint16 port) {
|
||||||
if (port == _wsServer->serverPort())
|
if (port == _wsServer->serverPort())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(_wsServer->isListening())
|
if(_wsServer->isListening())
|
||||||
Stop();
|
Stop();
|
||||||
|
|
||||||
bool serverStarted = _wsServer->listen(QHostAddress::Any, port);
|
bool serverStarted = _wsServer->listen(QHostAddress::Any, port);
|
||||||
if (serverStarted) {
|
if (serverStarted) {
|
||||||
blog(LOG_INFO, "server started successfully on TCP port %d", port);
|
blog(LOG_INFO, "server started successfully on TCP port %d", port);
|
||||||
|
|
||||||
connect(_wsServer, SIGNAL(newConnection()),
|
connect(_wsServer, SIGNAL(newConnection()),
|
||||||
this, SLOT(onNewConnection()));
|
this, SLOT(onNewConnection()));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
QString errorString = _wsServer->errorString();
|
QString errorString = _wsServer->errorString();
|
||||||
blog(LOG_ERROR,
|
blog(LOG_ERROR,
|
||||||
"error: failed to start server on TCP port %d: %s",
|
"error: failed to start server on TCP port %d: %s",
|
||||||
port, errorString.toUtf8().constData());
|
port, errorString.toUtf8().constData());
|
||||||
|
|
||||||
QMainWindow* mainWindow = (QMainWindow*)obs_frontend_get_main_window();
|
QMainWindow* mainWindow = (QMainWindow*)obs_frontend_get_main_window();
|
||||||
|
|
||||||
obs_frontend_push_ui_translation(obs_module_get_string);
|
obs_frontend_push_ui_translation(obs_module_get_string);
|
||||||
QString title = tr("OBSWebsocket.Server.StartFailed.Title");
|
QString title = tr("OBSWebsocket.Server.StartFailed.Title");
|
||||||
QString msg = tr("OBSWebsocket.Server.StartFailed.Message").arg(port);
|
QString msg = tr("OBSWebsocket.Server.StartFailed.Message").arg(port);
|
||||||
obs_frontend_pop_ui_translation();
|
obs_frontend_pop_ui_translation();
|
||||||
|
|
||||||
QMessageBox::warning(mainWindow, title, msg);
|
QMessageBox::warning(mainWindow, title, msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WSServer::Stop() {
|
void WSServer::Stop() {
|
||||||
QMutexLocker locker(&_clMutex);
|
QMutexLocker locker(&_clMutex);
|
||||||
for(QWebSocket* pClient : _clients) {
|
for(QWebSocket* pClient : _clients) {
|
||||||
pClient->close();
|
pClient->close();
|
||||||
}
|
}
|
||||||
locker.unlock();
|
locker.unlock();
|
||||||
|
|
||||||
_wsServer->close();
|
_wsServer->close();
|
||||||
|
|
||||||
blog(LOG_INFO, "server stopped successfully");
|
blog(LOG_INFO, "server stopped successfully");
|
||||||
}
|
}
|
||||||
|
|
||||||
void WSServer::broadcast(QString message) {
|
void WSServer::broadcast(QString message) {
|
||||||
QMutexLocker locker(&_clMutex);
|
QMutexLocker locker(&_clMutex);
|
||||||
for(QWebSocket* pClient : _clients) {
|
for(QWebSocket* pClient : _clients) {
|
||||||
if (Config::Current()->AuthRequired
|
if (Config::Current()->AuthRequired
|
||||||
&& (pClient->property(PROP_AUTHENTICATED).toBool() == false)) {
|
&& (pClient->property(PROP_AUTHENTICATED).toBool() == false)) {
|
||||||
// Skip this client if unauthenticated
|
// Skip this client if unauthenticated
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
pClient->sendTextMessage(message);
|
pClient->sendTextMessage(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WSServer::onNewConnection() {
|
void WSServer::onNewConnection() {
|
||||||
QWebSocket* pSocket = _wsServer->nextPendingConnection();
|
QWebSocket* pSocket = _wsServer->nextPendingConnection();
|
||||||
if (pSocket) {
|
if (pSocket) {
|
||||||
connect(pSocket, SIGNAL(textMessageReceived(const QString&)),
|
connect(pSocket, SIGNAL(textMessageReceived(const QString&)),
|
||||||
this, SLOT(onTextMessageReceived(QString)));
|
this, SLOT(onTextMessageReceived(QString)));
|
||||||
connect(pSocket, SIGNAL(disconnected()),
|
connect(pSocket, SIGNAL(disconnected()),
|
||||||
this, SLOT(onSocketDisconnected()));
|
this, SLOT(onSocketDisconnected()));
|
||||||
|
|
||||||
pSocket->setProperty(PROP_AUTHENTICATED, false);
|
pSocket->setProperty(PROP_AUTHENTICATED, false);
|
||||||
|
|
||||||
QMutexLocker locker(&_clMutex);
|
QMutexLocker locker(&_clMutex);
|
||||||
_clients << pSocket;
|
_clients << pSocket;
|
||||||
locker.unlock();
|
locker.unlock();
|
||||||
|
|
||||||
QHostAddress clientAddr = pSocket->peerAddress();
|
QHostAddress clientAddr = pSocket->peerAddress();
|
||||||
QString clientIp = Utils::FormatIPAddress(clientAddr);
|
QString clientIp = Utils::FormatIPAddress(clientAddr);
|
||||||
|
|
||||||
blog(LOG_INFO, "new client connection from %s:%d",
|
blog(LOG_INFO, "new client connection from %s:%d",
|
||||||
clientIp.toUtf8().constData(), pSocket->peerPort());
|
clientIp.toUtf8().constData(), pSocket->peerPort());
|
||||||
|
|
||||||
obs_frontend_push_ui_translation(obs_module_get_string);
|
obs_frontend_push_ui_translation(obs_module_get_string);
|
||||||
QString title = tr("OBSWebsocket.NotifyConnect.Title");
|
QString title = tr("OBSWebsocket.NotifyConnect.Title");
|
||||||
QString msg = tr("OBSWebsocket.NotifyConnect.Message")
|
QString msg = tr("OBSWebsocket.NotifyConnect.Message")
|
||||||
.arg(Utils::FormatIPAddress(clientAddr));
|
.arg(Utils::FormatIPAddress(clientAddr));
|
||||||
obs_frontend_pop_ui_translation();
|
obs_frontend_pop_ui_translation();
|
||||||
|
|
||||||
Utils::SysTrayNotify(msg, QSystemTrayIcon::Information, title);
|
Utils::SysTrayNotify(msg, QSystemTrayIcon::Information, title);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WSServer::onTextMessageReceived(QString message) {
|
void WSServer::onTextMessageReceived(QString message) {
|
||||||
QWebSocket* pSocket = qobject_cast<QWebSocket*>(sender());
|
QWebSocket* pSocket = qobject_cast<QWebSocket*>(sender());
|
||||||
if (pSocket) {
|
if (pSocket) {
|
||||||
WSRequestHandler handler(pSocket);
|
WSRequestHandler handler(pSocket);
|
||||||
handler.processIncomingMessage(message);
|
handler.processIncomingMessage(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WSServer::onSocketDisconnected() {
|
void WSServer::onSocketDisconnected() {
|
||||||
QWebSocket* pSocket = qobject_cast<QWebSocket*>(sender());
|
QWebSocket* pSocket = qobject_cast<QWebSocket*>(sender());
|
||||||
if (pSocket) {
|
if (pSocket) {
|
||||||
pSocket->setProperty(PROP_AUTHENTICATED, false);
|
pSocket->setProperty(PROP_AUTHENTICATED, false);
|
||||||
|
|
||||||
QMutexLocker locker(&_clMutex);
|
QMutexLocker locker(&_clMutex);
|
||||||
_clients.removeAll(pSocket);
|
_clients.removeAll(pSocket);
|
||||||
locker.unlock();
|
locker.unlock();
|
||||||
|
|
||||||
pSocket->deleteLater();
|
pSocket->deleteLater();
|
||||||
|
|
||||||
QHostAddress clientAddr = pSocket->peerAddress();
|
QHostAddress clientAddr = pSocket->peerAddress();
|
||||||
QString clientIp = Utils::FormatIPAddress(clientAddr);
|
QString clientIp = Utils::FormatIPAddress(clientAddr);
|
||||||
|
|
||||||
blog(LOG_INFO, "client %s:%d disconnected",
|
blog(LOG_INFO, "client %s:%d disconnected",
|
||||||
clientIp.toUtf8().constData(), pSocket->peerPort());
|
clientIp.toUtf8().constData(), pSocket->peerPort());
|
||||||
|
|
||||||
obs_frontend_push_ui_translation(obs_module_get_string);
|
obs_frontend_push_ui_translation(obs_module_get_string);
|
||||||
QString title = tr("OBSWebsocket.NotifyDisconnect.Title");
|
QString title = tr("OBSWebsocket.NotifyDisconnect.Title");
|
||||||
QString msg = tr("OBSWebsocket.NotifyDisconnect.Message")
|
QString msg = tr("OBSWebsocket.NotifyDisconnect.Message")
|
||||||
.arg(Utils::FormatIPAddress(clientAddr));
|
.arg(Utils::FormatIPAddress(clientAddr));
|
||||||
obs_frontend_pop_ui_translation();
|
obs_frontend_pop_ui_translation();
|
||||||
|
|
||||||
Utils::SysTrayNotify(msg, QSystemTrayIcon::Information, title);
|
Utils::SysTrayNotify(msg, QSystemTrayIcon::Information, title);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,24 +29,24 @@ QT_FORWARD_DECLARE_CLASS(QWebSocketServer)
|
|||||||
QT_FORWARD_DECLARE_CLASS(QWebSocket)
|
QT_FORWARD_DECLARE_CLASS(QWebSocket)
|
||||||
|
|
||||||
class WSServer : public QObject {
|
class WSServer : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit WSServer(QObject* parent = Q_NULLPTR);
|
explicit WSServer(QObject* parent = Q_NULLPTR);
|
||||||
virtual ~WSServer();
|
virtual ~WSServer();
|
||||||
void Start(quint16 port);
|
void Start(quint16 port);
|
||||||
void Stop();
|
void Stop();
|
||||||
void broadcast(QString message);
|
void broadcast(QString message);
|
||||||
static WSServer* Instance;
|
static WSServer* Instance;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onNewConnection();
|
void onNewConnection();
|
||||||
void onTextMessageReceived(QString message);
|
void onTextMessageReceived(QString message);
|
||||||
void onSocketDisconnected();
|
void onSocketDisconnected();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QWebSocketServer* _wsServer;
|
QWebSocketServer* _wsServer;
|
||||||
QList<QWebSocket*> _clients;
|
QList<QWebSocket*> _clients;
|
||||||
QMutex _clMutex;
|
QMutex _clMutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // WSSERVER_H
|
#endif // WSSERVER_H
|
@ -26,79 +26,79 @@ with this program. If not, see <https://www.gnu.org/licenses/>
|
|||||||
#define CHANGE_ME "changeme"
|
#define CHANGE_ME "changeme"
|
||||||
|
|
||||||
SettingsDialog::SettingsDialog(QWidget* parent) :
|
SettingsDialog::SettingsDialog(QWidget* parent) :
|
||||||
QDialog(parent, Qt::Dialog),
|
QDialog(parent, Qt::Dialog),
|
||||||
ui(new Ui::SettingsDialog)
|
ui(new Ui::SettingsDialog)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
connect(ui->authRequired, &QCheckBox::stateChanged,
|
connect(ui->authRequired, &QCheckBox::stateChanged,
|
||||||
this, &SettingsDialog::AuthCheckboxChanged);
|
this, &SettingsDialog::AuthCheckboxChanged);
|
||||||
connect(ui->buttonBox, &QDialogButtonBox::accepted,
|
connect(ui->buttonBox, &QDialogButtonBox::accepted,
|
||||||
this, &SettingsDialog::FormAccepted);
|
this, &SettingsDialog::FormAccepted);
|
||||||
|
|
||||||
|
|
||||||
AuthCheckboxChanged();
|
AuthCheckboxChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingsDialog::showEvent(QShowEvent* event) {
|
void SettingsDialog::showEvent(QShowEvent* event) {
|
||||||
Config* conf = Config::Current();
|
Config* conf = Config::Current();
|
||||||
|
|
||||||
ui->serverEnabled->setChecked(conf->ServerEnabled);
|
ui->serverEnabled->setChecked(conf->ServerEnabled);
|
||||||
ui->serverPort->setValue(conf->ServerPort);
|
ui->serverPort->setValue(conf->ServerPort);
|
||||||
|
|
||||||
ui->debugEnabled->setChecked(conf->DebugEnabled);
|
ui->debugEnabled->setChecked(conf->DebugEnabled);
|
||||||
ui->alertsEnabled->setChecked(conf->AlertsEnabled);
|
ui->alertsEnabled->setChecked(conf->AlertsEnabled);
|
||||||
|
|
||||||
ui->authRequired->setChecked(conf->AuthRequired);
|
ui->authRequired->setChecked(conf->AuthRequired);
|
||||||
ui->password->setText(CHANGE_ME);
|
ui->password->setText(CHANGE_ME);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingsDialog::ToggleShowHide() {
|
void SettingsDialog::ToggleShowHide() {
|
||||||
if (!isVisible())
|
if (!isVisible())
|
||||||
setVisible(true);
|
setVisible(true);
|
||||||
else
|
else
|
||||||
setVisible(false);
|
setVisible(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingsDialog::AuthCheckboxChanged() {
|
void SettingsDialog::AuthCheckboxChanged() {
|
||||||
if (ui->authRequired->isChecked())
|
if (ui->authRequired->isChecked())
|
||||||
ui->password->setEnabled(true);
|
ui->password->setEnabled(true);
|
||||||
else
|
else
|
||||||
ui->password->setEnabled(false);
|
ui->password->setEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingsDialog::FormAccepted() {
|
void SettingsDialog::FormAccepted() {
|
||||||
Config* conf = Config::Current();
|
Config* conf = Config::Current();
|
||||||
|
|
||||||
conf->ServerEnabled = ui->serverEnabled->isChecked();
|
conf->ServerEnabled = ui->serverEnabled->isChecked();
|
||||||
conf->ServerPort = ui->serverPort->value();
|
conf->ServerPort = ui->serverPort->value();
|
||||||
|
|
||||||
conf->DebugEnabled = ui->debugEnabled->isChecked();
|
conf->DebugEnabled = ui->debugEnabled->isChecked();
|
||||||
conf->AlertsEnabled = ui->alertsEnabled->isChecked();
|
conf->AlertsEnabled = ui->alertsEnabled->isChecked();
|
||||||
|
|
||||||
if (ui->authRequired->isChecked()) {
|
if (ui->authRequired->isChecked()) {
|
||||||
if (ui->password->text() != CHANGE_ME) {
|
if (ui->password->text() != CHANGE_ME) {
|
||||||
conf->SetPassword(ui->password->text());
|
conf->SetPassword(ui->password->text());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Config::Current()->Secret.isEmpty())
|
if (!Config::Current()->Secret.isEmpty())
|
||||||
conf->AuthRequired = true;
|
conf->AuthRequired = true;
|
||||||
else
|
else
|
||||||
conf->AuthRequired = false;
|
conf->AuthRequired = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
conf->AuthRequired = false;
|
conf->AuthRequired = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
conf->Save();
|
conf->Save();
|
||||||
|
|
||||||
if (conf->ServerEnabled)
|
if (conf->ServerEnabled)
|
||||||
WSServer::Instance->Start(conf->ServerPort);
|
WSServer::Instance->Start(conf->ServerPort);
|
||||||
else
|
else
|
||||||
WSServer::Instance->Stop();
|
WSServer::Instance->Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
SettingsDialog::~SettingsDialog() {
|
SettingsDialog::~SettingsDialog() {
|
||||||
delete ui;
|
delete ui;
|
||||||
}
|
}
|
||||||
|
@ -25,20 +25,20 @@ with this program. If not, see <https://www.gnu.org/licenses/>
|
|||||||
|
|
||||||
class SettingsDialog : public QDialog
|
class SettingsDialog : public QDialog
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit SettingsDialog(QWidget* parent = 0);
|
explicit SettingsDialog(QWidget* parent = 0);
|
||||||
~SettingsDialog();
|
~SettingsDialog();
|
||||||
void showEvent(QShowEvent* event);
|
void showEvent(QShowEvent* event);
|
||||||
void ToggleShowHide();
|
void ToggleShowHide();
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void AuthCheckboxChanged();
|
void AuthCheckboxChanged();
|
||||||
void FormAccepted();
|
void FormAccepted();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::SettingsDialog* ui;
|
Ui::SettingsDialog* ui;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SETTINGSDIALOG_H
|
#endif // SETTINGSDIALOG_H
|
||||||
|
@ -2,150 +2,150 @@
|
|||||||
<ui version="4.0">
|
<ui version="4.0">
|
||||||
<class>SettingsDialog</class>
|
<class>SettingsDialog</class>
|
||||||
<widget class="QDialog" name="SettingsDialog">
|
<widget class="QDialog" name="SettingsDialog">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>407</width>
|
<width>407</width>
|
||||||
<height>195</height>
|
<height>195</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||||
<horstretch>0</horstretch>
|
<horstretch>0</horstretch>
|
||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>OBSWebsocket.Settings.DialogTitle</string>
|
<string>OBSWebsocket.Settings.DialogTitle</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizeGripEnabled">
|
<property name="sizeGripEnabled">
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
<property name="sizeConstraint">
|
<property name="sizeConstraint">
|
||||||
<enum>QLayout::SetDefaultConstraint</enum>
|
<enum>QLayout::SetDefaultConstraint</enum>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QFormLayout" name="formLayout">
|
<layout class="QFormLayout" name="formLayout">
|
||||||
<item row="3" column="1">
|
<item row="3" column="1">
|
||||||
<widget class="QCheckBox" name="authRequired">
|
<widget class="QCheckBox" name="authRequired">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>OBSWebsocket.Settings.AuthRequired</string>
|
<string>OBSWebsocket.Settings.AuthRequired</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="4" column="0">
|
<item row="4" column="0">
|
||||||
<widget class="QLabel" name="lbl_password">
|
<widget class="QLabel" name="lbl_password">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>OBSWebsocket.Settings.Password</string>
|
<string>OBSWebsocket.Settings.Password</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="4" column="1">
|
<item row="4" column="1">
|
||||||
<widget class="QLineEdit" name="password">
|
<widget class="QLineEdit" name="password">
|
||||||
<property name="echoMode">
|
<property name="echoMode">
|
||||||
<enum>QLineEdit::Password</enum>
|
<enum>QLineEdit::Password</enum>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="1">
|
<item row="1" column="1">
|
||||||
<widget class="QCheckBox" name="serverEnabled">
|
<widget class="QCheckBox" name="serverEnabled">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>OBSWebsocket.Settings.ServerEnable</string>
|
<string>OBSWebsocket.Settings.ServerEnable</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="checked">
|
<property name="checked">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0">
|
<item row="2" column="0">
|
||||||
<widget class="QLabel" name="lbl_serverPort">
|
<widget class="QLabel" name="lbl_serverPort">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>OBSWebsocket.Settings.ServerPort</string>
|
<string>OBSWebsocket.Settings.ServerPort</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="1">
|
<item row="2" column="1">
|
||||||
<widget class="QSpinBox" name="serverPort">
|
<widget class="QSpinBox" name="serverPort">
|
||||||
<property name="minimum">
|
<property name="minimum">
|
||||||
<number>1024</number>
|
<number>1024</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="maximum">
|
<property name="maximum">
|
||||||
<number>65535</number>
|
<number>65535</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="value">
|
<property name="value">
|
||||||
<number>4444</number>
|
<number>4444</number>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="5" column="1">
|
<item row="5" column="1">
|
||||||
<widget class="QCheckBox" name="alertsEnabled">
|
<widget class="QCheckBox" name="alertsEnabled">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>OBSWebsocket.Settings.AlertsEnable</string>
|
<string>OBSWebsocket.Settings.AlertsEnable</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="checked">
|
<property name="checked">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="6" column="1">
|
<item row="6" column="1">
|
||||||
<widget class="QCheckBox" name="debugEnabled">
|
<widget class="QCheckBox" name="debugEnabled">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>OBSWebsocket.Settings.DebugEnable</string>
|
<string>OBSWebsocket.Settings.DebugEnable</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="checked">
|
<property name="checked">
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QDialogButtonBox" name="buttonBox">
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Horizontal</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="standardButtons">
|
<property name="standardButtons">
|
||||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<resources/>
|
<resources/>
|
||||||
<connections>
|
<connections>
|
||||||
<connection>
|
<connection>
|
||||||
<sender>buttonBox</sender>
|
<sender>buttonBox</sender>
|
||||||
<signal>accepted()</signal>
|
<signal>accepted()</signal>
|
||||||
<receiver>SettingsDialog</receiver>
|
<receiver>SettingsDialog</receiver>
|
||||||
<slot>accept()</slot>
|
<slot>accept()</slot>
|
||||||
<hints>
|
<hints>
|
||||||
<hint type="sourcelabel">
|
<hint type="sourcelabel">
|
||||||
<x>248</x>
|
<x>248</x>
|
||||||
<y>294</y>
|
<y>294</y>
|
||||||
</hint>
|
</hint>
|
||||||
<hint type="destinationlabel">
|
<hint type="destinationlabel">
|
||||||
<x>157</x>
|
<x>157</x>
|
||||||
<y>314</y>
|
<y>314</y>
|
||||||
</hint>
|
</hint>
|
||||||
</hints>
|
</hints>
|
||||||
</connection>
|
</connection>
|
||||||
<connection>
|
<connection>
|
||||||
<sender>buttonBox</sender>
|
<sender>buttonBox</sender>
|
||||||
<signal>rejected()</signal>
|
<signal>rejected()</signal>
|
||||||
<receiver>SettingsDialog</receiver>
|
<receiver>SettingsDialog</receiver>
|
||||||
<slot>reject()</slot>
|
<slot>reject()</slot>
|
||||||
<hints>
|
<hints>
|
||||||
<hint type="sourcelabel">
|
<hint type="sourcelabel">
|
||||||
<x>316</x>
|
<x>316</x>
|
||||||
<y>300</y>
|
<y>300</y>
|
||||||
</hint>
|
</hint>
|
||||||
<hint type="destinationlabel">
|
<hint type="destinationlabel">
|
||||||
<x>286</x>
|
<x>286</x>
|
||||||
<y>314</y>
|
<y>314</y>
|
||||||
</hint>
|
</hint>
|
||||||
</hints>
|
</hints>
|
||||||
</connection>
|
</connection>
|
||||||
</connections>
|
</connections>
|
||||||
</ui>
|
</ui>
|
||||||
|
@ -40,41 +40,41 @@ OBS_MODULE_USE_DEFAULT_LOCALE("obs-websocket", "en-US")
|
|||||||
SettingsDialog* settings_dialog;
|
SettingsDialog* settings_dialog;
|
||||||
|
|
||||||
bool obs_module_load(void) {
|
bool obs_module_load(void) {
|
||||||
blog(LOG_INFO, "you can haz websockets (version %s)", OBS_WEBSOCKET_VERSION);
|
blog(LOG_INFO, "you can haz websockets (version %s)", OBS_WEBSOCKET_VERSION);
|
||||||
blog(LOG_INFO, "qt version (compile-time): %s ; qt version (run-time): %s",
|
blog(LOG_INFO, "qt version (compile-time): %s ; qt version (run-time): %s",
|
||||||
QT_VERSION_STR, qVersion());
|
QT_VERSION_STR, qVersion());
|
||||||
|
|
||||||
// Core setup
|
// Core setup
|
||||||
Config* config = Config::Current();
|
Config* config = Config::Current();
|
||||||
config->Load();
|
config->Load();
|
||||||
|
|
||||||
WSServer::Instance = new WSServer();
|
WSServer::Instance = new WSServer();
|
||||||
WSEvents::Instance = new WSEvents(WSServer::Instance);
|
WSEvents::Instance = new WSEvents(WSServer::Instance);
|
||||||
|
|
||||||
if (config->ServerEnabled)
|
if (config->ServerEnabled)
|
||||||
WSServer::Instance->Start(config->ServerPort);
|
WSServer::Instance->Start(config->ServerPort);
|
||||||
|
|
||||||
// UI setup
|
// UI setup
|
||||||
QAction* menu_action = (QAction*)obs_frontend_add_tools_menu_qaction(
|
QAction* menu_action = (QAction*)obs_frontend_add_tools_menu_qaction(
|
||||||
obs_module_text("OBSWebsocket.Menu.SettingsItem"));
|
obs_module_text("OBSWebsocket.Menu.SettingsItem"));
|
||||||
|
|
||||||
obs_frontend_push_ui_translation(obs_module_get_string);
|
obs_frontend_push_ui_translation(obs_module_get_string);
|
||||||
QMainWindow* main_window = (QMainWindow*)obs_frontend_get_main_window();
|
QMainWindow* main_window = (QMainWindow*)obs_frontend_get_main_window();
|
||||||
settings_dialog = new SettingsDialog(main_window);
|
settings_dialog = new SettingsDialog(main_window);
|
||||||
obs_frontend_pop_ui_translation();
|
obs_frontend_pop_ui_translation();
|
||||||
|
|
||||||
auto menu_cb = [] {
|
auto menu_cb = [] {
|
||||||
settings_dialog->ToggleShowHide();
|
settings_dialog->ToggleShowHide();
|
||||||
};
|
};
|
||||||
menu_action->connect(menu_action, &QAction::triggered, menu_cb);
|
menu_action->connect(menu_action, &QAction::triggered, menu_cb);
|
||||||
|
|
||||||
// Loading finished
|
// Loading finished
|
||||||
blog(LOG_INFO, "module loaded!");
|
blog(LOG_INFO, "module loaded!");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void obs_module_unload() {
|
void obs_module_unload() {
|
||||||
blog(LOG_INFO, "goodbye!");
|
blog(LOG_INFO, "goodbye!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user