mirror of
https://github.com/Palakis/obs-websocket.git
synced 2024-08-30 18:12:16 +00:00
Compare commits
90 Commits
Author | SHA1 | Date | |
---|---|---|---|
974d6b48b2 | |||
db2b1e2dc7 | |||
98656b5d2f | |||
3c7570d814 | |||
fc3e30a826 | |||
2f0476b43c | |||
e310c7d744 | |||
8a649b89c8 | |||
95f52987ef | |||
82b8c66d51 | |||
83fb1843ee | |||
58b10069ab | |||
9cda739672 | |||
276bba050b | |||
147e49b362 | |||
bc338c1f4a | |||
e8fbb18a71 | |||
682c349831 | |||
14b311f6ab | |||
8a40f355c8 | |||
ae2f90c5c2 | |||
7aff773e2c | |||
0cdfa6e7f6 | |||
fc637eef6d | |||
b4c3141170 | |||
41257f7af5 | |||
b204f3ec90 | |||
b4926b3535 | |||
77d63e9848 | |||
94dcd58c2e | |||
689ce16f1b | |||
edc64b8336 | |||
03db5bfd8d | |||
9ad340ab02 | |||
962e26040d | |||
b07884c1da | |||
bad0fb62ed | |||
28e522ce97 | |||
c206cdfa4c | |||
c31ec077f5 | |||
afc6a60746 | |||
0a495b67e6 | |||
37ea7073d5 | |||
feaeef5a70 | |||
5586670d38 | |||
65a9139ffe | |||
3d76f078cd | |||
a1de1b11bc | |||
b5a3e3a4f0 | |||
d7b0ad4916 | |||
2a80a6b217 | |||
9df72f54d5 | |||
ef75ca36c9 | |||
84c0b698f5 | |||
3d9a4ef1e6 | |||
cf51fdceef | |||
85a52ab01f | |||
f2792c0b40 | |||
97109087a4 | |||
953f07f21f | |||
03f1035690 | |||
a561c60f7e | |||
7963b328f9 | |||
3b7e216409 | |||
9ae43a6f75 | |||
6b86de1fb9 | |||
4e6d4ac437 | |||
3b197651cc | |||
c675f1c20c | |||
e87955d59a | |||
c718d8d803 | |||
454a68d1b7 | |||
45f6f74cbe | |||
cb7412a457 | |||
a9fc82365c | |||
edc0fed9e2 | |||
1c718963ea | |||
cd40ccdb9d | |||
80e1dc2446 | |||
d03c4cc4b9 | |||
7bd434e755 | |||
640bcb90c6 | |||
08e86a1378 | |||
fefcc3937a | |||
25210dfa52 | |||
56fbb7b9cf | |||
c55d33b956 | |||
0c5bce101e | |||
0a50e2a95c | |||
5ad940924b |
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
|
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -1,3 +0,0 @@
|
||||
[submodule "deps/mbedtls"]
|
||||
path = deps/mbedtls
|
||||
url = https://github.com/ARMmbed/mbedtls
|
@ -34,8 +34,10 @@ matrix:
|
||||
|
||||
- os: osx
|
||||
env: _macos_build
|
||||
osx_image: xcode8.3
|
||||
before_install: "./CI/install-dependencies-macos.sh"
|
||||
osx_image: xcode9.4
|
||||
before_install:
|
||||
- "./CI/install-dependencies-macos.sh"
|
||||
- "./CI/install-build-obs-macos.sh"
|
||||
script: "./CI/build-macos.sh"
|
||||
after_success:
|
||||
- ./CI/package-macos.sh
|
||||
|
21
BUILDING.md
21
BUILDING.md
@ -1,6 +1,9 @@
|
||||
# Compiling obs-websocket
|
||||
## Prerequisites
|
||||
You'll need [QT 5.9.0](https://download.qt.io/official_releases/qt/5.7/5.7.0/), CMake, and a working development environment for OBS Studio installed on your computer.
|
||||
You'll need [Qt 5.10.x](https://download.qt.io/official_releases/qt/5.10/),
|
||||
[CMake](https://cmake.org/download/), and a working [development environment for
|
||||
OBS Studio](https://obsproject.com/wiki/install-instructions) installed on your
|
||||
computer.
|
||||
|
||||
## Windows
|
||||
In cmake-gui, you'll have to set the following variables :
|
||||
@ -22,12 +25,24 @@ sudo make install
|
||||
```
|
||||
|
||||
## OS X
|
||||
Use of the Travis macOS CI scripts is recommended. Please note that these scripts install new software and can change several settings on your system. An existing obs-studio development environment is not required, as `install-dependencies-macos.sh` will install it for you.
|
||||
Of course, you're encouraged to dig through the contents of these scripts to look for issues or specificities.
|
||||
As a prerequisite, you will need Xcode for your current OSX version, the command line tools, and [Homebrew](https://brew.sh/).
|
||||
Homebrew's setup will guide you in getting your system set up, you should be good to go once Homebrew is successfully up and running.
|
||||
|
||||
Use of the Travis macOS CI scripts is recommended. Please note that these
|
||||
scripts install new software and can change several settings on your system. An
|
||||
existing obs-studio development environment is not required, as
|
||||
`install-build-obs-macos.sh` will install it for you. If you already have a
|
||||
working obs-studio development environment and have built obs-studio, you can
|
||||
skip that script.
|
||||
|
||||
Of course, you're encouraged to dig through the contents of these scripts to
|
||||
look for issues or specificities.
|
||||
|
||||
```
|
||||
git clone --recursive https://github.com/Palakis/obs-websocket.git
|
||||
cd obs-websocket
|
||||
./CI/install-dependencies-macos.sh
|
||||
./CI/install-build-obs-macos.sh
|
||||
./CI/build-macos.sh
|
||||
./CI/package-macos.sh
|
||||
```
|
||||
|
@ -1,13 +1,28 @@
|
||||
#!/bin/sh
|
||||
set -ex
|
||||
|
||||
OSTYPE=$(uname)
|
||||
|
||||
if [ "${OSTYPE}" != "Darwin" ]; then
|
||||
echo "[obs-websocket - Error] macOS build script can be run on Darwin-type OS only."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
HAS_CMAKE=$(type cmake 2>/dev/null)
|
||||
|
||||
if [ "${HAS_CMAKE}" = "" ]; then
|
||||
echo "[obs-websocket - Error] CMake not installed - please run 'install-dependencies-macos.sh' first."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
#export QT_PREFIX="$(find /usr/local/Cellar/qt5 -d 1 | tail -n 1)"
|
||||
|
||||
mkdir build && cd build
|
||||
echo "[obs-websocket] Building 'obs-websocket' for macOS."
|
||||
mkdir -p build && cd build
|
||||
cmake .. \
|
||||
-DQTDIR=/usr/local/opt/qt \
|
||||
-DLIBOBS_INCLUDE_DIR=../../obs-studio/libobs \
|
||||
-DLIBOBS_LIB=../../obs-studio/libobs \
|
||||
-DOBS_FRONTEND_LIB="$(pwd)/../../obs-studio/build/UI/obs-frontend-api/libobs-frontend-api.dylib" \
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
|
||||
-DCMAKE_INSTALL_PREFIX=/usr \
|
||||
&& make -j4
|
||||
|
@ -4,5 +4,5 @@ set -ex
|
||||
cd /root/obs-websocket
|
||||
|
||||
mkdir build && cd build
|
||||
cmake -DLIBOBS_INCLUDE_DIR="../../obs-studio/libobs" -DCMAKE_INSTALL_PREFIX=/usr ..
|
||||
cmake -DCMAKE_INSTALL_PREFIX=/usr ..
|
||||
make -j4
|
||||
|
@ -15,7 +15,7 @@ if git diff --quiet; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ "$TRAVIS_PULL_REQUEST" != "false" -o "$TRAVIS_BRANCH" != "master" ]; then
|
||||
if [ "$TRAVIS_PULL_REQUEST" != "false" -o "$TRAVIS_BRANCH" != "4.x-current" ]; then
|
||||
echo "-- Skipping documentation deployment because this is either a pull request or a non-master branch."
|
||||
exit 0
|
||||
fi
|
||||
|
35
CI/install-build-obs-macos.sh
Executable file
35
CI/install-build-obs-macos.sh
Executable file
@ -0,0 +1,35 @@
|
||||
#!/bin/sh
|
||||
|
||||
OSTYPE=$(uname)
|
||||
|
||||
if [ "${OSTYPE}" != "Darwin" ]; then
|
||||
echo "[obs-websocket - Error] macOS obs-studio build script can be run on Darwin-type OS only."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
HAS_CMAKE=$(type cmake 2>/dev/null)
|
||||
HAS_GIT=$(type git 2>/dev/null)
|
||||
|
||||
if [ "${HAS_CMAKE}" = "" ]; then
|
||||
echo "[obs-websocket - Error] CMake not installed - please run 'install-dependencies-macos.sh' first."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "${HAS_GIT}" = "" ]; then
|
||||
echo "[obs-websocket - Error] Git not installed - please install Xcode developer tools or via Homebrew."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Build obs-studio
|
||||
cd ..
|
||||
echo "[obs-websocket] Cloning obs-studio from GitHub.."
|
||||
git clone https://github.com/obsproject/obs-studio
|
||||
cd obs-studio
|
||||
OBSLatestTag=$(git describe --tags --abbrev=0)
|
||||
git checkout $OBSLatestTag
|
||||
mkdir build && cd build
|
||||
echo "[obs-websocket] Building obs-studio.."
|
||||
cmake .. \
|
||||
-DDISABLE_PLUGINS=true \
|
||||
-DCMAKE_PREFIX_PATH=/usr/local/opt/qt/lib/cmake \
|
||||
&& make -j4
|
@ -60,13 +60,24 @@ REM If obs-studio directory does not exist, clone the git repo, get the latest
|
||||
REM tag number, and set the build flag.
|
||||
if not exist C:\projects\obs-studio (
|
||||
echo obs-studio directory does not exist
|
||||
git clone --recursive https://github.com/jp9000/obs-studio
|
||||
git clone https://github.com/obsproject/obs-studio
|
||||
cd C:\projects\obs-studio\
|
||||
git describe --tags --abbrev=0 > C:\projects\obs-studio-latest-tag.txt
|
||||
set /p OBSLatestTag=<C:\projects\obs-studio-latest-tag.txt
|
||||
set BuildOBS=true
|
||||
)
|
||||
|
||||
REM If the needed obs-studio libs for this build_config do not exist,
|
||||
REM set the build flag.
|
||||
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
|
||||
set BuildOBS=true
|
||||
)
|
||||
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
|
||||
set BuildOBS=true
|
||||
)
|
||||
|
||||
REM Some debug info
|
||||
echo:
|
||||
echo Latest tag pre-pull: %OBSLatestTagPrePull%
|
||||
@ -97,12 +108,12 @@ if defined BuildOBS (
|
||||
mkdir build64
|
||||
echo Running cmake for obs-studio %OBSLatestTag% 32-bit...
|
||||
cd ./build32
|
||||
cmake -G "Visual Studio 14 2015" -DCOPIED_DEPENDENCIES=false -DCOPY_DEPENDENCIES=true ..
|
||||
cmake -G "Visual Studio 14 2015" -DDISABLE_PLUGINS=true -DCOPIED_DEPENDENCIES=false -DCOPY_DEPENDENCIES=true ..
|
||||
echo:
|
||||
echo:
|
||||
echo Running cmake for obs-studio %OBSLatestTag% 64-bit...
|
||||
cd ../build64
|
||||
cmake -G "Visual Studio 14 2015 Win64" -DCOPIED_DEPENDENCIES=false -DCOPY_DEPENDENCIES=true ..
|
||||
cmake -G "Visual Studio 14 2015 Win64" -DDISABLE_PLUGINS=true -DCOPIED_DEPENDENCIES=false -DCOPY_DEPENDENCIES=true ..
|
||||
echo:
|
||||
echo:
|
||||
echo Building obs-studio %OBSLatestTag% 32-bit ^(Build Config: %build_config%^)...
|
||||
|
@ -1,32 +1,59 @@
|
||||
#!/bin/sh
|
||||
set -ex
|
||||
|
||||
OSTYPE=$(uname)
|
||||
|
||||
if [ "${OSTYPE}" != "Darwin" ]; then
|
||||
echo "[obs-websocket - Error] macOS install dependencies script can be run on Darwin-type OS only."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
HAS_BREW=$(type brew 2>/dev/null)
|
||||
|
||||
if [ "${HAS_BREW}" = "" ]; then
|
||||
echo "[obs-websocket - Error] Please install Homebrew (https://www.brew.sh/) to build obs-websocket on macOS."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# OBS Studio deps
|
||||
brew update
|
||||
brew install ffmpeg
|
||||
brew install libav
|
||||
echo "[obs-websocket] Updating Homebrew.."
|
||||
brew update >/dev/null
|
||||
echo "[obs-websocket] Checking installed Homebrew formulas.."
|
||||
BREW_PACKAGES=$(brew list)
|
||||
BREW_DEPENDENCIES="ffmpeg libav cmake"
|
||||
|
||||
for DEPENDENCY in ${BREW_DEPENDENCIES}; do
|
||||
if echo "${BREW_PACKAGES}" | grep -q "^${DEPENDENCY}\$"; then
|
||||
echo "[obs-websocket] Upgrading OBS-Studio dependency '${DEPENDENCY}'.."
|
||||
brew upgrade ${DEPENDENCY} 2>/dev/null
|
||||
else
|
||||
echo "[obs-websocket] Installing OBS-Studio dependency '${DEPENDENCY}'.."
|
||||
brew install ${DEPENDENCY} 2>/dev/null
|
||||
fi
|
||||
done
|
||||
|
||||
# qtwebsockets deps
|
||||
# qt latest
|
||||
#brew install qt5
|
||||
echo "[obs-websocket] Installing obs-websocket dependency 'QT 5.10.1'.."
|
||||
# =!= NOTICE =!=
|
||||
# When building QT5 from sources on macOS 10.13+, use local qt5 formula:
|
||||
# brew install ./CI/macos/qt.rb
|
||||
# Pouring from the bottle is much quicker though, so use bottle for now.
|
||||
# =!= NOTICE =!=
|
||||
|
||||
# qt 5.9.2
|
||||
brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/2b121c9a96e58a5da14228630cb71d5bead7137e/Formula/qt.rb
|
||||
brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/9a70413d137839de0054571e5f85fd07ee400955/Formula/qt.rb
|
||||
|
||||
#echo "Qt path: $(find /usr/local/Cellar/qt5 -d 1 | tail -n 1)"
|
||||
# Pin this version of QT5 to avoid `brew upgrade`
|
||||
# upgrading it to incompatible version
|
||||
brew pin qt
|
||||
|
||||
# Build obs-studio
|
||||
cd ..
|
||||
git clone --recursive https://github.com/jp9000/obs-studio
|
||||
cd obs-studio
|
||||
git checkout 21.0.0
|
||||
mkdir build && cd build
|
||||
cmake .. \
|
||||
-DCMAKE_PREFIX_PATH=/usr/local/opt/qt/lib/cmake \
|
||||
&& make -j4
|
||||
# Fetch and install Packages app
|
||||
# =!= NOTICE =!=
|
||||
# Installs a LaunchDaemon under /Library/LaunchDaemons/fr.whitebox.packages.build.dispatcher.plist
|
||||
# =!= NOTICE =!=
|
||||
|
||||
# Packages app
|
||||
cd ..
|
||||
curl -L -O http://s.sudre.free.fr/Software/files/Packages.dmg -f --retry 5 -C -
|
||||
hdiutil attach ./Packages.dmg
|
||||
sudo installer -pkg /Volumes/Packages\ 1.2.2/packages/Packages.pkg -target /
|
||||
HAS_PACKAGES=$(type packagesbuild 2>/dev/null)
|
||||
|
||||
if [ "${HAS_PACKAGES}" = "" ]; then
|
||||
echo "[obs-websocket] Installing Packaging app (might require password due to 'sudo').."
|
||||
curl -o './Packages.pkg' --retry-connrefused -s --retry-delay 1 'https://s3-us-west-2.amazonaws.com/obs-nightly/Packages.pkg'
|
||||
sudo installer -pkg ./Packages.pkg -target /
|
||||
fi
|
@ -1,57 +1,19 @@
|
||||
#!/bin/sh
|
||||
set -ex
|
||||
|
||||
# OBS Studio deps
|
||||
add-apt-repository -y ppa:obsproject/obs-studio
|
||||
apt-get -qq update
|
||||
apt-get install -y \
|
||||
libc-dev-bin libc6-dev \
|
||||
git \
|
||||
build-essential
|
||||
|
||||
apt-get install -y \
|
||||
libc-dev-bin \
|
||||
libc6-dev git \
|
||||
build-essential \
|
||||
checkinstall \
|
||||
cmake \
|
||||
libasound2-dev \
|
||||
libavcodec-dev \
|
||||
libavdevice-dev \
|
||||
libavfilter-dev \
|
||||
libavformat-dev \
|
||||
libavutil-dev \
|
||||
libcurl4-openssl-dev \
|
||||
libfontconfig-dev \
|
||||
libfreetype6-dev \
|
||||
libgl1-mesa-dev \
|
||||
libjack-jackd2-dev \
|
||||
libjansson-dev \
|
||||
libpulse-dev \
|
||||
libqt5x11extras5-dev \
|
||||
libspeexdsp-dev \
|
||||
libswresample-dev \
|
||||
libswscale-dev \
|
||||
libudev-dev \
|
||||
libv4l-dev \
|
||||
libvlc-dev \
|
||||
libx11-dev \
|
||||
libx264-dev \
|
||||
libxcb-shm0-dev \
|
||||
libxcb-xinerama0-dev \
|
||||
libxcomposite-dev \
|
||||
libxinerama-dev \
|
||||
pkg-config \
|
||||
qtbase5-dev
|
||||
obs-studio \
|
||||
libqt5websockets5-dev
|
||||
|
||||
# obs-websocket deps
|
||||
apt-get install -y libqt5websockets5-dev
|
||||
|
||||
# Build obs-studio
|
||||
cd /root
|
||||
git clone https://github.com/jp9000/obs-studio ./obs-studio
|
||||
cd obs-studio
|
||||
git checkout 21.0.0
|
||||
mkdir build && cd build
|
||||
cmake -DUNIX_STRUCTURE=1 -DCMAKE_INSTALL_PREFIX=/usr ..
|
||||
make -j4
|
||||
make install
|
||||
# Dirty hack
|
||||
wget -O /usr/include/obs/obs-frontend-api.h https://raw.githubusercontent.com/obsproject/obs-studio/master/UI/obs-frontend-api/obs-frontend-api.h
|
||||
|
||||
ldconfig
|
||||
|
@ -635,7 +635,7 @@
|
||||
<key>OVERWRITE_PERMISSIONS</key>
|
||||
<false/>
|
||||
<key>VERSION</key>
|
||||
<string>4.3.3</string>
|
||||
<string>4.5.0</string>
|
||||
</dict>
|
||||
<key>PROJECT_COMMENTS</key>
|
||||
<dict>
|
||||
|
163
CI/macos/qt.rb
Normal file
163
CI/macos/qt.rb
Normal file
@ -0,0 +1,163 @@
|
||||
# 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.
|
||||
class Qt < Formula
|
||||
desc "Cross-platform application and UI framework"
|
||||
homepage "https://www.qt.io/"
|
||||
url "https://download.qt.io/archive/qt/5.10/5.10.1/single/qt-everywhere-src-5.10.1.tar.xz"
|
||||
mirror "https://mirrorservice.org/sites/download.qt-project.org/official_releases/qt/5.10/5.10.1/single/qt-everywhere-src-5.10.1.tar.xz"
|
||||
sha256 "05ffba7b811b854ed558abf2be2ddbd3bb6ddd0b60ea4b5da75d277ac15e740a"
|
||||
head "https://code.qt.io/qt/qt5.git", :branch => "5.10.1", :shallow => false
|
||||
|
||||
bottle do
|
||||
sha256 "8b4bad005596a5f8790150fe455db998ac2406f4e0f04140d6656205d844d266" => :high_sierra
|
||||
sha256 "9c488554935fb573554a4e36d36d3c81e47245b7fefc4b61edef894e67ba1740" => :sierra
|
||||
sha256 "c0407afba5951df6cc4c6f6c1c315972bd41c99cecb4e029919c4c15ab6f7bdc" => :el_capitan
|
||||
end
|
||||
|
||||
keg_only "Qt 5 has CMake issues when linked"
|
||||
|
||||
option "with-docs", "Build documentation"
|
||||
option "with-examples", "Build examples"
|
||||
|
||||
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
|
||||
# configuration and thus untested in practice. Builds on OS X 10.7 have been
|
||||
# reported to fail: <https://github.com/Homebrew/homebrew/issues/45284>.
|
||||
depends_on :macos => :mountain_lion
|
||||
|
||||
depends_on "pkg-config" => :build
|
||||
depends_on :xcode => :build
|
||||
depends_on "mysql-client" => :optional
|
||||
depends_on "postgresql" => :optional
|
||||
|
||||
# Restore `.pc` files for framework-based build of Qt 5 on OS X. This
|
||||
# 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!)
|
||||
#
|
||||
# Core formulae known to fail without this patch (as of 2016-10-15):
|
||||
# * gnuplot (with `--with-qt` option)
|
||||
# * mkvtoolnix (with `--with-qt` option, silent build failure)
|
||||
# * poppler (with `--with-qt` option)
|
||||
patch do
|
||||
url "https://raw.githubusercontent.com/Homebrew/formula-patches/e8fe6567/qt5/restore-pc-files.patch"
|
||||
sha256 "48ff18be2f4050de7288bddbae7f47e949512ac4bcd126c2f504be2ac701158b"
|
||||
end
|
||||
|
||||
# Fix compile error on macOS 10.13 around QFixed:
|
||||
# https://github.com/Homebrew/homebrew-core/issues/27095
|
||||
# https://bugreports.qt.io/browse/QTBUG-67545
|
||||
patch do
|
||||
url "https://raw.githubusercontent.com/z00m1n/formula-patches/0de0e229/qt/QTBUG-67545.patch"
|
||||
sha256 "4a115097c7582c7dce4207f5500d13feb8c990eb8a05a43f41953985976ebe6c"
|
||||
end
|
||||
|
||||
# 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:
|
||||
# https://github.com/Homebrew/homebrew-core/issues/27095
|
||||
# https://bugreports.qt.io/browse/QTBUG-67810
|
||||
patch do
|
||||
url "https://raw.githubusercontent.com/z00m1n/formula-patches/a1a1f0dd/qt/QTBUG-67810.patch"
|
||||
sha256 "8ee0bf71df1043f08ebae3aa35036be29c4d9ebff8a27e3b0411a6bd635e9382"
|
||||
end
|
||||
|
||||
def install
|
||||
args = %W[
|
||||
-verbose
|
||||
-prefix #{prefix}
|
||||
-release
|
||||
-opensource -confirm-license
|
||||
-system-zlib
|
||||
-qt-libpng
|
||||
-qt-libjpeg
|
||||
-qt-freetype
|
||||
-qt-pcre
|
||||
-nomake tests
|
||||
-no-rpath
|
||||
-pkg-config
|
||||
-dbus-runtime
|
||||
-no-assimp
|
||||
]
|
||||
|
||||
args << "-nomake" << "examples" if build.without? "examples"
|
||||
|
||||
if build.with? "mysql-client"
|
||||
args << "-plugin-sql-mysql"
|
||||
(buildpath/"brew_shim/mysql_config").write <<~EOS
|
||||
#!/bin/sh
|
||||
if [ x"$1" = x"--libs" ]; then
|
||||
mysql_config --libs | sed "s/-lssl -lcrypto//"
|
||||
else
|
||||
exec mysql_config "$@"
|
||||
fi
|
||||
EOS
|
||||
chmod 0755, "brew_shim/mysql_config"
|
||||
args << "-mysql_config" << buildpath/"brew_shim/mysql_config"
|
||||
end
|
||||
|
||||
args << "-plugin-sql-psql" if build.with? "postgresql"
|
||||
|
||||
system "./configure", *args
|
||||
system "make"
|
||||
ENV.deparallelize
|
||||
system "make", "install"
|
||||
|
||||
if build.with? "docs"
|
||||
system "make", "docs"
|
||||
system "make", "install_docs"
|
||||
end
|
||||
|
||||
# Some config scripts will only find Qt in a "Frameworks" folder
|
||||
frameworks.install_symlink Dir["#{lib}/*.framework"]
|
||||
|
||||
# The pkg-config files installed suggest that headers can be found in the
|
||||
# `include` directory. Make this so by creating symlinks from `include` to
|
||||
# the Frameworks' Headers folders.
|
||||
Pathname.glob("#{lib}/*.framework/Headers") do |path|
|
||||
include.install_symlink path => path.parent.basename(".framework")
|
||||
end
|
||||
|
||||
# Move `*.app` bundles into `libexec` to expose them to `brew linkapps` and
|
||||
# because we don't like having them in `bin`.
|
||||
# (Note: This move breaks invocation of Assistant via the Help menu
|
||||
# of both Designer and Linguist as that relies on Assistant being in `bin`.)
|
||||
libexec.mkpath
|
||||
Pathname.glob("#{bin}/*.app") { |app| mv app, libexec }
|
||||
end
|
||||
|
||||
def caveats; <<~EOS
|
||||
We agreed to the Qt opensource license for you.
|
||||
If this is unacceptable you should uninstall.
|
||||
EOS
|
||||
end
|
||||
|
||||
test do
|
||||
(testpath/"hello.pro").write <<~EOS
|
||||
QT += core
|
||||
QT -= gui
|
||||
TARGET = hello
|
||||
CONFIG += console
|
||||
CONFIG -= app_bundle
|
||||
TEMPLATE = app
|
||||
SOURCES += main.cpp
|
||||
EOS
|
||||
|
||||
(testpath/"main.cpp").write <<~EOS
|
||||
#include <QCoreApplication>
|
||||
#include <QDebug>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QCoreApplication a(argc, argv);
|
||||
qDebug() << "Hello World!";
|
||||
return 0;
|
||||
}
|
||||
EOS
|
||||
|
||||
system bin/"qmake", testpath/"hello.pro"
|
||||
system "make"
|
||||
assert_predicate testpath/"hello", :exist?
|
||||
assert_predicate testpath/"main.o", :exist?
|
||||
system "./hello"
|
||||
end
|
||||
end
|
@ -2,8 +2,15 @@
|
||||
|
||||
set -e
|
||||
|
||||
echo "-- Preparing package build"
|
||||
export QT_CELLAR_PREFIX="$(find /usr/local/Cellar/qt -d 1 | tail -n 1)"
|
||||
OSTYPE=$(uname)
|
||||
|
||||
if [ "${OSTYPE}" != "Darwin" ]; then
|
||||
echo "[obs-websocket - Error] macOS package script can be run on Darwin-type OS only."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "[obs-websocket] Preparing package build"
|
||||
export QT_CELLAR_PREFIX="$(/usr/bin/find /usr/local/Cellar/qt -d 1 | sort -t '.' -k 1,1n -k 2,2n -k 3,3n | tail -n 1)"
|
||||
|
||||
export WS_LIB="/usr/local/opt/qt/lib/QtWebSockets.framework/QtWebSockets"
|
||||
export NET_LIB="/usr/local/opt/qt/lib/QtNetwork.framework/QtNetwork"
|
||||
@ -20,26 +27,28 @@ fi
|
||||
export FILENAME="obs-websocket-$VERSION.pkg"
|
||||
export LATEST_FILENAME="obs-websocket-latest-$LATEST_VERSION.pkg"
|
||||
|
||||
echo "-- Copying Qt dependencies"
|
||||
cp $WS_LIB ./build
|
||||
cp $NET_LIB ./build
|
||||
echo "[obs-websocket] Copying Qt dependencies"
|
||||
if [ ! -f ./build/$(basename $WS_LIB) ]; then cp $WS_LIB ./build; fi
|
||||
if [ ! -f ./build/$(basename $NET_LIB) ]; then cp $NET_LIB ./build; fi
|
||||
|
||||
chmod +rw ./build/QtWebSockets ./build/QtNetwork
|
||||
|
||||
echo "-- Modifying QtNetwork"
|
||||
echo "[obs-websocket] Modifying QtNetwork"
|
||||
install_name_tool \
|
||||
-id @rpath/QtNetwork \
|
||||
-change /usr/local/opt/qt/lib/QtNetwork.framework/Versions/5/QtNetwork @rpath/QtNetwork \
|
||||
-change $QT_CELLAR_PREFIX/lib/QtCore.framework/Versions/5/QtCore @rpath/QtCore \
|
||||
./build/QtNetwork
|
||||
|
||||
echo "-- Modifying QtWebSockets"
|
||||
echo "[obs-websocket] Modifying QtWebSockets"
|
||||
install_name_tool \
|
||||
-id @rpath/QtWebSockets \
|
||||
-change /usr/local/opt/qt/lib/QtWebSockets.framework/Versions/5/QtWebSockets @rpath/QtWebSockets \
|
||||
-change $QT_CELLAR_PREFIX/lib/QtNetwork.framework/Versions/5/QtNetwork @rpath/QtNetwork \
|
||||
-change $QT_CELLAR_PREFIX/lib/QtCore.framework/Versions/5/QtCore @rpath/QtCore \
|
||||
./build/QtWebSockets
|
||||
|
||||
echo "-- Modifying obs-websocket.so"
|
||||
echo "[obs-websocket] Modifying obs-websocket.so"
|
||||
install_name_tool \
|
||||
-change /usr/local/opt/qt/lib/QtWebSockets.framework/Versions/5/QtWebSockets @rpath/QtWebSockets \
|
||||
-change /usr/local/opt/qt/lib/QtWidgets.framework/Versions/5/QtWidgets @rpath/QtWidgets \
|
||||
@ -49,18 +58,18 @@ install_name_tool \
|
||||
./build/obs-websocket.so
|
||||
|
||||
# Check if replacement worked
|
||||
echo "-- Dependencies for QtNetwork"
|
||||
echo "[obs-websocket] Dependencies for QtNetwork"
|
||||
otool -L ./build/QtNetwork
|
||||
echo "-- Dependencies for QtWebSockets"
|
||||
echo "[obs-websocket] Dependencies for QtWebSockets"
|
||||
otool -L ./build/QtWebSockets
|
||||
echo "-- Dependencies for obs-websocket"
|
||||
echo "[obs-websocket] Dependencies for obs-websocket"
|
||||
otool -L ./build/obs-websocket.so
|
||||
|
||||
chmod -w ./build/QtWebSockets ./build/QtNetwork
|
||||
|
||||
echo "-- Actual package build"
|
||||
echo "[obs-websocket] Actual package build"
|
||||
packagesbuild ./CI/macos/obs-websocket.pkgproj
|
||||
|
||||
echo "-- Renaming obs-websocket.pkg to $FILENAME"
|
||||
echo "[obs-websocket] Renaming obs-websocket.pkg to $FILENAME"
|
||||
mv ./release/obs-websocket.pkg ./release/$FILENAME
|
||||
cp ./release/$FILENAME ./release/$LATEST_FILENAME
|
||||
|
@ -6,16 +6,15 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTOUIC ON)
|
||||
|
||||
if (WIN32 OR APPLE)
|
||||
include(external/FindLibObs.cmake)
|
||||
endif()
|
||||
|
||||
find_package(LibObs REQUIRED)
|
||||
find_package(Qt5Core REQUIRED)
|
||||
find_package(Qt5WebSockets REQUIRED)
|
||||
find_package(Qt5Widgets REQUIRED)
|
||||
|
||||
add_subdirectory(deps/mbedtls EXCLUDE_FROM_ALL)
|
||||
set(ENABLE_PROGRAMS false)
|
||||
|
||||
set(obs-websocket_SOURCES
|
||||
src/obs-websocket.cpp
|
||||
src/WSServer.cpp
|
||||
@ -50,22 +49,17 @@ add_library(obs-websocket MODULE
|
||||
${obs-websocket_SOURCES}
|
||||
${obs-websocket_HEADERS})
|
||||
|
||||
add_dependencies(obs-websocket mbedcrypto)
|
||||
|
||||
include_directories(
|
||||
"${LIBOBS_INCLUDE_DIR}/../UI/obs-frontend-api"
|
||||
${Qt5Core_INCLUDES}
|
||||
${Qt5WebSockets_INCLUDES}
|
||||
${Qt5Widgets_INCLUDES}
|
||||
${mbedcrypto_INCLUDES}
|
||||
"${CMAKE_SOURCE_DIR}/deps/mbedtls/include")
|
||||
${Qt5Widgets_INCLUDES})
|
||||
|
||||
target_link_libraries(obs-websocket
|
||||
libobs
|
||||
Qt5::Core
|
||||
Qt5::WebSockets
|
||||
Qt5::Widgets
|
||||
mbedcrypto)
|
||||
Qt5::Widgets)
|
||||
|
||||
# --- End of section ---
|
||||
|
||||
@ -73,7 +67,7 @@ target_link_libraries(obs-websocket
|
||||
if(WIN32)
|
||||
if(NOT DEFINED OBS_FRONTEND_LIB)
|
||||
set(OBS_FRONTEND_LIB "OBS_FRONTEND_LIB-NOTFOUND" CACHE FILEPATH "OBS frontend library")
|
||||
message(FATAL_ERROR "Could not find OBS Frontend API\'s library !")
|
||||
message(FATAL_ERROR "Could not find OBS Frontend API's library !")
|
||||
endif()
|
||||
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
@ -91,23 +85,12 @@ if(WIN32)
|
||||
target_link_libraries(obs-websocket
|
||||
"${OBS_FRONTEND_LIB}")
|
||||
|
||||
add_custom_command(TARGET obs-websocket POST_BUILD
|
||||
COMMAND if $<CONFIG:Release>==1 ("${CMAKE_COMMAND}" -E copy
|
||||
"${QTDIR}/bin/Qt5WebSockets.dll"
|
||||
"${QTDIR}/bin/Qt5Network.dll"
|
||||
"${CMAKE_BINARY_DIR}/$<CONFIG>")
|
||||
|
||||
COMMAND if $<CONFIG:Debug>==1 ("${CMAKE_COMMAND}" -E copy
|
||||
"${QTDIR}/bin/Qt5WebSocketsd.dll"
|
||||
"${QTDIR}/bin/Qt5Networkd.dll"
|
||||
"${CMAKE_BINARY_DIR}/$<CONFIG>")
|
||||
)
|
||||
|
||||
# --- Release package helper ---
|
||||
# The "release" folder has a structure similar OBS' one on Windows
|
||||
set(RELEASE_DIR "${PROJECT_SOURCE_DIR}/release")
|
||||
|
||||
add_custom_command(TARGET obs-websocket POST_BUILD
|
||||
# If config is Release, package release files
|
||||
COMMAND if $<CONFIG:Release>==1 (
|
||||
"${CMAKE_COMMAND}" -E make_directory
|
||||
"${RELEASE_DIR}/data/obs-plugins/obs-websocket"
|
||||
@ -123,6 +106,26 @@ if(WIN32)
|
||||
"${QTDIR}/bin/Qt5Network.dll"
|
||||
"${RELEASE_DIR}/obs-plugins/${ARCH_NAME}")
|
||||
|
||||
# If config is RelWithDebInfo, package release files
|
||||
COMMAND if $<CONFIG:RelWithDebInfo>==1 (
|
||||
"${CMAKE_COMMAND}" -E make_directory
|
||||
"${RELEASE_DIR}/data/obs-plugins/obs-websocket"
|
||||
"${RELEASE_DIR}/obs-plugins/${ARCH_NAME}")
|
||||
|
||||
COMMAND if $<CONFIG:RelWithDebInfo>==1 ("${CMAKE_COMMAND}" -E copy_directory
|
||||
"${PROJECT_SOURCE_DIR}/data"
|
||||
"${RELEASE_DIR}/data/obs-plugins/obs-websocket")
|
||||
|
||||
COMMAND if $<CONFIG:RelWithDebInfo>==1 ("${CMAKE_COMMAND}" -E copy
|
||||
"$<TARGET_FILE:obs-websocket>"
|
||||
"${QTDIR}/bin/Qt5WebSockets.dll"
|
||||
"${QTDIR}/bin/Qt5Network.dll"
|
||||
"${RELEASE_DIR}/obs-plugins/${ARCH_NAME}")
|
||||
|
||||
COMMAND if $<CONFIG:RelWithDebInfo>==1 ("${CMAKE_COMMAND}" -E copy
|
||||
"$<TARGET_PDB_FILE:obs-websocket>"
|
||||
"${RELEASE_DIR}/obs-plugins/${ARCH_NAME}")
|
||||
|
||||
# Copy to obs-studio dev environment for immediate testing
|
||||
COMMAND if $<CONFIG:Debug>==1 (
|
||||
"${CMAKE_COMMAND}" -E copy
|
||||
@ -131,6 +134,11 @@ if(WIN32)
|
||||
"${QTDIR}/bin/Qt5Networkd.dll"
|
||||
"${LIBOBS_INCLUDE_DIR}/../${OBS_BUILDDIR_ARCH}/rundir/$<CONFIG>/obs-plugins/${ARCH_NAME}")
|
||||
|
||||
COMMAND if $<CONFIG:Debug>==1 (
|
||||
"${CMAKE_COMMAND}" -E copy
|
||||
"$<TARGET_PDB_FILE:obs-websocket>"
|
||||
"${LIBOBS_INCLUDE_DIR}/../${OBS_BUILDDIR_ARCH}/rundir/$<CONFIG>/obs-plugins/${ARCH_NAME}")
|
||||
|
||||
COMMAND if $<CONFIG:Debug>==1 (
|
||||
"${CMAKE_COMMAND}" -E make_directory
|
||||
"${LIBOBS_INCLUDE_DIR}/../${OBS_BUILDDIR_ARCH}/rundir/$<CONFIG>/data/obs-plugins/obs-websocket")
|
||||
@ -149,7 +157,6 @@ endif()
|
||||
if(UNIX AND NOT APPLE)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
||||
|
||||
target_compile_options(mbedcrypto PRIVATE -fPIC)
|
||||
set_target_properties(obs-websocket PROPERTIES PREFIX "")
|
||||
target_link_libraries(obs-websocket
|
||||
obs-frontend-api)
|
||||
@ -167,6 +174,7 @@ endif()
|
||||
if(APPLE)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++ -fvisibility=default")
|
||||
|
||||
set(CMAKE_SKIP_RPATH TRUE)
|
||||
set_target_properties(obs-websocket PROPERTIES PREFIX "")
|
||||
target_link_libraries(obs-websocket "${OBS_FRONTEND_LIB}")
|
||||
endif()
|
||||
|
@ -9,7 +9,7 @@ install:
|
||||
- set DepsPath32=%CD%\dependencies2015\win32
|
||||
- set DepsPath64=%CD%\dependencies2015\win64
|
||||
- call C:\projects\obs-websocket\CI\install-setup-qt.cmd
|
||||
- set build_config=Release
|
||||
- set build_config=RelWithDebInfo
|
||||
- call C:\projects\obs-websocket\CI\install-build-obs.cmd
|
||||
- cd C:\projects\obs-websocket\
|
||||
- mkdir build32
|
||||
@ -25,9 +25,12 @@ build_script:
|
||||
|
||||
before_deploy:
|
||||
- 7z a "C:\projects\obs-websocket\build.zip" C:\projects\obs-websocket\release\*
|
||||
- set PATH=%PATH%;"C:\\Program Files (x86)\\Inno Setup 5"
|
||||
- iscc "C:\projects\obs-websocket\installer\installer.iss"
|
||||
|
||||
deploy_script:
|
||||
- ps: Push-AppveyorArtifact "C:\projects\obs-websocket\build.zip" -FileName "obs-websocket-$(git log --pretty=format:'%h' -n 1).zip"
|
||||
- ps: Push-AppveyorArtifact "C:\projects\obs-websocket\build.zip" -FileName "obs-websocket-$(git log --pretty=format:'%h' -n 1)-Windows.zip"
|
||||
- ps: Push-AppveyorArtifact "C:\projects\obs-websocket\installer\Output\obs-websocket-Windows-Installer.exe" -FileName "obs-websocket-$(git log --pretty=format:'%h' -n 1)-Windows-Installer.exe"
|
||||
|
||||
test: off
|
||||
|
||||
|
1
deps/mbedtls
vendored
1
deps/mbedtls
vendored
Submodule deps/mbedtls deleted from 1a6a15c795
@ -30,6 +30,14 @@ const processComments = comments => {
|
||||
let errors = [];
|
||||
|
||||
comments.forEach(comment => {
|
||||
if (comment.typedef) {
|
||||
comment.comment = undefined;
|
||||
comment.context = undefined;
|
||||
sorted['typedefs'] = sorted['typedefs'] || [];
|
||||
sorted['typedefs'].push(comment);
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof comment.api === 'undefined') return;
|
||||
let validationFailures = validateComment(comment);
|
||||
|
||||
@ -84,9 +92,7 @@ const validateComment = comment => {
|
||||
fullContext: Object.assign({}, comment)
|
||||
};
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
const files = glob.sync(config.srcGlob);
|
||||
const comments = processComments(parseFiles(files));
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,19 +1,13 @@
|
||||
<!-- This file was generated based on handlebars templates. Do not edit directly! -->
|
||||
|
||||
# obs-websocket 4.2.1 protocol reference
|
||||
|
||||
**This is the reference for the unreleased obs-websocket 4.2.1. See the list below for older versions.**
|
||||
- [4.2.0 protocol reference](https://github.com/Palakis/obs-websocket/blob/4.2.0/docs/generated/protocol.md)
|
||||
- [4.1.0 protocol reference](https://github.com/Palakis/obs-websocket/blob/4.1.0/PROTOCOL.md)
|
||||
- [4.0.0 protocol reference](https://github.com/Palakis/obs-websocket/blob/4.0.0/PROTOCOL.md)
|
||||
# obs-websocket 4.5.0 protocol reference
|
||||
|
||||
# General Introduction
|
||||
Messages are exchanged between the client and the server as JSON objects.
|
||||
This protocol is based on the original OBS Remote protocol created by Bill Hamilton, with new commands specific to OBS Studio.
|
||||
|
||||
|
||||
# Authentication
|
||||
OBSWebSocket uses SHA256 to transmit credentials.
|
||||
`obs-websocket` uses SHA256 to transmit credentials.
|
||||
|
||||
A request for [`GetAuthRequired`](#getauthrequired) returns two elements:
|
||||
- A `challenge`: a random string that will be used to generate the auth response.
|
||||
@ -48,6 +42,9 @@ auth_response = base64_encode(auth_response_hash)
|
||||
|
||||
<!-- toc -->
|
||||
|
||||
- [Typedefs](#typedefs)
|
||||
* [Scene](#scene)
|
||||
* [Source](#source)
|
||||
- [Events](#events)
|
||||
* [Scenes](#scenes)
|
||||
+ [SwitchScenes](#switchscenes)
|
||||
@ -125,10 +122,13 @@ auth_response = base64_encode(auth_response_hash)
|
||||
+ [SetSceneItemPosition](#setsceneitemposition)
|
||||
+ [SetSceneItemTransform](#setsceneitemtransform)
|
||||
+ [SetSceneItemCrop](#setsceneitemcrop)
|
||||
+ [DeleteSceneItem](#deletesceneitem)
|
||||
+ [DuplicateSceneItem](#duplicatesceneitem)
|
||||
* [Scenes](#scenes-1)
|
||||
+ [SetCurrentScene](#setcurrentscene)
|
||||
+ [GetCurrentScene](#getcurrentscene)
|
||||
+ [GetSceneList](#getscenelist)
|
||||
+ [ReorderSceneItems](#reordersceneitems)
|
||||
* [Sources](#sources-1)
|
||||
+ [GetSourcesList](#getsourceslist)
|
||||
+ [GetSourcesTypesList](#getsourcestypeslist)
|
||||
@ -143,9 +143,17 @@ auth_response = base64_encode(auth_response_hash)
|
||||
+ [SetSourceSettings](#setsourcesettings)
|
||||
+ [GetTextGDIPlusProperties](#gettextgdiplusproperties)
|
||||
+ [SetTextGDIPlusProperties](#settextgdiplusproperties)
|
||||
+ [GetTextFreetype2Properties](#gettextfreetype2properties)
|
||||
+ [SetTextFreetype2Properties](#settextfreetype2properties)
|
||||
+ [GetBrowserSourceProperties](#getbrowsersourceproperties)
|
||||
+ [SetBrowserSourceProperties](#setbrowsersourceproperties)
|
||||
+ [GetSpecialSources](#getspecialsources)
|
||||
+ [GetSourceFilters](#getsourcefilters)
|
||||
+ [AddFilterToSource](#addfiltertosource)
|
||||
+ [RemoveFilterFromSource](#removefilterfromsource)
|
||||
+ [ReorderSourceFilter](#reordersourcefilter)
|
||||
+ [MoveSourceFilter](#movesourcefilter)
|
||||
+ [SetSourceFilterSettings](#setsourcefiltersettings)
|
||||
* [Streaming](#streaming-1)
|
||||
+ [GetStreamingStatus](#getstreamingstatus)
|
||||
+ [StartStopStreaming](#startstopstreaming)
|
||||
@ -171,6 +179,31 @@ auth_response = base64_encode(auth_response_hash)
|
||||
|
||||
<!-- tocstop -->
|
||||
|
||||
# Typedefs
|
||||
These are complex types, such as `Source` and `Scene`, which are used as arguments or return values in multiple requests and/or events.
|
||||
|
||||
|
||||
## Scene
|
||||
| Name | Type | Description |
|
||||
| ---- | :---: | ------------|
|
||||
| `name` | _String_ | Name of the currently active scene. |
|
||||
| `sources` | _Array<Source>_ | Ordered list of the current scene's source items. |
|
||||
## Source
|
||||
| Name | Type | Description |
|
||||
| ---- | :---: | ------------|
|
||||
| `cy` | _Number_ | |
|
||||
| `cx` | _Number_ | |
|
||||
| `name` | _String_ | The name of this Scene Item. |
|
||||
| `render` | _Boolean_ | Whether or not this Scene Item is set to "visible". |
|
||||
| `source_cx` | _Number_ | |
|
||||
| `source_cy` | _Number_ | |
|
||||
| `type` | _String_ | Source type. Value is one of the following: "input", "filter", "transition", "scene" or "unknown" |
|
||||
| `volume` | _Number_ | |
|
||||
| `x` | _Number_ | |
|
||||
| `y` | _Number_ | |
|
||||
|
||||
|
||||
|
||||
# Events
|
||||
Events are broadcast by the server to each connected client when a recognized action occurs within OBS.
|
||||
|
||||
@ -198,7 +231,7 @@ Indicates a scene change.
|
||||
| Name | Type | Description |
|
||||
| ---- | :---: | ------------|
|
||||
| `scene-name` | _String_ | The new scene. |
|
||||
| `sources` | _Array_ | List of sources in the new scene. |
|
||||
| `sources` | _Array<Source>_ | List of sources in the new scene. Same specification as [`GetCurrentScene`](#getcurrentscene). |
|
||||
|
||||
|
||||
---
|
||||
@ -304,6 +337,8 @@ A transition (other than "cut") has begun.
|
||||
| ---- | :---: | ------------|
|
||||
| `name` | _String_ | Transition name. |
|
||||
| `duration` | _int_ | Transition duration (in milliseconds). |
|
||||
| `from-scene` | _String_ | Source scene of the transition |
|
||||
| `to-scene` | _String_ | Destination scene of the transition |
|
||||
|
||||
|
||||
---
|
||||
@ -508,7 +543,7 @@ _No additional response items._
|
||||
|
||||
- Added in v4.2.0
|
||||
|
||||
A request to start the replay buffer has been issued.
|
||||
A request to stop the replay buffer has been issued.
|
||||
|
||||
**Response Items:**
|
||||
|
||||
@ -557,7 +592,7 @@ Emitted every 2 seconds after enabling it by calling SetHeartbeat.
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | :---: | ------------|
|
||||
| `pulse` | _boolean_ | Toggles between every JSON meassage as an "I am alive" indicator. |
|
||||
| `pulse` | _boolean_ | Toggles between every JSON message as an "I am alive" indicator. |
|
||||
| `current-profile` | _string (optional)_ | Current active profile. |
|
||||
| `current-scene` | _string (optional)_ | Current active scene. |
|
||||
| `streaming` | _boolean (optional)_ | Current streaming state. |
|
||||
@ -656,7 +691,7 @@ The selected preview scene has changed (only available in Studio Mode).
|
||||
| Name | Type | Description |
|
||||
| ---- | :---: | ------------|
|
||||
| `scene-name` | _String_ | Name of the scene being previewed. |
|
||||
| `sources` | _Source\|Array_ | List of sources composing the scene. Same specification as [`GetCurrentScene`](#getcurrentscene). |
|
||||
| `sources` | _Array<Source>_ | List of sources composing the scene. Same specification as [`GetCurrentScene`](#getcurrentscene). |
|
||||
|
||||
|
||||
---
|
||||
@ -878,7 +913,7 @@ _No specified parameters._
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | :---: | ------------|
|
||||
| `profiles` | _Object\|Array_ | List of available profiles. |
|
||||
| `profiles` | _Array<Object>_ | List of available profiles. |
|
||||
|
||||
|
||||
---
|
||||
@ -1112,8 +1147,7 @@ _No specified parameters._
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | :---: | ------------|
|
||||
| `scene-collections` | _Object\|Array_ | Scene collections list |
|
||||
| `scene-collections.*.` | _String_ | |
|
||||
| `scene-collections` | _Array<String>_ | Scene collections list |
|
||||
|
||||
|
||||
---
|
||||
@ -1206,7 +1240,7 @@ Reset a scene item.
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | :---: | ------------|
|
||||
| `scene-name` | _String (optional)_ | Name of the scene the source belogns to. Defaults to the current scene. |
|
||||
| `scene-name` | _String (optional)_ | Name of the scene the source belongs to. Defaults to the current scene. |
|
||||
| `item` | _String_ | Name of the source item. |
|
||||
|
||||
|
||||
@ -1312,6 +1346,59 @@ Sets the crop coordinates of the specified source item.
|
||||
|
||||
_No additional response items._
|
||||
|
||||
---
|
||||
|
||||
### DeleteSceneItem
|
||||
|
||||
|
||||
- Added in v4.5.0
|
||||
|
||||
Deletes a scene item.
|
||||
|
||||
**Request Fields:**
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | :---: | ------------|
|
||||
| `scene` | _String (optional)_ | Name of the scene the source belongs to. Defaults to the current scene. |
|
||||
| `item` | _Object_ | item to delete (required) |
|
||||
| `item.name` | _String_ | name of the scene item (prefer `id`, including both is acceptable). |
|
||||
| `item.id` | _int_ | id of the scene item. |
|
||||
|
||||
|
||||
**Response Items:**
|
||||
|
||||
_No additional response items._
|
||||
|
||||
---
|
||||
|
||||
### DuplicateSceneItem
|
||||
|
||||
|
||||
- Added in v4.5.0
|
||||
|
||||
Duplicates a scene item.
|
||||
|
||||
**Request Fields:**
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | :---: | ------------|
|
||||
| `fromScene` | _String (optional)_ | Name of the scene to copy the item from. Defaults to the current scene. |
|
||||
| `toScene` | _String (optional)_ | Name of the scene to create the item in. Defaults to the current scene. |
|
||||
| `item` | _Object_ | item to duplicate (required) |
|
||||
| `item.name` | _String_ | name of the scene item (prefer `id`, including both is acceptable). |
|
||||
| `item.id` | _int_ | id of the scene item. |
|
||||
|
||||
|
||||
**Response Items:**
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | :---: | ------------|
|
||||
| `scene` | _String_ | Name of the scene where the new item was created |
|
||||
| `item` | _Object_ | New item info |
|
||||
| `̀item.id` | _int_ | New item ID |
|
||||
| `item.name` | _String_ | New item name |
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Scenes
|
||||
@ -1352,7 +1439,7 @@ _No specified parameters._
|
||||
| Name | Type | Description |
|
||||
| ---- | :---: | ------------|
|
||||
| `name` | _String_ | Name of the currently active scene. |
|
||||
| `sources` | _Source\|Array_ | Ordered list of the current scene's source items. |
|
||||
| `sources` | _Array<Source>_ | Ordered list of the current scene's source items. |
|
||||
|
||||
|
||||
---
|
||||
@ -1373,9 +1460,32 @@ _No specified parameters._
|
||||
| Name | Type | Description |
|
||||
| ---- | :---: | ------------|
|
||||
| `current-scene` | _String_ | Name of the currently active scene. |
|
||||
| `scenes` | _Scene\|Array_ | Ordered list of the current profile's scenes (See `[GetCurrentScene](#getcurrentscene)` for more information). |
|
||||
| `scenes` | _Array<Scene>_ | Ordered list of the current profile's scenes (See `[GetCurrentScene](#getcurrentscene)` for more information). |
|
||||
|
||||
|
||||
---
|
||||
|
||||
### ReorderSceneItems
|
||||
|
||||
|
||||
- Added in v4.5.0
|
||||
|
||||
Changes the order of scene items in the requested scene.
|
||||
|
||||
**Request Fields:**
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | :---: | ------------|
|
||||
| `scene` | _String (optional)_ | Name of the scene to reorder (defaults to current). |
|
||||
| `items` | _Scene\|Array_ | Ordered list of objects with name and/or id specified. Id preferred due to uniqueness per scene |
|
||||
| `items[].id` | _int (optional)_ | Id of a specific scene item. Unique on a scene by scene basis. |
|
||||
| `items[].name` | _String (optional)_ | Name of a scene item. Sufficiently unique if no scene items share sources within the scene. |
|
||||
|
||||
|
||||
**Response Items:**
|
||||
|
||||
_No additional response items._
|
||||
|
||||
---
|
||||
|
||||
## Sources
|
||||
@ -1395,7 +1505,7 @@ _No specified parameters._
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | :---: | ------------|
|
||||
| `sources` | _Array of Objects_ | Array of sources as objects |
|
||||
| `sources` | _Array<Object>_ | Array of sources |
|
||||
| `sources.*.name` | _String_ | Unique source name |
|
||||
| `sources.*.typeId` | _String_ | Non-unique source internal type (a.k.a type id) |
|
||||
| `sources.*.type` | _String_ | Source type. Value is one of the following: "input", "filter", "transition", "scene" or "unknown" |
|
||||
@ -1418,7 +1528,7 @@ _No specified parameters._
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | :---: | ------------|
|
||||
| `ids` | _Array of Objects_ | Array of sources as objects |
|
||||
| `ids` | _Array<Object>_ | Array of source types |
|
||||
| `ids.*.typeId` | _String_ | Non-unique internal source type ID |
|
||||
| `ids.*.displayName` | _String_ | Display name of the source type |
|
||||
| `ids.*.type` | _String_ | Type. Value is one of the following: "input", "filter", "transition" or "other" |
|
||||
@ -1446,16 +1556,16 @@ Get the volume of the specified source.
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | :---: | ------------|
|
||||
| `source` | _String_ | Name of the source. |
|
||||
| `source` | _String_ | Source name. |
|
||||
|
||||
|
||||
**Response Items:**
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | :---: | ------------|
|
||||
| `name` | _String_ | Name of the source. |
|
||||
| `name` | _String_ | Source name. |
|
||||
| `volume` | _double_ | Volume of the source. Between `0.0` and `1.0`. |
|
||||
| `mute` | _boolean_ | Indicates whether the source is muted. |
|
||||
| `muted` | _boolean_ | Indicates whether the source is muted. |
|
||||
|
||||
|
||||
---
|
||||
@ -1471,7 +1581,7 @@ Set the volume of the specified source.
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | :---: | ------------|
|
||||
| `source` | _String_ | Name of the source. |
|
||||
| `source` | _String_ | Source name. |
|
||||
| `volume` | _double_ | Desired volume. Must be between `0.0` and `1.0`. |
|
||||
|
||||
|
||||
@ -1492,14 +1602,14 @@ Get the mute status of a specified source.
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | :---: | ------------|
|
||||
| `source` | _String_ | The name of the source. |
|
||||
| `source` | _String_ | Source name. |
|
||||
|
||||
|
||||
**Response Items:**
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | :---: | ------------|
|
||||
| `name` | _String_ | The name of the source. |
|
||||
| `name` | _String_ | Source name. |
|
||||
| `muted` | _boolean_ | Mute status of the source. |
|
||||
|
||||
|
||||
@ -1516,7 +1626,7 @@ Sets the mute status of a specified source.
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | :---: | ------------|
|
||||
| `source` | _String_ | The name of the source. |
|
||||
| `source` | _String_ | Source name. |
|
||||
| `mute` | _boolean_ | Desired mute status. |
|
||||
|
||||
|
||||
@ -1537,7 +1647,7 @@ Inverts the mute status of a specified source.
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | :---: | ------------|
|
||||
| `source` | _String_ | The name of the source. |
|
||||
| `source` | _String_ | Source name. |
|
||||
|
||||
|
||||
**Response Items:**
|
||||
@ -1557,7 +1667,7 @@ Set the audio sync offset of a specified source.
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | :---: | ------------|
|
||||
| `source` | _String_ | The name of the source. |
|
||||
| `source` | _String_ | Source name. |
|
||||
| `offset` | _int_ | The desired audio sync offset (in nanoseconds). |
|
||||
|
||||
|
||||
@ -1578,14 +1688,14 @@ Get the audio sync offset of a specified source.
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | :---: | ------------|
|
||||
| `source` | _String_ | The name of the source. |
|
||||
| `source` | _String_ | Source name. |
|
||||
|
||||
|
||||
**Response Items:**
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | :---: | ------------|
|
||||
| `name` | _String_ | The name of the source. |
|
||||
| `name` | _String_ | Source name. |
|
||||
| `offset` | _int_ | The audio sync offset (in nanoseconds). |
|
||||
|
||||
|
||||
@ -1602,7 +1712,7 @@ Get settings of the specified source
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | :---: | ------------|
|
||||
| `sourceName` | _String_ | Name of the source item. |
|
||||
| `sourceName` | _String_ | Source name. |
|
||||
| `sourceType` | _String (optional)_ | Type of the specified source. Useful for type-checking if you expect a specific settings schema. |
|
||||
|
||||
|
||||
@ -1612,7 +1722,7 @@ Get settings of the specified source
|
||||
| ---- | :---: | ------------|
|
||||
| `sourceName` | _String_ | Source name |
|
||||
| `sourceType` | _String_ | Type of the specified source |
|
||||
| `sourceSettings` | _Object_ | Source settings. Varying between source types. |
|
||||
| `sourceSettings` | _Object_ | Source settings (varies between source types, may require some probing around). |
|
||||
|
||||
|
||||
---
|
||||
@ -1628,9 +1738,9 @@ Set settings of the specified source.
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | :---: | ------------|
|
||||
| `sourceName` | _String_ | Name of the source item. |
|
||||
| `sourceName` | _String_ | Source name. |
|
||||
| `sourceType` | _String (optional)_ | Type of the specified source. Useful for type-checking to avoid settings a set of settings incompatible with the actual source's type. |
|
||||
| `sourceSettings` | _Object_ | Source settings. Varying between source types. |
|
||||
| `sourceSettings` | _Object_ | Source settings (varies between source types, may require some probing around). |
|
||||
|
||||
|
||||
**Response Items:**
|
||||
@ -1639,7 +1749,7 @@ Set settings of the specified source.
|
||||
| ---- | :---: | ------------|
|
||||
| `sourceName` | _String_ | Source name |
|
||||
| `sourceType` | _String_ | Type of the specified source |
|
||||
| `sourceSettings` | _Object_ | Source settings. Varying between source types. |
|
||||
| `sourceSettings` | _Object_ | Updated source settings |
|
||||
|
||||
|
||||
---
|
||||
@ -1655,14 +1765,14 @@ Get the current properties of a Text GDI Plus source.
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | :---: | ------------|
|
||||
| `scene-name` | _String (optional)_ | Name of the scene to retrieve. Defaults to the current scene. |
|
||||
| `source` | _String_ | Name of the source. |
|
||||
| `source` | _String_ | Source name. |
|
||||
|
||||
|
||||
**Response Items:**
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | :---: | ------------|
|
||||
| `source` | _String_ | Source name. |
|
||||
| `align` | _String_ | Text Alignment ("left", "center", "right"). |
|
||||
| `bk-color` | _int_ | Background color. |
|
||||
| `bk-opacity` | _int_ | Background opacity (0-100). |
|
||||
@ -1690,7 +1800,6 @@ Get the current properties of a Text GDI Plus source.
|
||||
| `text` | _String_ | Text content to be displayed. |
|
||||
| `valign` | _String_ | Text vertical alignment ("top", "center", "bottom"). |
|
||||
| `vertical` | _boolean_ | Vertical text enabled. |
|
||||
| `render` | _boolean_ | Visibility of the scene item. |
|
||||
|
||||
|
||||
---
|
||||
@ -1700,13 +1809,12 @@ Get the current properties of a Text GDI Plus source.
|
||||
|
||||
- Added in v4.1.0
|
||||
|
||||
Get the current properties of a Text GDI Plus source.
|
||||
Set the current properties of a Text GDI Plus source.
|
||||
|
||||
**Request Fields:**
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | :---: | ------------|
|
||||
| `scene-name` | _String (optional)_ | Name of the scene to retrieve. Defaults to the current scene. |
|
||||
| `source` | _String_ | Name of the source. |
|
||||
| `align` | _String (optional)_ | Text Alignment ("left", "center", "right"). |
|
||||
| `bk-color` | _int (optional)_ | Background color. |
|
||||
@ -1738,6 +1846,79 @@ Get the current properties of a Text GDI Plus source.
|
||||
| `render` | _boolean (optional)_ | Visibility of the scene item. |
|
||||
|
||||
|
||||
**Response Items:**
|
||||
|
||||
_No additional response items._
|
||||
|
||||
---
|
||||
|
||||
### GetTextFreetype2Properties
|
||||
|
||||
|
||||
- Added in v4.5.0
|
||||
|
||||
Get the current properties of a Text Freetype 2 source.
|
||||
|
||||
**Request Fields:**
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | :---: | ------------|
|
||||
| `source` | _String_ | Source name. |
|
||||
|
||||
|
||||
**Response Items:**
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | :---: | ------------|
|
||||
| `source` | _String_ | Source name |
|
||||
| `color1` | _int_ | Gradient top color. |
|
||||
| `color2` | _int_ | Gradient bottom color. |
|
||||
| `custom_width` | _int_ | Custom width (0 to disable). |
|
||||
| `drop_shadow` | _boolean_ | Drop shadow. |
|
||||
| `font` | _Object_ | Holds data for the font. Ex: `"font": { "face": "Arial", "flags": 0, "size": 150, "style": "" }` |
|
||||
| `font.face` | _String_ | Font face. |
|
||||
| `font.flags` | _int_ | Font text styling flag. `Bold=1, Italic=2, Bold Italic=3, Underline=5, Strikeout=8` |
|
||||
| `font.size` | _int_ | Font text size. |
|
||||
| `font.style` | _String_ | Font Style (unknown function). |
|
||||
| `from_file` | _boolean_ | Read text from the specified file. |
|
||||
| `log_mode` | _boolean_ | Chat log. |
|
||||
| `outline` | _boolean_ | Outline. |
|
||||
| `text` | _String_ | Text content to be displayed. |
|
||||
| `text_file` | _String_ | File path. |
|
||||
| `word_wrap` | _boolean_ | Word wrap. |
|
||||
|
||||
|
||||
---
|
||||
|
||||
### SetTextFreetype2Properties
|
||||
|
||||
|
||||
- Added in v4.5.0
|
||||
|
||||
Set the current properties of a Text Freetype 2 source.
|
||||
|
||||
**Request Fields:**
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | :---: | ------------|
|
||||
| `source` | _String_ | Source name. |
|
||||
| `color1` | _int (optional)_ | Gradient top color. |
|
||||
| `color2` | _int (optional)_ | Gradient bottom color. |
|
||||
| `custom_width` | _int (optional)_ | Custom width (0 to disable). |
|
||||
| `drop_shadow` | _boolean (optional)_ | Drop shadow. |
|
||||
| `font` | _Object (optional)_ | Holds data for the font. Ex: `"font": { "face": "Arial", "flags": 0, "size": 150, "style": "" }` |
|
||||
| `font.face` | _String (optional)_ | Font face. |
|
||||
| `font.flags` | _int (optional)_ | Font text styling flag. `Bold=1, Italic=2, Bold Italic=3, Underline=5, Strikeout=8` |
|
||||
| `font.size` | _int (optional)_ | Font text size. |
|
||||
| `font.style` | _String (optional)_ | Font Style (unknown function). |
|
||||
| `from_file` | _boolean (optional)_ | Read text from the specified file. |
|
||||
| `log_mode` | _boolean (optional)_ | Chat log. |
|
||||
| `outline` | _boolean (optional)_ | Outline. |
|
||||
| `text` | _String (optional)_ | Text content to be displayed. |
|
||||
| `text_file` | _String (optional)_ | File path. |
|
||||
| `word_wrap` | _boolean (optional)_ | Word wrap. |
|
||||
|
||||
|
||||
**Response Items:**
|
||||
|
||||
_No additional response items._
|
||||
@ -1755,14 +1936,14 @@ Get current properties for a Browser Source.
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | :---: | ------------|
|
||||
| `scene-name` | _String (optional)_ | Name of the scene that the source belongs to. Defaults to the current scene. |
|
||||
| `source` | _String_ | Name of the source. |
|
||||
| `source` | _String_ | Source name. |
|
||||
|
||||
|
||||
**Response Items:**
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | :---: | ------------|
|
||||
| `source` | _String_ | Source name. |
|
||||
| `is_local_file` | _boolean_ | Indicates that a local file is in use. |
|
||||
| `local_file` | _String_ | file path. |
|
||||
| `url` | _String_ | Url. |
|
||||
@ -1771,7 +1952,6 @@ Get current properties for a Browser Source.
|
||||
| `height` | _int_ | Height. |
|
||||
| `fps` | _int_ | Framerate. |
|
||||
| `shutdown` | _boolean_ | Indicates whether the source should be shutdown when not visible. |
|
||||
| `render` | _boolean (optional)_ | Visibility of the scene item. |
|
||||
|
||||
|
||||
---
|
||||
@ -1787,7 +1967,6 @@ Set current properties for a Browser Source.
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | :---: | ------------|
|
||||
| `scene-name` | _String (optional)_ | Name of the scene that the source belongs to. Defaults to the current scene. |
|
||||
| `source` | _String_ | Name of the source. |
|
||||
| `is_local_file` | _boolean (optional)_ | Indicates that a local file is in use. |
|
||||
| `local_file` | _String (optional)_ | file path. |
|
||||
@ -1828,6 +2007,142 @@ _No specified parameters._
|
||||
| `mic-3` | _String (optional)_ | NAme of the third Mic/Aux input source. |
|
||||
|
||||
|
||||
---
|
||||
|
||||
### GetSourceFilters
|
||||
|
||||
|
||||
- Added in v4.5.0
|
||||
|
||||
List filters applied to a source
|
||||
|
||||
**Request Fields:**
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | :---: | ------------|
|
||||
| `sourceName` | _String_ | Source name |
|
||||
|
||||
|
||||
**Response Items:**
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | :---: | ------------|
|
||||
| `filters` | _Array<Object>_ | List of filters for the specified source |
|
||||
| `filters.*.type` | _String_ | Filter type |
|
||||
| `filters.*.name` | _String_ | Filter name |
|
||||
| `filters.*.settings` | _Object_ | Filter settings |
|
||||
|
||||
|
||||
---
|
||||
|
||||
### AddFilterToSource
|
||||
|
||||
|
||||
- Added in v4.5.0
|
||||
|
||||
Add a new filter to a source. Available source types along with their settings properties are available from `GetSourceTypesList`.
|
||||
|
||||
**Request Fields:**
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | :---: | ------------|
|
||||
| `sourceName` | _String_ | Name of the source on which the filter is added |
|
||||
| `filterName` | _String_ | Name of the new filter |
|
||||
| `filterType` | _String_ | Filter type |
|
||||
| `filterSettings` | _Object_ | Filter settings |
|
||||
|
||||
|
||||
**Response Items:**
|
||||
|
||||
_No additional response items._
|
||||
|
||||
---
|
||||
|
||||
### RemoveFilterFromSource
|
||||
|
||||
|
||||
- Added in v4.5.0
|
||||
|
||||
Remove a filter from a source
|
||||
|
||||
**Request Fields:**
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | :---: | ------------|
|
||||
| `sourceName` | _String_ | Name of the source from which the specified filter is removed |
|
||||
| `filterName` | _String_ | Name of the filter to remove |
|
||||
|
||||
|
||||
**Response Items:**
|
||||
|
||||
_No additional response items._
|
||||
|
||||
---
|
||||
|
||||
### ReorderSourceFilter
|
||||
|
||||
|
||||
- Added in v4.5.0
|
||||
|
||||
Move a filter in the chain (absolute index positioning)
|
||||
|
||||
**Request Fields:**
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | :---: | ------------|
|
||||
| `sourceName` | _String_ | Name of the source to which the filter belongs |
|
||||
| `filterName` | _String_ | Name of the filter to reorder |
|
||||
| `newIndex` | _Integer_ | Desired position of the filter in the chain |
|
||||
|
||||
|
||||
**Response Items:**
|
||||
|
||||
_No additional response items._
|
||||
|
||||
---
|
||||
|
||||
### MoveSourceFilter
|
||||
|
||||
|
||||
- Added in v4.5.0
|
||||
|
||||
Move a filter in the chain (relative positioning)
|
||||
|
||||
**Request Fields:**
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | :---: | ------------|
|
||||
| `sourceName` | _String_ | Name of the source to which the filter belongs |
|
||||
| `filterName` | _String_ | Name of the filter to reorder |
|
||||
| `movementType` | _String_ | How to move the filter around in the source's filter chain. Either "up", "down", "top" or "bottom". |
|
||||
|
||||
|
||||
**Response Items:**
|
||||
|
||||
_No additional response items._
|
||||
|
||||
---
|
||||
|
||||
### SetSourceFilterSettings
|
||||
|
||||
|
||||
- Added in v4.5.0
|
||||
|
||||
Update settings of a filter
|
||||
|
||||
**Request Fields:**
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | :---: | ------------|
|
||||
| `sourceName` | _String_ | Name of the source to which the filter belongs |
|
||||
| `filterName` | _String_ | Name of the filter to reconfigure |
|
||||
| `filterSettings` | _Object_ | New settings. These will be merged to the current filter settings. |
|
||||
|
||||
|
||||
**Response Items:**
|
||||
|
||||
_No additional response items._
|
||||
|
||||
---
|
||||
|
||||
## Streaming
|
||||
@ -1966,7 +2281,7 @@ _No specified parameters._
|
||||
| `settings` | _Object_ | Stream settings object. |
|
||||
| `settings.server` | _String_ | The publish URL. |
|
||||
| `settings.key` | _String_ | The publish key of the stream. |
|
||||
| `settings.use-auth` | _boolean_ | Indicates whether audentication should be used when connecting to the streaming server. |
|
||||
| `settings.use-auth` | _boolean_ | Indicates whether authentication should be used when connecting to the streaming server. |
|
||||
| `settings.username` | _String_ | The username to use when accessing the streaming server. Only present if `use-auth` is `true`. |
|
||||
| `settings.password` | _String_ | The password to use when accessing the streaming server. Only present if `use-auth` is `true`. |
|
||||
|
||||
@ -2029,7 +2344,7 @@ _No specified parameters._
|
||||
| Name | Type | Description |
|
||||
| ---- | :---: | ------------|
|
||||
| `name` | _String_ | The name of the active preview scene. |
|
||||
| `sources` | _Source\|Array_ | |
|
||||
| `sources` | _Array<Source>_ | |
|
||||
|
||||
|
||||
---
|
||||
@ -2147,8 +2462,8 @@ _No specified parameters._
|
||||
| Name | Type | Description |
|
||||
| ---- | :---: | ------------|
|
||||
| `current-transition` | _String_ | Name of the currently active transition. |
|
||||
| `transitions` | _Object\|Array_ | List of transitions. |
|
||||
| `transitions[].name` | _String_ | Name of the transition. |
|
||||
| `transitions` | _Array<Object>_ | List of transitions. |
|
||||
| `transitions.*.name` | _String_ | Name of the transition. |
|
||||
|
||||
|
||||
---
|
||||
|
@ -1,12 +1,11 @@
|
||||
# obs-websocket 4.3.2 protocol reference
|
||||
# obs-websocket 4.5.0 protocol reference
|
||||
|
||||
# General Introduction
|
||||
Messages are exchanged between the client and the server as JSON objects.
|
||||
This protocol is based on the original OBS Remote protocol created by Bill Hamilton, with new commands specific to OBS Studio.
|
||||
|
||||
|
||||
# Authentication
|
||||
OBSWebSocket uses SHA256 to transmit credentials.
|
||||
`obs-websocket` uses SHA256 to transmit credentials.
|
||||
|
||||
A request for [`GetAuthRequired`](#getauthrequired) returns two elements:
|
||||
- A `challenge`: a random string that will be used to generate the auth response.
|
||||
|
2
docs/partials/typedefsHeader.md
Normal file
2
docs/partials/typedefsHeader.md
Normal file
@ -0,0 +1,2 @@
|
||||
# Typedefs
|
||||
These are complex types, such as `Source` and `Scene`, which are used as arguments or return values in multiple requests and/or events.
|
@ -7,6 +7,19 @@
|
||||
|
||||
|
||||
|
||||
{{#read "partials/typedefsHeader.md"}}{{/read}}
|
||||
|
||||
{{#each typedefs}}
|
||||
## {{typedefs.0.name}}
|
||||
| Name | Type | Description |
|
||||
| ---- | :---: | ------------|
|
||||
{{#each properties}}
|
||||
| `{{name}}` | _{{depipe type}}_ | {{{depipe description}}} |
|
||||
{{/each}}
|
||||
{{/each}}
|
||||
|
||||
|
||||
|
||||
{{#read "partials/eventsHeader.md"}}{{/read}}
|
||||
|
||||
{{#each events}}
|
||||
|
@ -2,7 +2,7 @@
|
||||
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
|
||||
|
||||
#define MyAppName "obs-websocket"
|
||||
#define MyAppVersion "4.3.3"
|
||||
#define MyAppVersion "4.5.0"
|
||||
#define MyAppPublisher "Stephane Lepin"
|
||||
#define MyAppURL "http://github.com/Palakis/obs-websocket"
|
||||
|
||||
@ -20,7 +20,7 @@ AppSupportURL={#MyAppURL}
|
||||
AppUpdatesURL={#MyAppURL}
|
||||
DefaultDirName={code:GetDirName}
|
||||
DefaultGroupName={#MyAppName}
|
||||
OutputBaseFilename=obs-websocket-{#MyAppVersion}-Windows-Installer
|
||||
OutputBaseFilename=obs-websocket-Windows-Installer
|
||||
Compression=lzma
|
||||
SolidCompression=yes
|
||||
LicenseFile=..\LICENSE
|
||||
|
@ -16,11 +16,11 @@ You should have received a copy of the GNU General Public License along
|
||||
with this program. If not, see <https://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
#include <mbedtls/base64.h>
|
||||
#include <mbedtls/sha256.h>
|
||||
#include <obs-frontend-api.h>
|
||||
#include <util/config-file.h>
|
||||
#include <string>
|
||||
|
||||
#include <QCryptographicHash>
|
||||
#include <QTime>
|
||||
|
||||
#define SECTION_NAME "WebsocketAPI"
|
||||
#define PARAM_ENABLE "ServerEnabled"
|
||||
@ -48,6 +48,8 @@ Config::Config() :
|
||||
Salt(""),
|
||||
SettingsLoaded(false)
|
||||
{
|
||||
qsrand(QTime::currentTime().msec());
|
||||
|
||||
// OBS Config defaults
|
||||
config_t* obsConfig = obs_frontend_get_global_config();
|
||||
if (obsConfig) {
|
||||
@ -69,19 +71,15 @@ Config::Config() :
|
||||
SECTION_NAME, PARAM_SALT, QT_TO_UTF8(Salt));
|
||||
}
|
||||
|
||||
mbedtls_entropy_init(&entropy);
|
||||
mbedtls_ctr_drbg_init(&rng);
|
||||
mbedtls_ctr_drbg_seed(&rng, mbedtls_entropy_func, &entropy, nullptr, 0);
|
||||
|
||||
SessionChallenge = GenerateSalt();
|
||||
}
|
||||
|
||||
Config::~Config() {
|
||||
mbedtls_ctr_drbg_free(&rng);
|
||||
mbedtls_entropy_free(&entropy);
|
||||
Config::~Config()
|
||||
{
|
||||
}
|
||||
|
||||
void Config::Load() {
|
||||
void Config::Load()
|
||||
{
|
||||
config_t* obsConfig = obs_frontend_get_global_config();
|
||||
|
||||
ServerEnabled = config_get_bool(obsConfig, SECTION_NAME, PARAM_ENABLE);
|
||||
@ -95,7 +93,8 @@ void Config::Load() {
|
||||
Salt = config_get_string(obsConfig, SECTION_NAME, PARAM_SALT);
|
||||
}
|
||||
|
||||
void Config::Save() {
|
||||
void Config::Save()
|
||||
{
|
||||
config_t* obsConfig = obs_frontend_get_global_config();
|
||||
|
||||
config_set_bool(obsConfig, SECTION_NAME, PARAM_ENABLE, ServerEnabled);
|
||||
@ -113,46 +112,42 @@ void Config::Save() {
|
||||
config_save(obsConfig);
|
||||
}
|
||||
|
||||
QString Config::GenerateSalt() {
|
||||
QString Config::GenerateSalt()
|
||||
{
|
||||
// Generate 32 random chars
|
||||
unsigned char* randomChars = (unsigned char*)bzalloc(32);
|
||||
mbedtls_ctr_drbg_random(&rng, randomChars, 32);
|
||||
const size_t randomCount = 32;
|
||||
QByteArray randomChars;
|
||||
for (size_t i = 0; i < randomCount; i++) {
|
||||
randomChars.append((char)qrand());
|
||||
}
|
||||
|
||||
// Convert the 32 random chars to a base64 string
|
||||
char* salt = (char*)bzalloc(64);
|
||||
size_t saltBytes;
|
||||
mbedtls_base64_encode(
|
||||
(unsigned char*)salt, 64, &saltBytes,
|
||||
randomChars, 32);
|
||||
QString salt = randomChars.toBase64();
|
||||
|
||||
bfree(randomChars);
|
||||
return salt;
|
||||
}
|
||||
|
||||
QString Config::GenerateSecret(QString password, QString salt) {
|
||||
QString Config::GenerateSecret(QString password, QString salt)
|
||||
{
|
||||
// Concatenate the password and the salt
|
||||
QString passAndSalt = "";
|
||||
passAndSalt += password;
|
||||
passAndSalt += salt;
|
||||
|
||||
// Generate a SHA256 hash of the password
|
||||
unsigned char* challengeHash = (unsigned char*)bzalloc(32);
|
||||
mbedtls_sha256(
|
||||
(unsigned char*)passAndSalt.toUtf8().constData(), passAndSalt.length(),
|
||||
challengeHash, 0);
|
||||
// Generate a SHA256 hash of the password and salt
|
||||
auto challengeHash = QCryptographicHash::hash(
|
||||
passAndSalt.toUtf8(),
|
||||
QCryptographicHash::Algorithm::Sha256
|
||||
);
|
||||
|
||||
// Encode SHA256 hash to Base64
|
||||
char* challenge = (char*)bzalloc(64);
|
||||
size_t challengeBytes = 0;
|
||||
mbedtls_base64_encode(
|
||||
(unsigned char*)challenge, 64, &challengeBytes,
|
||||
challengeHash, 32);
|
||||
QString challenge = challengeHash.toBase64();
|
||||
|
||||
bfree(challengeHash);
|
||||
return challenge;
|
||||
}
|
||||
|
||||
void Config::SetPassword(QString password) {
|
||||
void Config::SetPassword(QString password)
|
||||
{
|
||||
QString newSalt = GenerateSalt();
|
||||
QString newChallenge = GenerateSecret(password, newSalt);
|
||||
|
||||
@ -160,37 +155,32 @@ void Config::SetPassword(QString password) {
|
||||
this->Secret = newChallenge;
|
||||
}
|
||||
|
||||
bool Config::CheckAuth(QString response) {
|
||||
bool Config::CheckAuth(QString response)
|
||||
{
|
||||
// Concatenate auth secret with the challenge sent to the user
|
||||
QString challengeAndResponse = "";
|
||||
challengeAndResponse += Secret;
|
||||
challengeAndResponse += SessionChallenge;
|
||||
|
||||
// Generate a SHA256 hash of challengeAndResponse
|
||||
unsigned char* hash = (unsigned char*)bzalloc(32);
|
||||
mbedtls_sha256(
|
||||
(unsigned char*)challengeAndResponse.toUtf8().constData(),
|
||||
challengeAndResponse.length(),
|
||||
hash, 0);
|
||||
auto hash = QCryptographicHash::hash(
|
||||
challengeAndResponse.toUtf8(),
|
||||
QCryptographicHash::Algorithm::Sha256
|
||||
);
|
||||
|
||||
// Encode the SHA256 hash to Base64
|
||||
char* expectedResponse = (char*)bzalloc(64);
|
||||
size_t base64_size = 0;
|
||||
mbedtls_base64_encode(
|
||||
(unsigned char*)expectedResponse, 64, &base64_size,
|
||||
hash, 32);
|
||||
QString expectedResponse = hash.toBase64();
|
||||
|
||||
bool authSuccess = false;
|
||||
if (response == QString(expectedResponse)) {
|
||||
if (response == expectedResponse) {
|
||||
SessionChallenge = GenerateSalt();
|
||||
authSuccess = true;
|
||||
}
|
||||
|
||||
bfree(hash);
|
||||
bfree(expectedResponse);
|
||||
return authSuccess;
|
||||
}
|
||||
|
||||
Config* Config::Current() {
|
||||
Config* Config::Current()
|
||||
{
|
||||
return _instance;
|
||||
}
|
||||
|
@ -21,9 +21,6 @@ with this program. If not, see <https://www.gnu.org/licenses/>
|
||||
|
||||
#include <QString>
|
||||
|
||||
#include <mbedtls/entropy.h>
|
||||
#include <mbedtls/ctr_drbg.h>
|
||||
|
||||
class Config {
|
||||
public:
|
||||
Config();
|
||||
@ -53,8 +50,6 @@ class Config {
|
||||
|
||||
private:
|
||||
static Config* _instance;
|
||||
mbedtls_entropy_context entropy;
|
||||
mbedtls_ctr_drbg_context rng;
|
||||
};
|
||||
|
||||
#endif // CONFIG_H
|
@ -103,6 +103,22 @@ obs_data_t* Utils::GetSceneItemData(obs_sceneitem_t* item) {
|
||||
return data;
|
||||
}
|
||||
|
||||
obs_sceneitem_t* Utils::GetSceneItemFromItem(obs_source_t* source, obs_data_t* item) {
|
||||
OBSSceneItem sceneItem;
|
||||
if (obs_data_has_user_value(item, "id")) {
|
||||
sceneItem = GetSceneItemFromId(source, obs_data_get_int(item, "id"));
|
||||
if (obs_data_has_user_value(item, "name") &&
|
||||
(QString)obs_source_get_name(obs_sceneitem_get_source(sceneItem)) !=
|
||||
(QString)obs_data_get_string(item, "name")) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
else if (obs_data_has_user_value(item, "name")) {
|
||||
sceneItem = GetSceneItemFromName(source, obs_data_get_string(item, "name"));
|
||||
}
|
||||
return sceneItem;
|
||||
}
|
||||
|
||||
obs_sceneitem_t* Utils::GetSceneItemFromName(obs_source_t* source, QString name) {
|
||||
struct current_search {
|
||||
QString query;
|
||||
@ -139,6 +155,39 @@ obs_sceneitem_t* Utils::GetSceneItemFromName(obs_source_t* source, QString name)
|
||||
return search.result;
|
||||
}
|
||||
|
||||
obs_sceneitem_t* Utils::GetSceneItemFromId(obs_source_t* source, size_t id) {
|
||||
struct current_search {
|
||||
size_t query;
|
||||
obs_sceneitem_t* result;
|
||||
};
|
||||
|
||||
current_search search;
|
||||
search.query = id;
|
||||
search.result = nullptr;
|
||||
|
||||
OBSScene scene = obs_scene_from_source(source);
|
||||
if (!scene)
|
||||
return nullptr;
|
||||
|
||||
obs_scene_enum_items(scene, [](
|
||||
obs_scene_t* scene,
|
||||
obs_sceneitem_t* currentItem,
|
||||
void* param)
|
||||
{
|
||||
current_search* search = static_cast<current_search*>(param);
|
||||
|
||||
if (obs_sceneitem_get_id(currentItem) == search->query) {
|
||||
search->result = currentItem;
|
||||
obs_sceneitem_addref(search->result);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}, &search);
|
||||
|
||||
return search.result;
|
||||
}
|
||||
|
||||
bool Utils::IsValidAlignment(const uint32_t alignment) {
|
||||
switch (alignment) {
|
||||
case OBS_ALIGN_CENTER:
|
||||
|
@ -39,6 +39,8 @@ class Utils {
|
||||
static obs_data_t* GetSceneItemData(obs_sceneitem_t* item);
|
||||
static obs_sceneitem_t* GetSceneItemFromName(
|
||||
obs_source_t* source, QString name);
|
||||
static obs_sceneitem_t* GetSceneItemFromId(obs_source_t* source, size_t id);
|
||||
static obs_sceneitem_t* GetSceneItemFromItem(obs_source_t* source, obs_data_t* item);
|
||||
static obs_source_t* GetTransitionFromName(QString transitionName);
|
||||
static obs_source_t* GetSceneFromNameOrCurrent(QString sceneName);
|
||||
|
||||
|
104
src/WSEvents.cpp
104
src/WSEvents.cpp
@ -80,12 +80,7 @@ WSEvents::WSEvents(WSServer* srv) {
|
||||
this, SLOT(Heartbeat()));
|
||||
statusTimer->start(2000); // equal to frontend's constant BITRATE_UPDATE_SECONDS
|
||||
|
||||
QListWidget* sceneList = Utils::GetSceneListControl();
|
||||
connect(sceneList, SIGNAL(currentItemChanged(QListWidgetItem*, QListWidgetItem*)),
|
||||
this, SLOT(SelectedSceneChanged(QListWidgetItem*, QListWidgetItem*)));
|
||||
|
||||
currentScene = nullptr;
|
||||
currentTransition = nullptr;
|
||||
|
||||
QTimer::singleShot(1000, this, SLOT(deferredInitOperations()));
|
||||
|
||||
@ -103,8 +98,7 @@ WSEvents::~WSEvents() {
|
||||
}
|
||||
|
||||
void WSEvents::deferredInitOperations() {
|
||||
OBSSourceAutoRelease transition = obs_frontend_get_current_transition();
|
||||
connectTransitionSignals(transition);
|
||||
hookTransitionBeginEvent();
|
||||
|
||||
OBSSourceAutoRelease scene = obs_frontend_get_current_scene();
|
||||
connectSceneSignals(scene);
|
||||
@ -123,6 +117,7 @@ void WSEvents::FrontendEventHandler(enum obs_frontend_event event, void* private
|
||||
owner->OnSceneListChange();
|
||||
}
|
||||
else if (event == OBS_FRONTEND_EVENT_SCENE_COLLECTION_CHANGED) {
|
||||
owner->hookTransitionBeginEvent();
|
||||
owner->OnSceneCollectionChange();
|
||||
}
|
||||
else if (event == OBS_FRONTEND_EVENT_SCENE_COLLECTION_LIST_CHANGED) {
|
||||
@ -132,6 +127,7 @@ void WSEvents::FrontendEventHandler(enum obs_frontend_event event, void* private
|
||||
owner->OnTransitionChange();
|
||||
}
|
||||
else if (event == OBS_FRONTEND_EVENT_TRANSITION_LIST_CHANGED) {
|
||||
owner->hookTransitionBeginEvent();
|
||||
owner->OnTransitionListChange();
|
||||
}
|
||||
else if (event == OBS_FRONTEND_EVENT_PROFILE_CHANGED) {
|
||||
@ -186,9 +182,11 @@ void WSEvents::FrontendEventHandler(enum obs_frontend_event event, void* private
|
||||
else if (event == OBS_FRONTEND_EVENT_STUDIO_MODE_DISABLED) {
|
||||
owner->OnStudioModeSwitched(false);
|
||||
}
|
||||
else if (event == OBS_FRONTEND_EVENT_PREVIEW_SCENE_CHANGED) {
|
||||
owner->OnPreviewSceneChanged();
|
||||
}
|
||||
else if (event == OBS_FRONTEND_EVENT_EXIT) {
|
||||
owner->connectSceneSignals(nullptr);
|
||||
owner->connectTransitionSignals(nullptr);
|
||||
owner->OnExit();
|
||||
}
|
||||
}
|
||||
@ -222,29 +220,18 @@ void WSEvents::broadcastUpdate(const char* updateType,
|
||||
blog(LOG_DEBUG, "Update << '%s'", json.toUtf8().constData());
|
||||
}
|
||||
|
||||
void WSEvents::connectTransitionSignals(obs_source_t* transition) {
|
||||
signal_handler_t* sh = nullptr;
|
||||
void WSEvents::hookTransitionBeginEvent() {
|
||||
obs_frontend_source_list transitions = {};
|
||||
obs_frontend_get_transitions(&transitions);
|
||||
|
||||
if (currentTransition) {
|
||||
sh = obs_source_get_signal_handler(currentTransition);
|
||||
signal_handler_disconnect(sh,
|
||||
"transition_start", OnTransitionBegin, this);
|
||||
for (int i = 0; i < transitions.sources.num; i++) {
|
||||
obs_source_t* transition = transitions.sources.array[i];
|
||||
signal_handler_t* sh = obs_source_get_signal_handler(transition);
|
||||
signal_handler_disconnect(sh, "transition_start", OnTransitionBegin, this);
|
||||
signal_handler_connect(sh, "transition_start", OnTransitionBegin, this);
|
||||
}
|
||||
|
||||
currentTransition = transition;
|
||||
|
||||
if (currentTransition) {
|
||||
if (!transitionIsCut(transition)) {
|
||||
currentTransition = transition;
|
||||
|
||||
sh = obs_source_get_signal_handler(currentTransition);
|
||||
signal_handler_connect(sh,
|
||||
"transition_start", OnTransitionBegin, this);
|
||||
}
|
||||
else {
|
||||
currentTransition = nullptr;
|
||||
}
|
||||
}
|
||||
obs_frontend_source_list_free(&transitions);
|
||||
}
|
||||
|
||||
void WSEvents::connectSceneSignals(obs_source_t* scene) {
|
||||
@ -305,7 +292,7 @@ const char* WSEvents::GetRecordingTimecode() {
|
||||
* Indicates a scene change.
|
||||
*
|
||||
* @return {String} `scene-name` The new scene.
|
||||
* @return {Array} `sources` List of sources in the new scene.
|
||||
* @return {Array<Source>} `sources` List of sources in the new scene. Same specification as [`GetCurrentScene`](#getcurrentscene).
|
||||
*
|
||||
* @api events
|
||||
* @name SwitchScenes
|
||||
@ -322,13 +309,6 @@ void WSEvents::OnSceneChange() {
|
||||
obs_data_set_array(data, "sources", sceneItems);
|
||||
|
||||
broadcastUpdate("SwitchScenes", data);
|
||||
|
||||
// Dirty fix : OBS blocks signals when swapping scenes in Studio Mode
|
||||
// after transition end, so SelectedSceneChanged is never called...
|
||||
if (obs_frontend_preview_program_mode_active()) {
|
||||
QListWidget* list = Utils::GetSceneListControl();
|
||||
SelectedSceneChanged(list->currentItem(), nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -356,7 +336,6 @@ void WSEvents::OnSceneCollectionChange() {
|
||||
broadcastUpdate("SceneCollectionChanged");
|
||||
|
||||
currentScene = nullptr;
|
||||
currentTransition = nullptr;
|
||||
|
||||
OnTransitionListChange();
|
||||
OnTransitionChange();
|
||||
@ -389,7 +368,6 @@ void WSEvents::OnSceneCollectionListChange() {
|
||||
*/
|
||||
void WSEvents::OnTransitionChange() {
|
||||
OBSSourceAutoRelease currentTransition = obs_frontend_get_current_transition();
|
||||
connectTransitionSignals(currentTransition);
|
||||
|
||||
OBSDataAutoRelease data = obs_data_create();
|
||||
obs_data_set_string(data, "transition-name",
|
||||
@ -571,7 +549,7 @@ void WSEvents::OnReplayStarted() {
|
||||
}
|
||||
|
||||
/**
|
||||
* A request to start the replay buffer has been issued.
|
||||
* A request to stop the replay buffer has been issued.
|
||||
*
|
||||
* @api events
|
||||
* @name ReplayStopping
|
||||
@ -679,7 +657,7 @@ void WSEvents::StreamStatus() {
|
||||
/**
|
||||
* Emitted every 2 seconds after enabling it by calling SetHeartbeat.
|
||||
*
|
||||
* @return {boolean} `pulse` Toggles between every JSON meassage as an "I am alive" indicator.
|
||||
* @return {boolean} `pulse` Toggles between every JSON message as an "I am alive" indicator.
|
||||
* @return {string (optional)} `current-profile` Current active profile.
|
||||
* @return {string (optional)} `current-scene` Current active scene.
|
||||
* @return {boolean (optional)} `streaming` Current streaming state.
|
||||
@ -755,6 +733,8 @@ void WSEvents::TransitionDurationChanged(int ms) {
|
||||
*
|
||||
* @return {String} `name` Transition name.
|
||||
* @return {int} `duration` Transition duration (in milliseconds).
|
||||
* @return {String} `from-scene` Source scene of the transition
|
||||
* @return {String} `to-scene` Destination scene of the transition
|
||||
*
|
||||
* @api events
|
||||
* @name TransitionBegin
|
||||
@ -762,14 +742,39 @@ void WSEvents::TransitionDurationChanged(int ms) {
|
||||
* @since 4.0.0
|
||||
*/
|
||||
void WSEvents::OnTransitionBegin(void* param, calldata_t* data) {
|
||||
UNUSED_PARAMETER(data);
|
||||
WSEvents* instance = static_cast<WSEvents*>(param);
|
||||
|
||||
OBSSourceAutoRelease currentTransition = obs_frontend_get_current_transition();
|
||||
OBSSource transition = (obs_source_t*)calldata_get_ptr(data, "source");
|
||||
if (!transition) return;
|
||||
|
||||
// Detect if transition is the global transition or a transition override.
|
||||
// Fetching the duration is different depending on the case.
|
||||
OBSSourceAutoRelease sourceScene = obs_transition_get_source(transition, OBS_TRANSITION_SOURCE_A);
|
||||
OBSSourceAutoRelease destinationScene = obs_transition_get_active_source(transition);
|
||||
OBSDataAutoRelease destinationSettings = obs_source_get_private_settings(destinationScene);
|
||||
int duration = -1;
|
||||
if (obs_data_has_default_value(destinationSettings, "transition_duration") ||
|
||||
obs_data_has_user_value(destinationSettings, "transition_duration"))
|
||||
{
|
||||
duration = obs_data_get_int(destinationSettings, "transition_duration");
|
||||
} else {
|
||||
duration = Utils::GetTransitionDuration();
|
||||
}
|
||||
|
||||
OBSDataAutoRelease fields = obs_data_create();
|
||||
obs_data_set_string(fields, "name", obs_source_get_name(currentTransition));
|
||||
obs_data_set_int(fields, "duration", Utils::GetTransitionDuration());
|
||||
obs_data_set_string(fields, "name", obs_source_get_name(transition));
|
||||
if (duration >= 0) {
|
||||
obs_data_set_int(fields, "duration", duration);
|
||||
} else {
|
||||
blog(LOG_WARNING, "OnTransitionBegin: duration is negative !");
|
||||
}
|
||||
|
||||
if (sourceScene) {
|
||||
obs_data_set_string(fields, "from-scene", obs_source_get_name(sourceScene));
|
||||
}
|
||||
if (destinationScene) {
|
||||
obs_data_set_string(fields, "to-scene", obs_source_get_name(destinationScene));
|
||||
}
|
||||
|
||||
instance->broadcastUpdate("TransitionBegin", fields);
|
||||
}
|
||||
@ -902,24 +907,23 @@ void WSEvents::OnSceneItemVisibilityChanged(void* param, calldata_t* data) {
|
||||
* The selected preview scene has changed (only available in Studio Mode).
|
||||
*
|
||||
* @return {String} `scene-name` Name of the scene being previewed.
|
||||
* @return {Source|Array} `sources` List of sources composing the scene. Same specification as [`GetCurrentScene`](#getcurrentscene).
|
||||
* @return {Array<Source>} `sources` List of sources composing the scene. Same specification as [`GetCurrentScene`](#getcurrentscene).
|
||||
*
|
||||
* @api events
|
||||
* @name PreviewSceneChanged
|
||||
* @category studio mode
|
||||
* @since 4.1.0
|
||||
*/
|
||||
void WSEvents::SelectedSceneChanged(QListWidgetItem* current, QListWidgetItem* prev) {
|
||||
void WSEvents::OnPreviewSceneChanged() {
|
||||
if (obs_frontend_preview_program_mode_active()) {
|
||||
OBSScene scene = Utils::SceneListItemToScene(current);
|
||||
OBSSourceAutoRelease scene = obs_frontend_get_current_preview_scene();
|
||||
if (!scene)
|
||||
return;
|
||||
|
||||
OBSSource sceneSource = obs_scene_get_source(scene);
|
||||
OBSDataArrayAutoRelease sceneItems = Utils::GetSceneItems(sceneSource);
|
||||
OBSDataArrayAutoRelease sceneItems = Utils::GetSceneItems(scene);
|
||||
|
||||
OBSDataAutoRelease data = obs_data_create();
|
||||
obs_data_set_string(data, "scene-name", obs_source_get_name(sceneSource));
|
||||
obs_data_set_string(data, "scene-name", obs_source_get_name(scene));
|
||||
obs_data_set_array(data, "sources", sceneItems);
|
||||
|
||||
broadcastUpdate("PreviewSceneChanged", data);
|
||||
|
@ -33,9 +33,10 @@ class WSEvents : public QObject {
|
||||
static void FrontendEventHandler(
|
||||
enum obs_frontend_event event, void* privateData);
|
||||
static WSEvents* Instance;
|
||||
void connectTransitionSignals(obs_source_t* transition);
|
||||
void connectSceneSignals(obs_source_t* scene);
|
||||
|
||||
void hookTransitionBeginEvent();
|
||||
|
||||
uint64_t GetStreamingTime();
|
||||
const char* GetStreamingTimecode();
|
||||
uint64_t GetRecordingTime();
|
||||
@ -48,13 +49,10 @@ class WSEvents : public QObject {
|
||||
void StreamStatus();
|
||||
void Heartbeat();
|
||||
void TransitionDurationChanged(int ms);
|
||||
void SelectedSceneChanged(
|
||||
QListWidgetItem* current, QListWidgetItem* prev);
|
||||
|
||||
private:
|
||||
WSServer* _srv;
|
||||
OBSSource currentScene;
|
||||
OBSSource currentTransition;
|
||||
|
||||
bool pulse;
|
||||
|
||||
@ -97,6 +95,7 @@ class WSEvents : public QObject {
|
||||
void OnReplayStopped();
|
||||
|
||||
void OnStudioModeSwitched(bool enabled);
|
||||
void OnPreviewSceneChanged();
|
||||
|
||||
void OnExit();
|
||||
|
||||
|
@ -46,6 +46,9 @@ QHash<QString, void(*)(WSRequestHandler*)> WSRequestHandler::messageMap {
|
||||
{ "GetSceneItemProperties", WSRequestHandler::HandleGetSceneItemProperties },
|
||||
{ "SetSceneItemProperties", WSRequestHandler::HandleSetSceneItemProperties },
|
||||
{ "ResetSceneItem", WSRequestHandler::HandleResetSceneItem },
|
||||
{ "DeleteSceneItem", WSRequestHandler::HandleDeleteSceneItem },
|
||||
{ "DuplicateSceneItem", WSRequestHandler::HandleDuplicateSceneItem },
|
||||
{ "ReorderSceneItems", WSRequestHandler::HandleReorderSceneItems },
|
||||
|
||||
{ "GetStreamingStatus", WSRequestHandler::HandleGetStreamingStatus },
|
||||
{ "StartStopStreaming", WSRequestHandler::HandleStartStopStreaming },
|
||||
@ -82,6 +85,13 @@ QHash<QString, void(*)(WSRequestHandler*)> WSRequestHandler::messageMap {
|
||||
{ "GetSourceSettings", WSRequestHandler::HandleGetSourceSettings },
|
||||
{ "SetSourceSettings", WSRequestHandler::HandleSetSourceSettings },
|
||||
|
||||
{ "GetSourceFilters", WSRequestHandler::HandleGetSourceFilters },
|
||||
{ "AddFilterToSource", WSRequestHandler::HandleAddFilterToSource },
|
||||
{ "RemoveFilterFromSource", WSRequestHandler::HandleRemoveFilterFromSource },
|
||||
{ "ReorderSourceFilter", WSRequestHandler::HandleReorderSourceFilter },
|
||||
{ "MoveSourceFilter", WSRequestHandler::HandleMoveSourceFilter },
|
||||
{ "SetSourceFilterSettings", WSRequestHandler::HandleSetSourceFilterSettings },
|
||||
|
||||
{ "SetCurrentSceneCollection", WSRequestHandler::HandleSetCurrentSceneCollection },
|
||||
{ "GetCurrentSceneCollection", WSRequestHandler::HandleGetCurrentSceneCollection },
|
||||
{ "ListSceneCollections", WSRequestHandler::HandleListSceneCollections },
|
||||
@ -105,6 +115,9 @@ QHash<QString, void(*)(WSRequestHandler*)> WSRequestHandler::messageMap {
|
||||
{ "SetTextGDIPlusProperties", WSRequestHandler::HandleSetTextGDIPlusProperties },
|
||||
{ "GetTextGDIPlusProperties", WSRequestHandler::HandleGetTextGDIPlusProperties },
|
||||
|
||||
{ "SetTextFreetype2Properties", WSRequestHandler::HandleSetTextFreetype2Properties },
|
||||
{ "GetTextFreetype2Properties", WSRequestHandler::HandleGetTextFreetype2Properties },
|
||||
|
||||
{ "GetBrowserSourceProperties", WSRequestHandler::HandleGetBrowserSourceProperties },
|
||||
{ "SetBrowserSourceProperties", WSRequestHandler::HandleSetBrowserSourceProperties }
|
||||
};
|
||||
|
@ -73,6 +73,9 @@ class WSRequestHandler : public QObject {
|
||||
static void HandleGetSceneItemProperties(WSRequestHandler* req);
|
||||
static void HandleSetSceneItemProperties(WSRequestHandler* req);
|
||||
static void HandleResetSceneItem(WSRequestHandler* req);
|
||||
static void HandleDuplicateSceneItem(WSRequestHandler* req);
|
||||
static void HandleDeleteSceneItem(WSRequestHandler* req);
|
||||
static void HandleReorderSceneItems(WSRequestHandler* req);
|
||||
|
||||
static void HandleGetStreamingStatus(WSRequestHandler* req);
|
||||
static void HandleStartStopStreaming(WSRequestHandler* req);
|
||||
@ -107,6 +110,13 @@ class WSRequestHandler : public QObject {
|
||||
static void HandleGetSourceSettings(WSRequestHandler* req);
|
||||
static void HandleSetSourceSettings(WSRequestHandler* req);
|
||||
|
||||
static void HandleGetSourceFilters(WSRequestHandler* req);
|
||||
static void HandleAddFilterToSource(WSRequestHandler* req);
|
||||
static void HandleRemoveFilterFromSource(WSRequestHandler* req);
|
||||
static void HandleReorderSourceFilter(WSRequestHandler* req);
|
||||
static void HandleMoveSourceFilter(WSRequestHandler* req);
|
||||
static void HandleSetSourceFilterSettings(WSRequestHandler* req);
|
||||
|
||||
static void HandleSetCurrentSceneCollection(WSRequestHandler* req);
|
||||
static void HandleGetCurrentSceneCollection(WSRequestHandler* req);
|
||||
static void HandleListSceneCollections(WSRequestHandler* req);
|
||||
@ -132,6 +142,10 @@ class WSRequestHandler : public QObject {
|
||||
|
||||
static void HandleSetTextGDIPlusProperties(WSRequestHandler* req);
|
||||
static void HandleGetTextGDIPlusProperties(WSRequestHandler* req);
|
||||
|
||||
static void HandleSetTextFreetype2Properties(WSRequestHandler* req);
|
||||
static void HandleGetTextFreetype2Properties(WSRequestHandler* req);
|
||||
|
||||
static void HandleSetBrowserSourceProperties(WSRequestHandler* req);
|
||||
static void HandleGetBrowserSourceProperties(WSRequestHandler* req);
|
||||
};
|
||||
|
@ -50,7 +50,7 @@ void WSRequestHandler::HandleGetCurrentProfile(WSRequestHandler* req) {
|
||||
/**
|
||||
* Get a list of available profiles.
|
||||
*
|
||||
* @return {Object|Array} `profiles` List of available profiles.
|
||||
* @return {Array<Object>} `profiles` List of available profiles.
|
||||
*
|
||||
* @api requests
|
||||
* @name ListProfiles
|
||||
|
@ -50,8 +50,7 @@ void WSRequestHandler::HandleGetCurrentSceneCollection(WSRequestHandler* req) {
|
||||
/**
|
||||
* List available scene collections
|
||||
*
|
||||
* @return {Object|Array} `scene-collections` Scene collections list
|
||||
* @return {String} `scene-collections.*.`
|
||||
* @return {Array<String>} `scene-collections` Scene collections list
|
||||
*
|
||||
* @api requests
|
||||
* @name ListSceneCollections
|
||||
|
@ -322,7 +322,7 @@ void WSRequestHandler::HandleSetSceneItemProperties(WSRequestHandler* req) {
|
||||
/**
|
||||
* Reset a scene item.
|
||||
*
|
||||
* @param {String (optional)} `scene-name` Name of the scene the source belogns to. Defaults to the current scene.
|
||||
* @param {String (optional)} `scene-name` Name of the scene the source belongs to. Defaults to the current scene.
|
||||
* @param {String} `item` Name of the source item.
|
||||
*
|
||||
* @api requests
|
||||
@ -566,3 +566,124 @@ void WSRequestHandler::HandleSetSceneItemCrop(WSRequestHandler* req) {
|
||||
req->SendErrorResponse("specified scene item doesn't exist");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a scene item.
|
||||
*
|
||||
* @param {String (optional)} `scene` Name of the scene the source belongs to. Defaults to the current scene.
|
||||
* @param {Object} `item` item to delete (required)
|
||||
* @param {String} `item.name` name of the scene item (prefer `id`, including both is acceptable).
|
||||
* @param {int} `item.id` id of the scene item.
|
||||
*
|
||||
* @api requests
|
||||
* @name DeleteSceneItem
|
||||
* @category scene items
|
||||
* @since 4.5.0
|
||||
*/
|
||||
void WSRequestHandler::HandleDeleteSceneItem(WSRequestHandler* req) {
|
||||
if (!req->hasField("item")) {
|
||||
req->SendErrorResponse("missing request parameters");
|
||||
return;
|
||||
}
|
||||
|
||||
const char* sceneName = obs_data_get_string(req->data, "scene");
|
||||
OBSSourceAutoRelease scene = Utils::GetSceneFromNameOrCurrent(sceneName);
|
||||
if (!scene) {
|
||||
req->SendErrorResponse("requested scene doesn't exist");
|
||||
return;
|
||||
}
|
||||
|
||||
OBSDataAutoRelease item = obs_data_get_obj(req->data, "item");
|
||||
OBSSceneItemAutoRelease sceneItem = Utils::GetSceneItemFromItem(scene, item);
|
||||
if (!sceneItem) {
|
||||
req->SendErrorResponse("item with id/name combination not found in specified scene");
|
||||
return;
|
||||
}
|
||||
|
||||
obs_sceneitem_remove(sceneItem);
|
||||
|
||||
req->SendOKResponse();
|
||||
}
|
||||
|
||||
struct DuplicateSceneItemData {
|
||||
obs_sceneitem_t *referenceItem;
|
||||
obs_source_t *fromSource;
|
||||
obs_sceneitem_t *newItem;
|
||||
};
|
||||
|
||||
static void DuplicateSceneItem(void *_data, obs_scene_t *scene) {
|
||||
DuplicateSceneItemData *data = (DuplicateSceneItemData *)_data;
|
||||
data->newItem = obs_scene_add(scene, data->fromSource);
|
||||
obs_sceneitem_set_visible(data->newItem, obs_sceneitem_visible(data->referenceItem));
|
||||
}
|
||||
|
||||
/**
|
||||
* Duplicates a scene item.
|
||||
*
|
||||
* @param {String (optional)} `fromScene` Name of the scene to copy the item from. Defaults to the current scene.
|
||||
* @param {String (optional)} `toScene` Name of the scene to create the item in. Defaults to the current scene.
|
||||
* @param {Object} `item` item to duplicate (required)
|
||||
* @param {String} `item.name` name of the scene item (prefer `id`, including both is acceptable).
|
||||
* @param {int} `item.id` id of the scene item.
|
||||
*
|
||||
* @return {String} `scene` Name of the scene where the new item was created
|
||||
* @return {Object} `item` New item info
|
||||
* @return {int} `̀item.id` New item ID
|
||||
* @return {String} `item.name` New item name
|
||||
*
|
||||
* @api requests
|
||||
* @name DuplicateSceneItem
|
||||
* @category scene items
|
||||
* @since 4.5.0
|
||||
*/
|
||||
void WSRequestHandler::HandleDuplicateSceneItem(WSRequestHandler* req) {
|
||||
if (!req->hasField("item")) {
|
||||
req->SendErrorResponse("missing request parameters");
|
||||
return;
|
||||
}
|
||||
|
||||
const char* fromSceneName = obs_data_get_string(req->data, "fromScene");
|
||||
OBSSourceAutoRelease fromScene = Utils::GetSceneFromNameOrCurrent(fromSceneName);
|
||||
if (!fromScene) {
|
||||
req->SendErrorResponse("requested fromScene doesn't exist");
|
||||
return;
|
||||
}
|
||||
|
||||
const char* toSceneName = obs_data_get_string(req->data, "toScene");
|
||||
OBSSourceAutoRelease toScene = Utils::GetSceneFromNameOrCurrent(toSceneName);
|
||||
if (!toScene) {
|
||||
req->SendErrorResponse("requested toScene doesn't exist");
|
||||
return;
|
||||
}
|
||||
|
||||
OBSDataAutoRelease item = obs_data_get_obj(req->data, "item");
|
||||
OBSSceneItemAutoRelease referenceItem = Utils::GetSceneItemFromItem(fromScene, item);
|
||||
if (!referenceItem) {
|
||||
req->SendErrorResponse("item with id/name combination not found in specified scene");
|
||||
return;
|
||||
}
|
||||
|
||||
DuplicateSceneItemData data;
|
||||
data.fromSource = obs_sceneitem_get_source(referenceItem);
|
||||
data.referenceItem = referenceItem;
|
||||
|
||||
obs_enter_graphics();
|
||||
obs_scene_atomic_update(obs_scene_from_source(toScene), DuplicateSceneItem, &data);
|
||||
obs_leave_graphics();
|
||||
|
||||
obs_sceneitem_t *newItem = data.newItem;
|
||||
if (!newItem) {
|
||||
req->SendErrorResponse("Error duplicating scene item");
|
||||
return;
|
||||
}
|
||||
|
||||
OBSDataAutoRelease itemData = obs_data_create();
|
||||
obs_data_set_int(itemData, "id", obs_sceneitem_get_id(newItem));
|
||||
obs_data_set_string(itemData, "name", obs_source_get_name(obs_sceneitem_get_source(newItem)));
|
||||
|
||||
OBSDataAutoRelease responseData = obs_data_create();
|
||||
obs_data_set_obj(responseData, "item", itemData);
|
||||
obs_data_set_string(responseData, "scene", obs_source_get_name(toScene));
|
||||
|
||||
req->SendOKResponse(responseData);
|
||||
}
|
||||
|
@ -3,6 +3,12 @@
|
||||
|
||||
#include "WSRequestHandler.h"
|
||||
|
||||
/**
|
||||
* @typedef {Object} `Scene`
|
||||
* @property {String} `name` Name of the currently active scene.
|
||||
* @property {Array<Source>} `sources` Ordered list of the current scene's source items.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Switch to the specified scene.
|
||||
*
|
||||
@ -34,7 +40,7 @@
|
||||
* Get the current scene's name and source items.
|
||||
*
|
||||
* @return {String} `name` Name of the currently active scene.
|
||||
* @return {Source|Array} `sources` Ordered list of the current scene's source items.
|
||||
* @return {Array<Source>} `sources` Ordered list of the current scene's source items.
|
||||
*
|
||||
* @api requests
|
||||
* @name GetCurrentScene
|
||||
@ -56,7 +62,7 @@ void WSRequestHandler::HandleGetCurrentScene(WSRequestHandler* req) {
|
||||
* Get a list of scenes in the currently active profile.
|
||||
*
|
||||
* @return {String} `current-scene` Name of the currently active scene.
|
||||
* @return {Scene|Array} `scenes` Ordered list of the current profile's scenes (See `[GetCurrentScene](#getcurrentscene)` for more information).
|
||||
* @return {Array<Scene>} `scenes` Ordered list of the current profile's scenes (See `[GetCurrentScene](#getcurrentscene)` for more information).
|
||||
*
|
||||
* @api requests
|
||||
* @name GetSceneList
|
||||
@ -74,3 +80,69 @@ void WSRequestHandler::HandleGetSceneList(WSRequestHandler* req) {
|
||||
|
||||
req->SendOKResponse(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the order of scene items in the requested scene.
|
||||
*
|
||||
* @param {String (optional)} `scene` Name of the scene to reorder (defaults to current).
|
||||
* @param {Scene|Array} `items` Ordered list of objects with name and/or id specified. Id preferred due to uniqueness per scene
|
||||
* @param {int (optional)} `items[].id` Id of a specific scene item. Unique on a scene by scene basis.
|
||||
* @param {String (optional)} `items[].name` Name of a scene item. Sufficiently unique if no scene items share sources within the scene.
|
||||
*
|
||||
* @api requests
|
||||
* @name ReorderSceneItems
|
||||
* @category scenes
|
||||
* @since 4.5.0
|
||||
*/
|
||||
void WSRequestHandler::HandleReorderSceneItems(WSRequestHandler* req) {
|
||||
QString sceneName = obs_data_get_string(req->data, "scene");
|
||||
OBSSourceAutoRelease scene = Utils::GetSceneFromNameOrCurrent(sceneName);
|
||||
if (!scene) {
|
||||
req->SendErrorResponse("requested scene doesn't exist");
|
||||
return;
|
||||
}
|
||||
|
||||
OBSDataArrayAutoRelease items = obs_data_get_array(req->data, "items");
|
||||
if (!items) {
|
||||
req->SendErrorResponse("sceneItem order not specified");
|
||||
return;
|
||||
}
|
||||
|
||||
size_t count = obs_data_array_count(items);
|
||||
|
||||
std::vector<obs_sceneitem_t*> newOrder;
|
||||
newOrder.reserve(count);
|
||||
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
OBSDataAutoRelease item = obs_data_array_item(items, i);
|
||||
|
||||
OBSSceneItemAutoRelease sceneItem = Utils::GetSceneItemFromItem(scene, item);
|
||||
obs_sceneitem_release(sceneItem); // ref dec
|
||||
|
||||
if (!sceneItem) {
|
||||
req->SendErrorResponse("Invalid sceneItem id or name specified");
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t j = 0; j <= i; ++j) {
|
||||
if (sceneItem == newOrder[j]) {
|
||||
req->SendErrorResponse("Duplicate sceneItem in specified order");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
newOrder.push_back(sceneItem);
|
||||
}
|
||||
|
||||
bool success = obs_scene_reorder_items(obs_scene_from_source(scene), newOrder.data(), count);
|
||||
if (!success) {
|
||||
req->SendErrorResponse("Invalid sceneItem order");
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto const& item: newOrder) {
|
||||
obs_sceneitem_release(item);
|
||||
}
|
||||
|
||||
req->SendOKResponse();
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -252,7 +252,7 @@ void WSRequestHandler::HandleStopStreaming(WSRequestHandler* req) {
|
||||
* @return {Object} `settings` Stream settings object.
|
||||
* @return {String} `settings.server` The publish URL.
|
||||
* @return {String} `settings.key` The publish key of the stream.
|
||||
* @return {boolean} `settings.use-auth` Indicates whether audentication should be used when connecting to the streaming server.
|
||||
* @return {boolean} `settings.use-auth` Indicates whether authentication should be used when connecting to the streaming server.
|
||||
* @return {String} `settings.username` The username to use when accessing the streaming server. Only present if `use-auth` is `true`.
|
||||
* @return {String} `settings.password` The password to use when accessing the streaming server. Only present if `use-auth` is `true`.
|
||||
*
|
||||
|
@ -27,7 +27,7 @@
|
||||
* Will return an `error` if Studio Mode is not enabled.
|
||||
*
|
||||
* @return {String} `name` The name of the active preview scene.
|
||||
* @return {Source|Array} `sources`
|
||||
* @return {Array<Source>} `sources`
|
||||
*
|
||||
* @api requests
|
||||
* @name GetPreviewScene
|
||||
|
@ -7,8 +7,8 @@
|
||||
* List of all transitions available in the frontend's dropdown menu.
|
||||
*
|
||||
* @return {String} `current-transition` Name of the currently active transition.
|
||||
* @return {Object|Array} `transitions` List of transitions.
|
||||
* @return {String} `transitions[].name` Name of the transition.
|
||||
* @return {Array<Object>} `transitions` List of transitions.
|
||||
* @return {String} `transitions.*.name` Name of the transition.
|
||||
*
|
||||
* @api requests
|
||||
* @name GetTransitionList
|
||||
|
@ -39,7 +39,7 @@ using OBSOutputAutoRelease =
|
||||
OBSRef<obs_output_t*, ___output_dummy_addref, obs_output_release>;
|
||||
|
||||
#define PROP_AUTHENTICATED "wsclient_authenticated"
|
||||
#define OBS_WEBSOCKET_VERSION "4.3.3"
|
||||
#define OBS_WEBSOCKET_VERSION "4.5.0"
|
||||
|
||||
#define blog(level, msg, ...) blog(level, "[obs-websocket] " msg, ##__VA_ARGS__)
|
||||
|
||||
|
Reference in New Issue
Block a user