Initial commit for attempted rewrite

This commit is contained in:
tt2468 2021-03-08 03:56:43 -08:00
commit f3d5cfbd18
79 changed files with 20144 additions and 0 deletions

10
.editorconfig Normal file
View File

@ -0,0 +1,10 @@
[*]
insert_final_newline = true
[*.{c,cpp,h,hpp}]
indent_style = tab
indent_size = 4
[*.{yml,yaml}]
indent_style = space
indent_size = 2

3
.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1,3 @@
open_collective: obs-websocket
github: Palakis
custom: https://www.paypal.me/stephanelepin

20
.github/ISSUE_TEMPLATE.md vendored Normal file
View File

@ -0,0 +1,20 @@
##### Issue type
<!--- Uncomment one of the two options below. -->
<!--- - Bug report -->
<!--- - Feature request -->
##### Description
<!--- Describe the bug encountered or feature requested. -->
##### Steps to reproduce and other useful info
<!--- If it's a bug, please describe the steps to reproduce it and PLEASE include an OBS log file. Otherwise, remove this section. -->
##### Technical information
- **Operating System** :
- **OBS Studio version** :
- **obs-websocket version** :
##### Development Environment
<!--- If you're trying to compile obs-websocket, please describe your compiler type and version (e.g: GCC 4.7, VC2013, ...), and the CMake settings used. -->
<!--- Remove this section if it does not apply. -->

BIN
.github/images/mediaunit_logo_black.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

BIN
.github/images/obsws_logo.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

35
.github/pull_request_template.md vendored Normal file
View File

@ -0,0 +1,35 @@
<!--- Please fill out the following template, which will help other contributors review your Pull Request. -->
<!--- Make sure youve read the contribution guidelines here: https://github.com/Palakis/obs-websocket/blob/4.x-current/CONTRIBUTING.md -->
### Description
<!--- Describe your changes. -->
### Motivation and Context
<!--- Why is this change required? What problem does it solve? -->
<!--- If it fixes/closes an open issue or implements feature request, -->
<!--- please link to the issue here. -->
### How Has This Been Tested?
<!--- Please describe in detail how you tested your changes, along with the OS(s) you tested with. -->
Tested OS(s):
### Types of changes
<!--- What types of changes does your PR introduce? Uncomment all that apply -->
<!--- - Bug fix (non-breaking change which fixes an issue) -->
<!--- - New request/event (non-breaking) -->
<!--- - Documentation change (a change to documentation pages) -->
<!--- - Enhancement (modification to a current event/request which adds functionality) -->
<!--- - Performance enhancement (non-breaking change which improves efficiency) -->
<!--- - Code cleanup (non-breaking change which makes code smaller or more readable) -->
### Checklist:
<!--- Go over all the following points, and put an `x` in all the boxes that apply. -->
<!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->
- [ ] I have read the [**contributing** document](https://github.com/Palakis/obs-websocket/blob/4.x-current/CONTRIBUTING.md).
- [ ] My code is not on the master branch.
- [ ] The code has been tested.
- [ ] All commit messages are properly formatted and commits squashed where appropriate.
- [ ] I have included updates to all appropriate documentation.

412
.github/workflows/pr_push.yml vendored Normal file
View File

@ -0,0 +1,412 @@
name: 'CI Multiplatform Build'
on:
push:
paths-ignore:
- 'docs/**'
branches:
- 4.x-current
pull_request:
paths-ignore:
- '**.md'
branches:
- 4.x-current
jobs:
windows:
name: 'Windows 32+64bit'
runs-on: [windows-latest]
if: contains(github.event.head_commit.message, '[skip ci]') != true
env:
QT_VERSION: '5.10.1'
WINDOWS_DEPS_VERSION: '2017'
CMAKE_GENERATOR: "Visual Studio 16 2019"
CMAKE_SYSTEM_VERSION: "10.0"
steps:
- name: Add msbuild to PATH
uses: microsoft/setup-msbuild@v1.0.0
- name: 'Checkout'
uses: actions/checkout@v2
with:
path: ${{ github.workspace }}/obs-websocket
submodules: 'recursive'
- name: 'Checkout OBS'
uses: actions/checkout@v2
with:
repository: obsproject/obs-studio
path: ${{ github.workspace }}/obs-studio
submodules: 'recursive'
- name: 'Get OBS-Studio git info'
shell: bash
working-directory: ${{ github.workspace }}/obs-studio
run: |
git fetch --prune --unshallow
echo ::set-env name=OBS_GIT_BRANCH::$(git rev-parse --abbrev-ref HEAD)
echo ::set-env name=OBS_GIT_HASH::$(git rev-parse --short HEAD)
echo ::set-env name=OBS_GIT_TAG::$(git describe --tags --abbrev=0)
- name: 'Checkout last OBS-Studio release (${{ env.OBS_GIT_TAG }})'
shell: bash
working-directory: ${{ github.workspace }}/obs-studio
run: |
git checkout ${{ env.OBS_GIT_TAG }}
git submodule update
- name: 'Get obs-websocket git info'
shell: bash
working-directory: ${{ github.workspace }}/obs-websocket
run: |
git fetch --prune --unshallow
echo ::set-env name=GIT_BRANCH::${{ github.event.pull_request.head.ref }}
echo ::set-env name=GIT_HASH::$(git rev-parse --short HEAD)
echo ::set-env name=GIT_TAG::$(git describe --tags --abbrev=0)
- name: 'Install prerequisite: QT'
run: |
curl -kLO https://cdn-fastly.obsproject.com/downloads/Qt_${{ env.QT_VERSION }}.7z -f --retry 5 -C -
7z x Qt_${{ env.QT_VERSION }}.7z -o"${{ github.workspace }}\cmbuild\QT"
- name: 'Install prerequisite: Pre-built OBS dependencies'
run: |
curl -kLO https://cdn-fastly.obsproject.com/downloads/dependencies${{ env.WINDOWS_DEPS_VERSION }}.zip -f --retry 5 -C -
7z x dependencies${{ env.WINDOWS_DEPS_VERSION }}.zip -o"${{ github.workspace }}\cmbuild\deps"
- name: 'Restore OBS 32-bit build v${{ env.OBS_GIT_TAG }} from cache'
id: build-cache-obs-32
uses: actions/cache@v1
env:
CACHE_NAME: 'build-cache-obs-32'
with:
path: ${{ github.workspace }}/obs-studio/build32
key: ${{ runner.os }}-${{ env.CACHE_NAME }}-${{ env.OBS_GIT_TAG }}
restore-keys: |
${{ runner.os }}-${{ env.CACHE_NAME }}-
- name: 'Configure OBS 32-bit'
if: steps.build-cache-obs-32.outputs.cache-hit != 'true'
working-directory: ${{ github.workspace }}/obs-studio
run: |
mkdir .\build32
cd .\build32
cmake -G "${{ env.CMAKE_GENERATOR }}" -A Win32 -DCMAKE_SYSTEM_VERSION="${{ env.CMAKE_SYSTEM_VERSION }}" -DQTDIR="${{ github.workspace }}\cmbuild\QT\${{ env.QT_VERSION }}\msvc2017" -DDepsPath="${{ github.workspace }}\cmbuild\deps\win32" -DCOPIED_DEPENDENCIES=NO -DCOPY_DEPENDENCIES=YES ..
- name: 'Build OBS-Studio 32-bit'
if: steps.build-cache-obs-32.outputs.cache-hit != 'true'
working-directory: ${{ github.workspace }}/obs-studio
run: |
msbuild /m /p:Configuration=RelWithDebInfo .\build32\libobs\libobs.vcxproj
msbuild /m /p:Configuration=RelWithDebInfo .\build32\UI\obs-frontend-api\obs-frontend-api.vcxproj
- name: 'Restore OBS 64-bit build v${{ env.OBS_GIT_TAG }} from cache'
id: build-cache-obs-64
uses: actions/cache@v1
env:
CACHE_NAME: 'build-cache-obs-64'
with:
path: ${{ github.workspace }}/obs-studio/build64
key: ${{ runner.os }}-${{ env.CACHE_NAME }}-${{ env.OBS_GIT_TAG }}
restore-keys: |
${{ runner.os }}-${{ env.CACHE_NAME }}-
- name: 'Configure OBS 64-bit'
if: steps.build-cache-obs-64.outputs.cache-hit != 'true'
working-directory: ${{ github.workspace }}/obs-studio
run: |
mkdir .\build64
cd .\build64
cmake -G "${{ env.CMAKE_GENERATOR }}" -A x64 -DCMAKE_SYSTEM_VERSION="${{ env.CMAKE_SYSTEM_VERSION }}" -DQTDIR="${{ github.workspace }}\cmbuild\QT\${{ env.QT_VERSION }}\msvc2017_64" -DDepsPath="${{ github.workspace }}\cmbuild\deps\win64" -DCOPIED_DEPENDENCIES=NO -DCOPY_DEPENDENCIES=YES ..
- name: 'Build OBS-Studio 64-bit'
if: steps.build-cache-obs-64.outputs.cache-hit != 'true'
working-directory: ${{ github.workspace }}/obs-studio
run: |
msbuild /m /p:Configuration=RelWithDebInfo .\build64\libobs\libobs.vcxproj
msbuild /m /p:Configuration=RelWithDebInfo .\build64\UI\obs-frontend-api\obs-frontend-api.vcxproj
- name: 'Configure obs-websocket 64-bit'
working-directory: ${{ github.workspace }}/obs-websocket
run: |
mkdir .\build64
cd .\build64
cmake -G "${{ env.CMAKE_GENERATOR }}" -A x64 -DCMAKE_SYSTEM_VERSION="${{ env.CMAKE_SYSTEM_VERSION }}" -DQTDIR="${{ github.workspace }}\cmbuild\QT\${{ env.QT_VERSION }}\msvc2017_64" -DLibObs_DIR="${{ github.workspace }}\obs-studio\build64\libobs" -DLIBOBS_INCLUDE_DIR="${{ github.workspace }}\obs-studio\libobs" -DLIBOBS_LIB="${{ github.workspace }}\obs-studio\build64\libobs\RelWithDebInfo\obs.lib" -DOBS_FRONTEND_LIB="${{ github.workspace }}\obs-studio\build64\UI\obs-frontend-api\RelWithDebInfo\obs-frontend-api.lib" ..
- name: 'Configure obs-websocket 32-bit'
working-directory: ${{ github.workspace }}/obs-websocket
run: |
mkdir .\build32
cd .\build32
cmake -G "${{ env.CMAKE_GENERATOR }}" -A Win32 -DCMAKE_SYSTEM_VERSION="${{ env.CMAKE_SYSTEM_VERSION }}" -DQTDIR="${{ github.workspace }}\cmbuild\QT\${{ env.QT_VERSION }}\msvc2017" -DLibObs_DIR="${{ github.workspace }}\obs-studio\build32\libobs" -DLIBOBS_INCLUDE_DIR="${{ github.workspace }}\obs-studio\libobs" -DLIBOBS_LIB="${{ github.workspace }}\obs-studio\build32\libobs\RelWithDebInfo\obs.lib" -DOBS_FRONTEND_LIB="${{ github.workspace }}\obs-studio\build32\UI\obs-frontend-api\RelWithDebInfo\obs-frontend-api.lib" ..
- name: 'Build obs-websocket 64-bit'
working-directory: ${{ github.workspace }}/obs-websocket
run: msbuild /m /p:Configuration=RelWithDebInfo .\build64\obs-websocket.sln
- name: 'Build obs-websocket 32-bit'
working-directory: ${{ github.workspace }}/obs-websocket
run: msbuild /m /p:Configuration=RelWithDebInfo .\build32\obs-websocket.sln
- name: 'Set PR artifact filename'
shell: bash
run: |
FILENAME="obs-websocket-${{ env.GIT_HASH }}-Windows"
echo "::set-env name=FILENAME::$FILENAME"
- name: 'Package obs-websocket'
working-directory: ${{ github.workspace }}/obs-websocket
run: |
mkdir package
cd package
7z a "${{ env.WIN_FILENAME }}.zip" "..\release\*"
iscc ..\installer\installer.iss /O. /F"${{ env.WIN_FILENAME }}-Installer"
- name: 'Publish ${{ env.WIN_FILENAME }}.zip'
if: success()
uses: actions/upload-artifact@v2-preview
with:
name: '${{ env.GIT_HASH }}-Windows'
path: ${{ github.workspace }}/obs-websocket/package/*.zip
- name: 'Publish ${{ env.WIN_FILENAME }}-Installer.exe'
if: success()
uses: actions/upload-artifact@v2-preview
with:
name: '${{ env.GIT_HASH }}-Windows-Installer'
path: ${{ github.workspace }}/obs-websocket/package/*.exe
ubuntu64:
name: "Linux/Ubuntu 64-bit"
runs-on: [ubuntu-latest]
if: contains(github.event.head_commit.message, '[skip ci]') != true
steps:
- name: 'Checkout'
uses: actions/checkout@v2
with:
path: ${{ github.workspace }}/obs-websocket
submodules: 'recursive'
- name: 'Checkout OBS'
uses: actions/checkout@v2
with:
repository: obsproject/obs-studio
path: ${{ github.workspace }}/obs-studio
submodules: 'recursive'
- name: 'Get OBS-Studio git info'
shell: bash
working-directory: ${{ github.workspace }}/obs-studio
run: |
git fetch --prune --unshallow
echo ::set-env name=OBS_GIT_BRANCH::$(git rev-parse --abbrev-ref HEAD)
echo ::set-env name=OBS_GIT_HASH::$(git rev-parse --short HEAD)
echo ::set-env name=OBS_GIT_TAG::$(git describe --tags --abbrev=0)
- name: 'Checkout last OBS-Studio release (${{ env.OBS_GIT_TAG }})'
shell: bash
working-directory: ${{ github.workspace }}/obs-studio
run: |
git checkout ${{ env.OBS_GIT_TAG }}
git submodule update
- name: 'Get obs-websocket git info'
working-directory: ${{ github.workspace }}/obs-websocket
run: |
git fetch --prune --unshallow
echo ::set-env name=GIT_BRANCH::${{ github.event.pull_request.head.ref }}
echo ::set-env name=GIT_HASH::$(git rev-parse --short HEAD)
echo ::set-env name=GIT_TAG::$(git describe --tags --abbrev=0)
- name: 'Install prerequisites (Apt)'
shell: bash
run: |
sudo dpkg --add-architecture amd64
sudo apt-get -qq update
sudo apt-get install -y \
build-essential \
checkinstall \
cmake \
libasound2-dev \
libavcodec-dev \
libavdevice-dev \
libavfilter-dev \
libavformat-dev \
libavutil-dev \
libcurl4-openssl-dev \
libfdk-aac-dev \
libfontconfig-dev \
libfreetype6-dev \
libgl1-mesa-dev \
libjack-jackd2-dev \
libjansson-dev \
libluajit-5.1-dev \
libpulse-dev \
libqt5x11extras5-dev \
libspeexdsp-dev \
libswresample-dev \
libswscale-dev \
libudev-dev \
libv4l-dev \
libva-dev \
libvlc-dev \
libx11-dev \
libx264-dev \
libxcb-randr0-dev \
libxcb-shm0-dev \
libxcb-xinerama0-dev \
libxcomposite-dev \
libxinerama-dev \
libmbedtls-dev \
pkg-config \
python3-dev \
qtbase5-dev \
libqt5svg5-dev \
swig
- name: 'Configure OBS-Studio'
working-directory: ${{ github.workspace }}/obs-studio
shell: bash
run: |
mkdir ./build
cd ./build
cmake -DDISABLE_PLUGINS=YES -DENABLE_SCRIPTING=NO -DUNIX_STRUCTURE=YES -DCMAKE_INSTALL_PREFIX=/usr ..
- name: 'Build OBS-Studio'
working-directory: ${{ github.workspace }}/obs-studio
shell: bash
run: |
set -e
cd ./build
make -j4 libobs obs-frontend-api
- name: 'Install OBS-Studio'
working-directory: ${{ github.workspace }}/obs-studio
shell: bash
run: |
cd ./build
sudo cp ./libobs/libobs.so /usr/lib
sudo cp ./UI/obs-frontend-api/libobs-frontend-api.so /usr/lib
sudo mkdir -p /usr/include/obs
sudo cp ../UI/obs-frontend-api/obs-frontend-api.h /usr/include/obs/obs-frontend-api.h
- name: 'Configure obs-websocket'
working-directory: ${{ github.workspace }}/obs-websocket
shell: bash
run: |
mkdir ./build
cd ./build
cmake -DLIBOBS_INCLUDE_DIR=${{ github.workspace }}/obs-studio/libobs -DCMAKE_INSTALL_PREFIX=/usr ..
- name: 'Build obs-websocket'
working-directory: ${{ github.workspace }}/obs-websocket
shell: bash
run: |
set -e
cd ./build
make -j4
- name: 'Set PR artifact filename'
shell: bash
run: |
FILENAME="obs-websocket-1-${{ env.GIT_HASH }}-1_amd64.deb"
echo "::set-env name=FILENAME::$FILENAME"
- name: 'Package ${{ env.FILENAME }}'
if: success()
working-directory: ${{ github.workspace }}/obs-websocket
shell: bash
run: |
VERSION="1-${{ env.GIT_HASH }}-git"
cd ./build
sudo checkinstall -y --type=debian --fstrans=no -nodoc \
--backup=no --deldoc=yes --install=no --pkgname=obs-websocket --pkgversion=$VERSION \
--pkglicense="GPLv2.0" --maintainer="${{ github.event.pusher.email }}" --pkggroup="video" \
--pkgsource="${{ github.event.repository.html_url }}" \
--requires="obs-studio,libqt5core5a,libqt5widgets5,qt5-image-formats-plugins" \
--pakdir="../package"
sudo chmod ao+r ../package/*
cd -
- name: 'Publish ${{ env.FILENAME }}'
if: success()
uses: actions/upload-artifact@v2-preview
with:
name: '${{ env.GIT_HASH }}-linux'
path: '${{ github.workspace }}/obs-websocket/package/*.deb'
macos64:
name: "macOS 64-bit"
runs-on: [macos-latest]
if: contains(github.event.head_commit.message, '[skip ci]') != true
env:
MACOS_DEPS_VERSION: '2020-04-18'
QT_VERSION: '5.14.1'
steps:
- name: 'Checkout'
uses: actions/checkout@v2
with:
path: ${{ github.workspace }}/obs-websocket
submodules: 'recursive'
- name: 'Checkout OBS'
uses: actions/checkout@v2
with:
repository: obsproject/obs-studio
path: ${{ github.workspace }}/obs-studio
submodules: 'recursive'
- name: 'Get OBS-Studio git info'
shell: bash
working-directory: ${{ github.workspace }}/obs-studio
run: |
git fetch --prune --unshallow
echo ::set-env name=OBS_GIT_BRANCH::$(git rev-parse --abbrev-ref HEAD)
echo ::set-env name=OBS_GIT_HASH::$(git rev-parse --short HEAD)
echo ::set-env name=OBS_GIT_TAG::$(git describe --tags --abbrev=0)
- name: 'Checkout last OBS-Studio release (${{ env.OBS_GIT_TAG }})'
shell: bash
working-directory: ${{ github.workspace }}/obs-studio
run: |
git checkout ${{ env.OBS_GIT_TAG }}
git submodule update
- name: 'Get obs-websocket git info'
working-directory: ${{ github.workspace }}/obs-websocket
run: |
git fetch --prune --unshallow
echo ::set-env name=GIT_BRANCH::${{ github.event.pull_request.head.ref }}
echo ::set-env name=GIT_HASH::$(git rev-parse --short HEAD)
echo ::set-env name=GIT_TAG::$(git describe --tags --abbrev=0)
- name: 'Install prerequisites (Homebrew)'
shell: bash
run: |
brew bundle --file ${{ github.workspace }}/obs-websocket/CI/macos/Brewfile
- name: 'Install prerequisite: Pre-built OBS dependencies'
shell: bash
run: |
curl -L -O https://github.com/obsproject/obs-deps/releases/download/${{ env.MACOS_DEPS_VERSION }}/osx-deps-${{ env.MACOS_DEPS_VERSION }}.tar.gz
tar -xf ${{ github.workspace }}/osx-deps-${{ env.MACOS_DEPS_VERSION }}.tar.gz -C "/tmp"
- name: 'Configure OBS Studio'
shell: bash
working-directory: ${{ github.workspace }}/obs-studio
run: |
mkdir build
cd build
cmake -DCMAKE_OSX_DEPLOYMENT_TARGET=10.11 -DENABLE_SCRIPTING=NO -DDepsPath=/tmp/obsdeps -DCMAKE_PREFIX_PATH=/usr/local/Cellar/qt/${{ env.QT_VERSION }}/lib/cmake ..
- name: 'Build OBS Studio libraries'
working-directory: ${{ github.workspace }}/obs-studio
shell: bash
run: |
set -e
cd ./build
make -j4 libobs obs-frontend-api
- name: 'Configure obs-websocket'
working-directory: ${{ github.workspace }}/obs-websocket
shell: bash
run: |
mkdir build
cd build
cmake -DQTDIR=/usr/local/Cellar/qt/${{ env.QT_VERSION }} -DLIBOBS_INCLUDE_DIR=${{ github.workspace }}/obs-studio/libobs -DLIBOBS_LIB=${{ github.workspace }}/obs-studio/libobs -DOBS_FRONTEND_LIB="${{ github.workspace }}/obs-studio/build/UI/obs-frontend-api/libobs-frontend-api.dylib" -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX=/usr ..
- name: 'Build obs-websocket'
working-directory: ${{ github.workspace }}/obs-websocket
shell: bash
run: |
set -e
cd ./build
make -j4
- name: 'Install prerequisite: Packages app'
if: success()
shell: bash
run: |
curl -L -O https://s3-us-west-2.amazonaws.com/obs-nightly/Packages.pkg
sudo installer -pkg ${{ github.workspace }}/Packages.pkg -target /
- name: 'Set PR artifact filename'
shell: bash
run: |
FILENAME_UNSIGNED="obs-websocket-${{ env.GIT_HASH }}-macOS-Unsigned.pkg"
echo "::set-env name=FILENAME_UNSIGNED::$FILENAME_UNSIGNED"
- name: 'Fix linked dynamic library paths'
if: success()
working-directory: ${{ github.workspace }}/obs-websocket
shell: bash
run: |
install_name_tool -change /usr/local/opt/qt/lib/QtWidgets.framework/Versions/5/QtWidgets @executable_path/../Frameworks/QtWidgets.framework/Versions/5/QtWidgets ./build/obs-websocket.so
install_name_tool -change /usr/local/opt/qt/lib/QtGui.framework/Versions/5/QtGui @executable_path/../Frameworks/QtGui.framework/Versions/5/QtGui ./build/obs-websocket.so
install_name_tool -change /usr/local/opt/qt/lib/QtCore.framework/Versions/5/QtCore @executable_path/../Frameworks/QtCore.framework/Versions/5/QtCore ./build/obs-websocket.so
echo "Dependencies for obs-websocket"
otool -L ./build/obs-websocket.so
- name: 'Package ${{ env.FILENAME }}'
if: success()
working-directory: ./obs-websocket
shell: bash
run: |
packagesbuild ./CI/macos/obs-websocket.pkgproj
mv ./release/obs-websocket.pkg ./release/${{ env.FILENAME_UNSIGNED }}
- name: 'Publish ${{ env.FILENAME_UNSIGNED }} artifact'
if: success()
uses: actions/upload-artifact@v2-preview
with:
name: '${{ env.GIT_HASH }}-macOS'
path: ${{ github.workspace }}/obs-websocket/release/*.pkg

484
.github/workflows/tag_release.yml vendored Normal file
View File

@ -0,0 +1,484 @@
name: 'CI Multiplatform Release'
on:
push:
paths-ignore:
- 'docs/**'
tags:
- '[45].[0-9]+.[0-9]+'
jobs:
windows:
name: 'Windows 32+64bit'
runs-on: [windows-latest]
env:
QT_VERSION: '5.10.1'
WINDOWS_DEPS_VERSION: '2017'
CMAKE_GENERATOR: "Visual Studio 16 2019"
CMAKE_SYSTEM_VERSION: "10.0"
steps:
- name: 'Add msbuild to PATH'
uses: microsoft/setup-msbuild@v1.0.0
- name: 'Checkout'
uses: actions/checkout@v2
with:
path: ${{ github.workspace }}/obs-websocket
submodules: 'recursive'
- name: 'Checkout OBS'
uses: actions/checkout@v2
with:
repository: obsproject/obs-studio
path: ${{ github.workspace }}/obs-studio
submodules: 'recursive'
- name: 'Get OBS-Studio git info'
shell: bash
working-directory: ${{ github.workspace }}/obs-studio
run: |
git fetch --prune --unshallow
echo ::set-env name=OBS_GIT_BRANCH::$(git rev-parse --abbrev-ref HEAD)
echo ::set-env name=OBS_GIT_HASH::$(git rev-parse --short HEAD)
echo ::set-env name=OBS_GIT_TAG::$(git describe --tags --abbrev=0)
- name: 'Checkout last OBS-Studio release (${{ env.OBS_GIT_TAG }})'
shell: bash
working-directory: ${{ github.workspace }}/obs-studio
run: |
git checkout ${{ env.OBS_GIT_TAG }}
git submodule update
- name: 'Get obs-websocket git info'
shell: bash
working-directory: ${{ github.workspace }}/obs-websocket
run: |
git fetch --prune --unshallow
echo ::set-env name=GIT_BRANCH::${{ github.event.pull_request.head.ref }}
echo ::set-env name=GIT_HASH::$(git rev-parse --short HEAD)
echo ::set-env name=GIT_TAG::$(git describe --tags --abbrev=0)
- name: 'Install prerequisite: QT'
run: |
curl -kLO https://cdn-fastly.obsproject.com/downloads/Qt_${{ env.QT_VERSION }}.7z -f --retry 5 -C -
7z x Qt_${{ env.QT_VERSION }}.7z -o"${{ github.workspace }}\cmbuild\QT"
- name: 'Install prerequisite: Pre-built OBS dependencies'
run: |
curl -kLO https://cdn-fastly.obsproject.com/downloads/dependencies${{ env.WINDOWS_DEPS_VERSION }}.zip -f --retry 5 -C -
7z x dependencies${{ env.WINDOWS_DEPS_VERSION }}.zip -o"${{ github.workspace }}\cmbuild\deps"
- name: 'Restore OBS 32-bit build v${{ env.OBS_GIT_TAG }} from cache'
id: build-cache-obs-32
uses: actions/cache@v1
env:
CACHE_NAME: 'build-cache-obs-32'
with:
path: ${{ github.workspace }}/obs-studio/build32
key: ${{ runner.os }}-${{ env.CACHE_NAME }}-${{ env.OBS_GIT_TAG }}
restore-keys: |
${{ runner.os }}-${{ env.CACHE_NAME }}-
- name: 'Configure OBS 32-bit'
if: steps.build-cache-obs-32.outputs.cache-hit != 'true'
working-directory: ${{ github.workspace }}/obs-studio
run: |
mkdir .\build32
cd .\build32
cmake -G "${{ env.CMAKE_GENERATOR }}" -A Win32 -DCMAKE_SYSTEM_VERSION="${{ env.CMAKE_SYSTEM_VERSION }}" -DQTDIR="${{ github.workspace }}\cmbuild\QT\${{ env.QT_VERSION }}\msvc2017" -DDepsPath="${{ github.workspace }}\cmbuild\deps\win32" -DCOPIED_DEPENDENCIES=NO -DCOPY_DEPENDENCIES=YES ..
- name: 'Build OBS-Studio 32-bit'
if: steps.build-cache-obs-32.outputs.cache-hit != 'true'
working-directory: ${{ github.workspace }}/obs-studio
run: |
msbuild /m /p:Configuration=RelWithDebInfo .\build32\libobs\libobs.vcxproj
msbuild /m /p:Configuration=RelWithDebInfo .\build32\UI\obs-frontend-api\obs-frontend-api.vcxproj
- name: 'Restore OBS 64-bit build v${{ env.OBS_GIT_TAG }} from cache'
id: build-cache-obs-64
uses: actions/cache@v1
env:
CACHE_NAME: 'build-cache-obs-64'
with:
path: ${{ github.workspace }}/obs-studio/build64
key: ${{ runner.os }}-${{ env.CACHE_NAME }}-${{ env.OBS_GIT_TAG }}
restore-keys: |
${{ runner.os }}-${{ env.CACHE_NAME }}-
- name: 'Configure OBS 64-bit'
if: steps.build-cache-obs-64.outputs.cache-hit != 'true'
working-directory: ${{ github.workspace }}/obs-studio
run: |
mkdir .\build64
cd .\build64
cmake -G "${{ env.CMAKE_GENERATOR }}" -A x64 -DCMAKE_SYSTEM_VERSION="${{ env.CMAKE_SYSTEM_VERSION }}" -DQTDIR="${{ github.workspace }}\cmbuild\QT\${{ env.QT_VERSION }}\msvc2017_64" -DDepsPath="${{ github.workspace }}\cmbuild\deps\win64" -DCOPIED_DEPENDENCIES=NO -DCOPY_DEPENDENCIES=YES ..
- name: 'Build OBS-Studio 64-bit'
if: steps.build-cache-obs-64.outputs.cache-hit != 'true'
working-directory: ${{ github.workspace }}/obs-studio
run: |
msbuild /m /p:Configuration=RelWithDebInfo .\build64\libobs\libobs.vcxproj
msbuild /m /p:Configuration=RelWithDebInfo .\build64\UI\obs-frontend-api\obs-frontend-api.vcxproj
- name: 'Configure obs-websocket 64-bit'
working-directory: ${{ github.workspace }}/obs-websocket
run: |
mkdir .\build64
cd .\build64
cmake -G "${{ env.CMAKE_GENERATOR }}" -A x64 -DCMAKE_SYSTEM_VERSION="${{ env.CMAKE_SYSTEM_VERSION }}" -DQTDIR="${{ github.workspace }}\cmbuild\QT\${{ env.QT_VERSION }}\msvc2017_64" -DLibObs_DIR="${{ github.workspace }}\obs-studio\build64\libobs" -DLIBOBS_INCLUDE_DIR="${{ github.workspace }}\obs-studio\libobs" -DLIBOBS_LIB="${{ github.workspace }}\obs-studio\build64\libobs\RelWithDebInfo\obs.lib" -DOBS_FRONTEND_LIB="${{ github.workspace }}\obs-studio\build64\UI\obs-frontend-api\RelWithDebInfo\obs-frontend-api.lib" ..
- name: 'Configure obs-websocket 32-bit'
working-directory: ${{ github.workspace }}/obs-websocket
run: |
mkdir .\build32
cd .\build32
cmake -G "${{ env.CMAKE_GENERATOR }}" -A Win32 -DCMAKE_SYSTEM_VERSION="${{ env.CMAKE_SYSTEM_VERSION }}" -DQTDIR="${{ github.workspace }}\cmbuild\QT\${{ env.QT_VERSION }}\msvc2017" -DLibObs_DIR="${{ github.workspace }}\obs-studio\build32\libobs" -DLIBOBS_INCLUDE_DIR="${{ github.workspace }}\obs-studio\libobs" -DLIBOBS_LIB="${{ github.workspace }}\obs-studio\build32\libobs\RelWithDebInfo\obs.lib" -DOBS_FRONTEND_LIB="${{ github.workspace }}\obs-studio\build32\UI\obs-frontend-api\RelWithDebInfo\obs-frontend-api.lib" ..
- name: 'Build obs-websocket 64-bit'
working-directory: ${{ github.workspace }}/obs-websocket
run: msbuild /m /p:Configuration=RelWithDebInfo .\build64\obs-websocket.sln
- name: 'Build obs-websocket 32-bit'
working-directory: ${{ github.workspace }}/obs-websocket
run: msbuild /m /p:Configuration=RelWithDebInfo .\build32\obs-websocket.sln
- name: 'Set release filename'
shell: bash
run: |
FILENAME="obs-websocket-${{ env.GIT_TAG }}-Windows"
echo "::set-env name=WIN_FILENAME::$FILENAME"
- name: 'Package obs-websocket'
working-directory: ${{ github.workspace }}/obs-websocket
run: |
mkdir package
cd package
7z a "${{ env.WIN_FILENAME }}.zip" "..\release\*"
iscc ..\installer\installer.iss /O. /F"${{ env.WIN_FILENAME }}-Installer"
- name: 'Publish ${{ env.WIN_FILENAME }}.zip'
if: success()
uses: actions/upload-artifact@v2-preview
with:
name: '${{ env.GIT_TAG }}-Windows'
path: ${{ github.workspace }}/obs-websocket/package/*.zip
- name: 'Publish ${{ env.WIN_FILENAME }}-Installer.exe'
if: success()
uses: actions/upload-artifact@v2-preview
with:
name: '${{ env.GIT_TAG }}-Windows-Installer'
path: ${{ github.workspace }}/obs-websocket/package/*.exe
ubuntu64:
name: "Linux/Ubuntu 64-bit"
runs-on: [ubuntu-latest]
steps:
- name: 'Checkout'
uses: actions/checkout@v2
with:
path: ${{ github.workspace }}/obs-websocket
submodules: 'recursive'
- name: 'Checkout OBS'
uses: actions/checkout@v2
with:
repository: obsproject/obs-studio
path: ${{ github.workspace }}/obs-studio
submodules: 'recursive'
- name: 'Get OBS-Studio git info'
shell: bash
working-directory: ${{ github.workspace }}/obs-studio
run: |
git fetch --prune --unshallow
echo ::set-env name=OBS_GIT_BRANCH::$(git rev-parse --abbrev-ref HEAD)
echo ::set-env name=OBS_GIT_HASH::$(git rev-parse --short HEAD)
echo ::set-env name=OBS_GIT_TAG::$(git describe --tags --abbrev=0)
- name: 'Checkout last OBS-Studio release (${{ env.OBS_GIT_TAG }})'
shell: bash
working-directory: ${{ github.workspace }}/obs-studio
run: |
git checkout ${{ env.OBS_GIT_TAG }}
git submodule update
- name: 'Get obs-websocket git info'
working-directory: ${{ github.workspace }}/obs-websocket
run: |
git fetch --prune --unshallow
echo ::set-env name=GIT_BRANCH::${{ github.event.pull_request.head.ref }}
echo ::set-env name=GIT_HASH::$(git rev-parse --short HEAD)
echo ::set-env name=GIT_TAG::$(git describe --tags --abbrev=0)
- name: 'Install prerequisites (Apt)'
shell: bash
run: |
sudo dpkg --add-architecture amd64
sudo apt-get -qq update
sudo apt-get install -y \
build-essential \
checkinstall \
cmake \
libasound2-dev \
libavcodec-dev \
libavdevice-dev \
libavfilter-dev \
libavformat-dev \
libavutil-dev \
libcurl4-openssl-dev \
libfdk-aac-dev \
libfontconfig-dev \
libfreetype6-dev \
libgl1-mesa-dev \
libjack-jackd2-dev \
libjansson-dev \
libluajit-5.1-dev \
libpulse-dev \
libqt5x11extras5-dev \
libspeexdsp-dev \
libswresample-dev \
libswscale-dev \
libudev-dev \
libv4l-dev \
libva-dev \
libvlc-dev \
libx11-dev \
libx264-dev \
libxcb-randr0-dev \
libxcb-shm0-dev \
libxcb-xinerama0-dev \
libxcomposite-dev \
libxinerama-dev \
libmbedtls-dev \
pkg-config \
python3-dev \
qtbase5-dev \
libqt5svg5-dev \
swig
- name: 'Configure OBS-Studio'
working-directory: ${{ github.workspace }}/obs-studio
shell: bash
run: |
mkdir ./build
cd ./build
cmake -DDISABLE_PLUGINS=YES -DENABLE_SCRIPTING=NO -DUNIX_STRUCTURE=YES -DCMAKE_INSTALL_PREFIX=/usr ..
- name: 'Build OBS-Studio'
working-directory: ${{ github.workspace }}/obs-studio
shell: bash
run: |
set -e
cd ./build
make -j4 libobs obs-frontend-api
- name: 'Install OBS-Studio'
working-directory: ${{ github.workspace }}/obs-studio
shell: bash
run: |
cd ./build
sudo cp ./libobs/libobs.so /usr/lib
sudo cp ./UI/obs-frontend-api/libobs-frontend-api.so /usr/lib
sudo mkdir -p /usr/include/obs
sudo cp ../UI/obs-frontend-api/obs-frontend-api.h /usr/include/obs/obs-frontend-api.h
- name: 'Configure obs-websocket'
working-directory: ${{ github.workspace }}/obs-websocket
shell: bash
run: |
mkdir ./build
cd ./build
cmake -DLIBOBS_INCLUDE_DIR=${{ github.workspace }}/obs-studio/libobs -DCMAKE_INSTALL_PREFIX=/usr ..
- name: 'Build obs-websocket'
working-directory: ${{ github.workspace }}/obs-websocket
shell: bash
run: |
set -e
cd ./build
make -j4
- name: 'Set release filename'
shell: bash
run: |
FILENAME="obs-websocket-${{ env.GIT_TAG }}-1_amd64.deb"
echo "::set-env name=LINUX_FILENAME::$FILENAME"
- name: 'Package ${{ env.LINUX_FILENAME }}'
if: success()
working-directory: ${{ github.workspace }}/obs-websocket
shell: bash
run: |
VERSION="${{ env.GIT_TAG }}"
cd ./build
sudo checkinstall -y --type=debian --fstrans=no -nodoc \
--backup=no --deldoc=yes --install=no --pkgname=obs-websocket --pkgversion=$VERSION \
--pkglicense="GPLv2.0" --maintainer="${{ github.event.pusher.email }}" --pkggroup="video" \
--pkgsource="${{ github.event.repository.html_url }}" \
--requires="obs-studio,libqt5core5a,libqt5widgets5,qt5-image-formats-plugins" \
--pakdir="../package"
sudo chmod ao+r ../package/*
cd -
- name: 'Publish ${{ env.LINUX_FILENAME }}'
if: success()
uses: actions/upload-artifact@v2-preview
with:
name: '${{ env.GIT_TAG }}-linux'
path: '${{ github.workspace }}/obs-websocket/package/*.deb'
macos64:
name: "macOS 64-bit"
runs-on: [macos-latest]
env:
MACOS_DEPS_VERSION: '2020-04-18'
QT_VERSION: '5.14.1'
steps:
- name: 'Checkout'
uses: actions/checkout@v2
with:
path: ${{ github.workspace }}/obs-websocket
submodules: 'recursive'
- name: 'Checkout OBS'
uses: actions/checkout@v2
with:
repository: obsproject/obs-studio
path: ${{ github.workspace }}/obs-studio
submodules: 'recursive'
- name: 'Get OBS-Studio git info'
shell: bash
working-directory: ${{ github.workspace }}/obs-studio
run: |
git fetch --prune --unshallow
echo ::set-env name=OBS_GIT_BRANCH::$(git rev-parse --abbrev-ref HEAD)
echo ::set-env name=OBS_GIT_HASH::$(git rev-parse --short HEAD)
echo ::set-env name=OBS_GIT_TAG::$(git describe --tags --abbrev=0)
- name: 'Checkout last OBS-Studio release (${{ env.OBS_GIT_TAG }})'
shell: bash
working-directory: ${{ github.workspace }}/obs-studio
run: |
git checkout ${{ env.OBS_GIT_TAG }}
git submodule update
- name: 'Get obs-websocket git info'
working-directory: ${{ github.workspace }}/obs-websocket
run: |
git fetch --prune --unshallow
echo ::set-env name=GIT_BRANCH::${{ github.event.pull_request.head.ref }}
echo ::set-env name=GIT_HASH::$(git rev-parse --short HEAD)
echo ::set-env name=GIT_TAG::$(git describe --tags --abbrev=0)
- name: 'Install prerequisites (Homebrew)'
shell: bash
run: |
brew bundle --file ${{ github.workspace }}/obs-websocket/CI/macos/Brewfile
- name: 'Install prerequisite: Pre-built OBS dependencies'
shell: bash
run: |
curl -L -O https://github.com/obsproject/obs-deps/releases/download/${{ env.MACOS_DEPS_VERSION }}/osx-deps-${{ env.MACOS_DEPS_VERSION }}.tar.gz
tar -xf ${{ github.workspace }}/osx-deps-${{ env.MACOS_DEPS_VERSION }}.tar.gz -C "/tmp"
- name: 'Configure OBS Studio'
shell: bash
working-directory: ${{ github.workspace }}/obs-studio
run: |
mkdir build
cd build
cmake -DCMAKE_OSX_DEPLOYMENT_TARGET=10.11 -DENABLE_SCRIPTING=NO -DDepsPath=/tmp/obsdeps -DCMAKE_PREFIX_PATH=/usr/local/Cellar/qt/${{ env.QT_VERSION }}/lib/cmake ..
- name: 'Build OBS Studio libraries'
working-directory: ${{ github.workspace }}/obs-studio
shell: bash
run: |
set -e
cd ./build
make -j4 libobs obs-frontend-api
- name: 'Configure obs-websocket'
working-directory: ${{ github.workspace }}/obs-websocket
shell: bash
run: |
mkdir build
cd build
cmake -DQTDIR=/usr/local/Cellar/qt/${{ env.QT_VERSION }} -DLIBOBS_INCLUDE_DIR=${{ github.workspace }}/obs-studio/libobs -DLIBOBS_LIB=${{ github.workspace }}/obs-studio/libobs -DOBS_FRONTEND_LIB="${{ github.workspace }}/obs-studio/build/UI/obs-frontend-api/libobs-frontend-api.dylib" -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX=/usr ..
- name: 'Build obs-websocket'
working-directory: ${{ github.workspace }}/obs-websocket
shell: bash
run: |
set -e
cd ./build
make -j4
- name: 'Install prerequisite: Packages app'
if: success()
shell: bash
run: |
curl -L -O https://s3-us-west-2.amazonaws.com/obs-nightly/Packages.pkg
sudo installer -pkg ${{ github.workspace }}/Packages.pkg -target /
- name: 'Set release filename'
if: success() && startsWith(github.ref, 'refs/tags')
shell: bash
run: |
FILENAME_UNSIGNED="obs-websocket-${{ env.GIT_TAG }}-macOS-Unsigned.pkg"
FILENAME="obs-websocket-${{ env.GIT_TAG }}-macOS.pkg"
echo "::set-env name=MAC_FILENAME_UNSIGNED::$FILENAME_UNSIGNED"
echo "::set-env name=MAC_FILENAME::$FILENAME"
- name: 'Fix linked dynamic library paths'
if: success()
working-directory: ${{ github.workspace }}/obs-websocket
shell: bash
run: |
install_name_tool -change /usr/local/opt/qt/lib/QtWidgets.framework/Versions/5/QtWidgets @executable_path/../Frameworks/QtWidgets.framework/Versions/5/QtWidgets ./build/obs-websocket.so
install_name_tool -change /usr/local/opt/qt/lib/QtGui.framework/Versions/5/QtGui @executable_path/../Frameworks/QtGui.framework/Versions/5/QtGui ./build/obs-websocket.so
install_name_tool -change /usr/local/opt/qt/lib/QtCore.framework/Versions/5/QtCore @executable_path/../Frameworks/QtCore.framework/Versions/5/QtCore ./build/obs-websocket.so
echo "Dependencies for obs-websocket"
otool -L ./build/obs-websocket.so
- name: 'Install Apple Developer Certificate'
if: success()
uses: apple-actions/import-codesign-certs@253ddeeac23f2bdad1646faac5c8c2832e800071
with:
p12-file-base64: ${{ secrets.MACOS_CERT_CODESIGN }}
p12-password: ${{ secrets.MACOS_CERT_PASS }}
- name: 'Code signing'
if: success()
working-directory: ./obs-websocket
shell: bash
run: |
set -e
codesign --sign "${{ secrets.MACOS_IDENT_CODESIGN }}" ./build/obs-websocket.so
packagesbuild ./CI/macos/obs-websocket.pkgproj
mv ./release/obs-websocket.pkg ./release/${{ env.MAC_FILENAME_UNSIGNED }}
productsign --sign "${{ secrets.MACOS_IDENT_INSTALLER }}" ./release/${{ env.MAC_FILENAME_UNSIGNED }} ./release/${{ env.MAC_FILENAME }}
rm ./release/${{ env.MAC_FILENAME_UNSIGNED }}
- name: 'Notarization'
if: success()
working-directory: ./obs-websocket
shell: bash
run: |
set -e
xcrun altool --store-password-in-keychain-item "AC_PASSWORD" -u "${{ secrets.MACOS_IDENT_USER }}" -p "${{ secrets.MACOS_IDENT_PASS }}"
xcnotary precheck ./release/${{ env.MAC_FILENAME }}
if [ "$?" -eq 0 ]; then xcnotary notarize ./release/${{ env.MAC_FILENAME }} --developer-account "${{ secrets.MACOS_IDENT_USER }}" --developer-password-keychain-item "AC_PASSWORD" --provider "${{ secrets.MACOS_IDENT_PROVIDER }}"; fi
- name: 'Publish ${{ env.MAC_FILENAME }} artifact'
if: success() && startsWith(github.ref, 'refs/tags')
uses: actions/upload-artifact@v2-preview
with:
name: '${{ env.GIT_TAG }}-macOS'
path: ${{ github.workspace }}/obs-websocket/release/*.pkg
make-release:
name: 'Create and upload release'
runs-on: [ubuntu-latest]
needs: [windows, ubuntu64, macos64]
steps:
- name: 'Get the version'
shell: bash
id: get_version
run: |
echo ::set-env name=TAG_VERSION::${GITHUB_REF/refs\/tags\//}
- name: 'Create Release'
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ env.TAG_VERSION }}
release_name: obs-websocket ${{ env.TAG_VERSION }}
draft: false
prerelease: false
- name: 'Download release artifacts'
uses: actions/download-artifact@v2-preview
- name: 'Upload Windows .zip artifact to release'
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ${{ github.workspace }}/${{ env.TAG_VERSION }}-Windows/obs-websocket-${{ env.TAG_VERSION }}-Windows.zip
asset_name: obs-websocket-${{ env.TAG_VERSION }}-Windows.zip
asset_content_type: application/zip
- name: 'Upload Windows .exe artifact to release'
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ${{ github.workspace }}/${{ env.TAG_VERSION }}-Windows-Installer/obs-websocket-${{ env.TAG_VERSION }}-Windows-Installer.exe
asset_name: obs-websocket-${{ env.TAG_VERSION }}-Windows-Installer.exe
asset_content_type: application/zip
- name: 'Upload Linux artifact to release'
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ${{ github.workspace }}/${{ env.TAG_VERSION }}-linux/obs-websocket_${{ env.TAG_VERSION }}-1_amd64.deb
asset_name: obs-websocket-${{ env.TAG_VERSION }}-1_amd64.deb
asset_content_type: application/octet-stream
- name: 'Upload macOS artifact to release'
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ${{ github.workspace }}/${{ env.TAG_VERSION }}-macOS/obs-websocket-${{ env.TAG_VERSION }}-macOS.pkg
asset_name: obs-websocket-${{ env.TAG_VERSION }}-macOS.pkg
asset_content_type: application/octet-stream

10
.gitignore vendored Normal file
View File

@ -0,0 +1,10 @@
*~
.DS_Store
/build/
/build32/
/build64/
/release/
/package/
/installer/Output/
.idea
.vscode

6
.gitmodules vendored Normal file
View File

@ -0,0 +1,6 @@
[submodule "deps/websocketpp"]
path = deps/websocketpp
url = https://github.com/zaphoyd/websocketpp.git
[submodule "deps/asio"]
path = deps/asio
url = https://github.com/chriskohlhoff/asio.git

66
BUILDING.md Normal file
View File

@ -0,0 +1,66 @@
# Compiling obs-websocket
## Prerequisites
You'll need [Qt 5.10.x](https://download.qt.io/official_releases/qt/5.10/),
[CMake](https://cmake.org/download/) and a working [OBS Studio development environment](https://obsproject.com/wiki/install-instructions) installed on your
computer.
## Windows
In cmake-gui, you'll have to set the following variables :
- **QTDIR** (path) : location of the Qt environment suited for your compiler and architecture
- **LIBOBS_INCLUDE_DIR** (path) : location of the libobs subfolder in the source code of OBS Studio
- **LIBOBS_LIB** (filepath) : location of the obs.lib file
- **OBS_FRONTEND_LIB** (filepath) : location of the obs-frontend-api.lib file
## Linux
On Debian/Ubuntu :
```shell
sudo apt-get install libboost-all-dev
git clone --recursive https://github.com/Palakis/obs-websocket.git
cd obs-websocket
mkdir build && cd build
cmake -DLIBOBS_INCLUDE_DIR="<path to the libobs sub-folder in obs-studio's source code>" -DCMAKE_INSTALL_PREFIX=/usr -DUSE_UBUNTU_FIX=true ..
make -j4
sudo make install
```
On other linux OS's, use this cmake command instead:
```shell
cmake -DLIBOBS_INCLUDE_DIR="<path to the libobs sub-folder in obs-studio's source code>" -DCMAKE_INSTALL_PREFIX=/usr ..
```
## OS X
As a prerequisite, you will need Xcode for your current OSX version, the Xcode 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 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.
```shell
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
```
This will result in a ready-to-use `obs-websocket.pkg` installer in the `release` subfolder.
## Automated Builds
[![Build Status](https://dev.azure.com/Palakis/obs-websocket/_apis/build/status/Palakis.obs-websocket?branchName=4.x-current)](https://dev.azure.com/Palakis/obs-websocket/_build/latest?definitionId=2&branchName=4.x-current)

28
CI/build-macos.sh Executable file
View File

@ -0,0 +1,28 @@
#!/bin/sh
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)"
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

6
CI/build-ubuntu.sh Executable file
View File

@ -0,0 +1,6 @@
#!/bin/sh
set -ex
mkdir build && cd build
cmake -DCMAKE_INSTALL_PREFIX=/usr -DUSE_UBUNTU_FIX=true ..
make -j4

6
CI/download-obs-deps.cmd Normal file
View File

@ -0,0 +1,6 @@
if not exist %DepsBasePath% (
curl -o %DepsBasePath%.zip -kLO https://obsproject.com/downloads/dependencies2017.zip -f --retry 5 -C -
7z x %DepsBasePath%.zip -o%DepsBasePath%
) else (
echo "OBS dependencies are already there. Download skipped."
)

31
CI/generate-docs.sh Executable file
View File

@ -0,0 +1,31 @@
#!/bin/bash
set -e
echo "-- Generating documentation."
echo "-- Node version: $(node -v)"
echo "-- NPM version: $(npm -v)"
git fetch origin
git checkout ${CHECKOUT_REF/refs\/heads\//}
cd docs
npm install
npm run build
echo "-- Documentation successfully generated."
if git diff --quiet; then
echo "-- No documentation changes to commit."
exit 0
fi
REMOTE_URL="$(git config remote.origin.url)"
TARGET_REPO=${REMOTE_URL/https:\/\/github.com\//github.com/}
GITHUB_REPO=https://${GH_TOKEN:-git}@${TARGET_REPO}
git config user.name "Azure CI"
git config user.email "$COMMIT_AUTHOR_EMAIL"
git add ./generated
git pull
git commit -m "docs(ci): Update protocol.md - $(git rev-parse --short HEAD) [skip ci]"
git push -q $GITHUB_REPO

42
CI/install-build-obs-macos.sh Executable file
View File

@ -0,0 +1,42 @@
#!/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
echo "[obs-websocket] Downloading and unpacking OBS dependencies"
wget --quiet --retry-connrefused --waitretry=1 https://obs-nightly.s3.amazonaws.com/osx-deps-2018-08-09.tar.gz
tar -xf ./osx-deps-2018-08-09.tar.gz -C /tmp
# 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 .. \
-DCMAKE_OSX_DEPLOYMENT_TARGET=10.11 \
-DDISABLE_PLUGINS=true \
-DENABLE_SCRIPTING=0 \
-DDepsPath=/tmp/obsdeps \
-DCMAKE_PREFIX_PATH=/usr/local/opt/qt/lib/cmake \
&& make -j4

View File

@ -0,0 +1,56 @@
#!/bin/sh
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
echo "[obs-websocket] Updating Homebrew.."
brew update >/dev/null
echo "[obs-websocket] Checking installed Homebrew formulas.."
BREW_PACKAGES=$(brew list)
BREW_DEPENDENCIES="jack speexdsp ccache swig mbedtls"
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
echo "[obs-websocket] Installing obs-websocket dependency 'QT 5.10.1'.."
brew install ./CI/macos/qt.rb
# Pin this version of QT5 to avoid `brew upgrade`
# upgrading it to incompatible version
brew pin qt
# Fetch and install Packages app
# =!= NOTICE =!=
# Installs a LaunchDaemon under /Library/LaunchDaemons/fr.whitebox.packages.build.dispatcher.plist
# =!= NOTICE =!=
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

View File

@ -0,0 +1,19 @@
#!/bin/sh
set -ex
sudo add-apt-repository -y ppa:obsproject/obs-studio
sudo apt-get -qq update
sudo apt-get install -y \
libc-dev-bin \
libc6-dev git \
build-essential \
checkinstall \
cmake \
obs-studio \
qtbase5-dev
# Dirty hack
sudo wget -O /usr/include/obs/obs-frontend-api.h https://raw.githubusercontent.com/obsproject/obs-studio/26.0.0/UI/obs-frontend-api/obs-frontend-api.h
sudo ldconfig

8
CI/install-qt-win.cmd Normal file
View File

@ -0,0 +1,8 @@
if not exist %QtBaseDir% (
curl -kLO https://cdn-fastly.obsproject.com/downloads/Qt_5.10.1.7z -f --retry 5 -z Qt_5.10.1.7z
7z x Qt_5.10.1.7z -o%QtBaseDir%
) else (
echo "Qt is already installed. Download skipped."
)
dir %QtBaseDir%

10
CI/macos/Brewfile Normal file
View File

@ -0,0 +1,10 @@
tap "akeru-inc/tap"
brew "jack"
brew "speexdsp"
brew "cmake"
brew "freetype"
brew "fdk-aac"
brew "https://gist.githubusercontent.com/DDRBoxman/9c7a2b08933166f4b61ed9a44b242609/raw/ef4de6c587c6bd7f50210eccd5bd51ff08e6de13/qt.rb"
brew "swig", link: false
brew "https://gist.githubusercontent.com/DDRBoxman/4cada55c51803a2f963fa40ce55c9d3e/raw/572c67e908bfbc1bcb8c476ea77ea3935133f5b5/swig.rb"
brew "akeru-inc/tap/xcnotary"

View File

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

145
CI/macos/qt.rb Normal file
View File

@ -0,0 +1,145 @@
# 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/official_releases/qt/5.10/5.10.1/single/qt-everywhere-src-5.10.1.tar.xz"
mirror "https://www.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", :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"
option "without-proprietary-codecs", "Don't build with proprietary codecs (e.g. mp3)"
# 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" => :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
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
]
args << "-nomake" << "examples" if build.without? "examples"
if build.with? "mysql"
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"
args << "-proprietary-codecs" if build.with? "proprietary-codecs"
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

90
CI/package-macos.sh Executable file
View File

@ -0,0 +1,90 @@
#!/bin/bash
set -e
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)"
GIT_HASH=$(git rev-parse --short HEAD)
GIT_BRANCH_OR_TAG=$(git name-rev --name-only HEAD | awk -F/ '{print $NF}')
VERSION="$GIT_HASH-$GIT_BRANCH_OR_TAG"
FILENAME_UNSIGNED="obs-websocket-$VERSION-Unsigned.pkg"
FILENAME="obs-websocket-$VERSION.pkg"
echo "[obs-websocket] Modifying obs-websocket.so"
install_name_tool \
-change /usr/local/opt/qt/lib/QtWidgets.framework/Versions/5/QtWidgets \
@executable_path/../Frameworks/QtWidgets.framework/Versions/5/QtWidgets \
-change /usr/local/opt/qt/lib/QtGui.framework/Versions/5/QtGui \
@executable_path/../Frameworks/QtGui.framework/Versions/5/QtGui \
-change /usr/local/opt/qt/lib/QtCore.framework/Versions/5/QtCore \
@executable_path/../Frameworks/QtCore.framework/Versions/5/QtCore \
./build/obs-websocket.so
# Check if replacement worked
echo "[obs-websocket] Dependencies for obs-websocket"
otool -L ./build/obs-websocket.so
if [[ "$RELEASE_MODE" == "True" ]]; then
echo "[obs-websocket] Signing plugin binary: obs-websocket.so"
codesign --sign "$CODE_SIGNING_IDENTITY" ./build/obs-websocket.so
else
echo "[obs-websocket] Skipped plugin codesigning"
fi
echo "[obs-websocket] Actual package build"
packagesbuild ./CI/macos/obs-websocket.pkgproj
echo "[obs-websocket] Renaming obs-websocket.pkg to $FILENAME"
mv ./release/obs-websocket.pkg ./release/$FILENAME_UNSIGNED
if [[ "$RELEASE_MODE" == "True" ]]; then
echo "[obs-websocket] Signing installer: $FILENAME"
productsign \
--sign "$INSTALLER_SIGNING_IDENTITY" \
./release/$FILENAME_UNSIGNED \
./release/$FILENAME
rm ./release/$FILENAME_UNSIGNED
echo "[obs-websocket] Submitting installer $FILENAME for notarization"
zip -r ./release/$FILENAME.zip ./release/$FILENAME
UPLOAD_RESULT=$(xcrun altool \
--notarize-app \
--primary-bundle-id "fr.palakis.obs-websocket" \
--username "$AC_USERNAME" \
--password "$AC_PASSWORD" \
--asc-provider "$AC_PROVIDER_SHORTNAME" \
--file "./release/$FILENAME.zip")
rm ./release/$FILENAME.zip
REQUEST_UUID=$(echo $UPLOAD_RESULT | awk -F ' = ' '/RequestUUID/ {print $2}')
echo "Request UUID: $REQUEST_UUID"
echo "[obs-websocket] Wait for notarization result"
# Pieces of code borrowed from rednoah/notarized-app
while sleep 30 && date; do
CHECK_RESULT=$(xcrun altool \
--notarization-info "$REQUEST_UUID" \
--username "$AC_USERNAME" \
--password "$AC_PASSWORD" \
--asc-provider "$AC_PROVIDER_SHORTNAME")
echo $CHECK_RESULT
if ! grep -q "Status: in progress" <<< "$CHECK_RESULT"; then
echo "[obs-websocket] Staple ticket to installer: $FILENAME"
xcrun stapler staple ./release/$FILENAME
break
fi
done
else
echo "[obs-websocket] Skipped installer codesigning and notarization"
fi

24
CI/package-ubuntu.sh Executable file
View File

@ -0,0 +1,24 @@
#!/bin/bash
set -e
export GIT_HASH=$(git rev-parse --short HEAD)
export PKG_VERSION="1-$GIT_HASH-$BRANCH_SHORT_NAME-git"
if [[ $BRANCH_FULL_NAME =~ ^refs/tags/ ]]; then
export PKG_VERSION="$BRANCH_SHORT_NAME"
echo "[obs-websocket] Branch is a tag. Setting version to $PKG_VERSION."
fi
cd ./build
PAGER="cat" sudo checkinstall -y --type=debian --fstrans=no --nodoc \
--backup=no --deldoc=yes --install=no \
--pkgname=obs-websocket --pkgversion="$PKG_VERSION" \
--pkglicense="GPLv2.0" --maintainer="stephane.lepin@gmail.com" \
--pkggroup="video" \
--pkgsource="https://github.com/Palakis/obs-websocket" \
--requires="obs-studio \(\>= 25.0.7\), libqt5core5a, libqt5widgets5, qt5-image-formats-plugins" \
--pakdir="../package"
sudo chmod ao+r ../package/*

12
CI/package-windows.cmd Normal file
View File

@ -0,0 +1,12 @@
mkdir package
cd package
git rev-parse --short HEAD > package-version.txt
set /p PackageVersion=<package-version.txt
del package-version.txt
REM Package ZIP archive
7z a "obs-websocket-%PackageVersion%-Windows.zip" "..\release\*"
REM Build installer
iscc ..\installer\installer.iss /O. /F"obs-websocket-%PackageVersion%-Windows-Installer"

View File

@ -0,0 +1,37 @@
@echo off
SETLOCAL EnableDelayedExpansion
REM If obs-studio directory does not exist, clone the git repo
if not exist %OBSPath% (
echo obs-studio directory does not exist
git clone https://github.com/obsproject/obs-studio %OBSPath%
cd /D %OBSPath%\
git describe --tags --abbrev=0 --exclude="*-rc*" > "%OBSPath%\obs-studio-latest-tag.txt"
set /p OBSLatestTag=<"%OBSPath%\obs-studio-latest-tag.txt"
)
REM Prepare OBS Studio builds
echo Running CMake...
cd /D %OBSPath%
echo git checkout %OBSLatestTag%
git checkout %OBSLatestTag%
echo:
if not exist build32 mkdir build32
if not exist build64 mkdir build64
echo Running cmake for obs-studio %OBSLatestTag% 32-bit...
cd build32
cmake -G "Visual Studio 16 2019" -A Win32 -DCMAKE_SYSTEM_VERSION=10.0 -DQTDIR="%QTDIR32%" -DDepsPath="%DepsPath32%" -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 16 2019" -A x64 -DCMAKE_SYSTEM_VERSION=10.0 -DQTDIR="%QTDIR64%" -DDepsPath="%DepsPath64%" -DDISABLE_PLUGINS=true -DCOPIED_DEPENDENCIES=false -DCOPY_DEPENDENCIES=true ..
echo:
echo:
dir "%OBSPath%\libobs"

7
CI/prepare-windows.cmd Normal file
View File

@ -0,0 +1,7 @@
mkdir build32
mkdir build64
cd build32
cmake -G "Visual Studio 16 2019" -A Win32 -DCMAKE_SYSTEM_VERSION=10.0 -DQTDIR="%QTDIR32%" -DLibObs_DIR="%OBSPath%\build32\libobs" -DLIBOBS_INCLUDE_DIR="%OBSPath%\libobs" -DLIBOBS_LIB="%OBSPath%\build32\libobs\%build_config%\obs.lib" -DOBS_FRONTEND_LIB="%OBSPath%\build32\UI\obs-frontend-api\%build_config%\obs-frontend-api.lib" ..
cd ..\build64
cmake -G "Visual Studio 16 2019" -A x64 -DCMAKE_SYSTEM_VERSION=10.0 -DQTDIR="%QTDIR64%" -DLibObs_DIR="%OBSPath%\build64\libobs" -DLIBOBS_INCLUDE_DIR="%OBSPath%\libobs" -DLIBOBS_LIB="%OBSPath%\build64\libobs\%build_config%\obs.lib" -DOBS_FRONTEND_LIB="%OBSPath%\build64\UI\obs-frontend-api\%build_config%\obs-frontend-api.lib" ..

192
CMakeLists.txt Normal file
View File

@ -0,0 +1,192 @@
cmake_minimum_required(VERSION 3.5)
project(obs-websocket VERSION 5.0.0)
set(CMAKE_PREFIX_PATH "${QTDIR}")
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_definitions(-DASIO_STANDALONE)
if (${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm")
set(CMAKE_CXX_FLAGS "-mfpu=neon")
endif()
if (WIN32 OR APPLE)
include(external/FindLibObs.cmake)
endif()
find_package(LibObs REQUIRED)
find_package(Qt5 REQUIRED COMPONENTS Core Widgets)
set(obs-websocket_SOURCES
src/obs-websocket.cpp
src/rpc/RpcRequestData.cpp
src/rpc/RpcRequestResponse.cpp
src/rpc/RpcEvent.cpp
src/forms/settings-dialog.cpp)
set(obs-websocket_HEADERS
src/obs-websocket.h
src/rpc/RpcRequest.h
src/rpc/RpcEvent.h
src/forms/settings-dialog.h)
# --- Platform-independent build settings ---
add_library(obs-websocket MODULE
${obs-websocket_SOURCES}
${obs-websocket_HEADERS})
include_directories(
"${LIBOBS_INCLUDE_DIR}/../UI/obs-frontend-api"
${Qt5Core_INCLUDES}
${Qt5Widgets_INCLUDES}
"${CMAKE_SOURCE_DIR}/deps/asio/asio/include"
"${CMAKE_SOURCE_DIR}/deps/websocketpp")
target_link_libraries(obs-websocket
libobs
Qt5::Core
Qt5::Widgets)
# --- End of section ---
# --- Windows-specific build settings and tasks ---
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 !")
endif()
if(MSVC)
# Enable Multicore Builds and disable FH4 (to not depend on VCRUNTIME140_1.DLL)
add_definitions(/MP /d2FH4-)
endif()
add_definitions(-D_WEBSOCKETPP_CPP11_STL_)
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(ARCH_NAME "64bit")
set(OBS_BUILDDIR_ARCH "build64")
else()
set(ARCH_NAME "32bit")
set(OBS_BUILDDIR_ARCH "build32")
endif()
include_directories(
"${LIBOBS_INCLUDE_DIR}/../${OBS_BUILDDIR_ARCH}/UI"
)
target_link_libraries(obs-websocket
"${OBS_FRONTEND_LIB}")
# --- 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"
"${RELEASE_DIR}/obs-plugins/${ARCH_NAME}")
COMMAND if $<CONFIG:Release>==1 ("${CMAKE_COMMAND}" -E copy_directory
"${PROJECT_SOURCE_DIR}/data"
"${RELEASE_DIR}/data/obs-plugins/obs-websocket")
COMMAND if $<CONFIG:Release>==1 ("${CMAKE_COMMAND}" -E copy
"$<TARGET_FILE:obs-websocket>"
"${RELEASE_DIR}/obs-plugins/${ARCH_NAME}")
# In Release mode, copy Qt image format plugins
COMMAND if $<CONFIG:Release>==1 (
"${CMAKE_COMMAND}" -E copy
"${QTDIR}/plugins/imageformats/qjpeg.dll"
"${RELEASE_DIR}/bin/${ARCH_NAME}/imageformats/qjpeg.dll")
COMMAND if $<CONFIG:RelWithDebInfo>==1 (
"${CMAKE_COMMAND}" -E copy
"${QTDIR}/plugins/imageformats/qjpeg.dll"
"${RELEASE_DIR}/bin/${ARCH_NAME}/imageformats/qjpeg.dll")
# 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>"
"${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
"$<TARGET_FILE:obs-websocket>"
"${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")
COMMAND if $<CONFIG:Debug>==1 (
"${CMAKE_COMMAND}" -E copy_directory
"${PROJECT_SOURCE_DIR}/data"
"${LIBOBS_INCLUDE_DIR}/../${OBS_BUILDDIR_ARCH}/rundir/$<CONFIG>/data/obs-plugins/obs-websocket")
)
# --- End of sub-section ---
endif()
# --- End of section ---
# --- Linux-specific build settings and tasks ---
if(UNIX AND NOT APPLE)
include(GNUInstallDirs)
set_target_properties(obs-websocket PROPERTIES PREFIX "")
target_link_libraries(obs-websocket obs-frontend-api)
file(GLOB locale_files data/locale/*.ini)
set(CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS
OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_WRITE GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
if(${USE_UBUNTU_FIX})
install(TARGETS obs-websocket LIBRARY
DESTINATION "/usr/lib/obs-plugins"
PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
endif()
install(TARGETS obs-websocket LIBRARY
DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}/obs-plugins"
PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
install(FILES ${locale_files}
DESTINATION "${CMAKE_INSTALL_FULL_DATAROOTDIR}/obs/obs-plugins/obs-websocket/locale")
endif()
# --- End of section ---
# -- OS X specific build settings and tasks --
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()
# -- End of section --

82
CONTRIBUTING.md Normal file
View File

@ -0,0 +1,82 @@
# Contributing to obs-websocket
## Translating obs-websocket to your language
Localization happens on [Crowdin](https://crowdin.com/project/obs-websocket)
## Branches
**Development happens on `4.x-current`**
## Writing code for obs-websocket
### Code Formatting Guidelines
* Function and variable names: snake_case for C names, camelCase for C++ method names
* Request and Event names should use MixedCaps names
* Request and Event json properties should use camelCase. For more detailed info on property naming, see [Google's JSON Style Guide](https://google.github.io/styleguide/jsoncstyleguide.xml)
* Code is indented with Tabs. Assume they are 8 columns wide
* 80 columns max code width. (Docs can be larger)
* New and updated requests/events must always come with accompanying documentation comments (see existing protocol elements for examples).
These are required to automatically generate the [protocol specification document](docs/generated/protocol.md).
### Code Best-Practices
* Favor return-early code and avoid wrapping huge portions of code in conditionals. As an example, this:
```cpp
if (success) {
return req->SendOKResponse();
} else {
return req->SendErrorResponse("something went wrong");
}
```
is better like this:
```cpp
if (!success) {
return req->SendErrorResponse("something went wrong");
}
return req->SendOKResponse();
```
* Some example common response/request property names are:
* `sceneName` - The name of a scene
* `sourceName` - The name of a source
* `fromScene` - From a scene - scene name
### Commit Guidelines
* Commits follow the 50/72 standard:
* 50 characters max for the commit title (excluding scope name)
* One empty line after the title
* Description wrapped to 72 columns max width per line.
* Commit titles:
* Use present tense
* Prefix the title with a "scope" name
* e.g: "CI: fix wrong behaviour when packaging for OS X"
* Typical scopes: CI, General, Requests, Events, Server
**Example commit:**
```
Requests: Add GetTransitionPosition
Adds a new request called `GetTransitionPosition` which gets the current
transition's state from 0.0f to 1.0f. Works with both auto and manual
transitions.
```
### Pull Requests
* Pull Requests must never be based off your fork's main branch (in this case, `4.x-current`).
* Start your work in a newly named branch based on the upstream main one (e.g.: `feature/cool-new-feature`, `bugfix/fix-palakis-mistakes`, ...)
* Only open a pull request if you are ready to show off your work.
* If your work is not done yet, but for any reason you need to PR it (like collecting discussions, testing with CI, getting testers),
create it as a Draft Pull Request (open the little arrow menu next to the "Create pull request" button, then select "Create draft pull request").

339
LICENSE Normal file
View File

@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc., <http://fsf.org/>
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
{description}
Copyright (C) {year} {fullname}
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
{signature of Ty Coon}, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

132
README.md Normal file
View File

@ -0,0 +1,132 @@
# obs-websocket
<p align="center">
<img src="/.github/images/obsws_logo.png" width=150 align="center">
</p>
WebSockets API for OBS Studio.
[![Build Status](https://dev.azure.com/Palakis/obs-websocket/_apis/build/status/Palakis.obs-websocket?branchName=4.x-current)](https://dev.azure.com/Palakis/obs-websocket/_build/latest?definitionId=2&branchName=4.x-current)
[![CodeFactor](https://www.codefactor.io/repository/github/palakis/obs-websocket/badge)](https://www.codefactor.io/repository/github/palakis/obs-websocket)
[![Twitter](https://img.shields.io/twitter/url/https/twitter.com/fold_left.svg?style=social&label=Follow%20%40LePalakis)](https://twitter.com/LePalakis)
[![Discord](https://img.shields.io/discord/715691013825364120.svg?label=&logo=discord&logoColor=ffffff&color=7389D8&labelColor=6A7EC2)](https://discord.gg/WBaSQ3A)
[![Financial Contributors on Open Collective](https://opencollective.com/obs-websocket/all/badge.svg?label=financial+contributors)](https://opencollective.com/obs-websocket)
## Downloads
Binaries for Windows, MacOS, and Linux are available in the [Releases](https://github.com/Palakis/obs-websocket/releases) section.
### Homebrew
If you're using MacOS you can use Homebrew for installation as well:
```sh
brew install obs-websocket
```
## Using obs-websocket
Here is a list of available web clients: (compatible with tablets and other touch interfaces)
- [Niek/obs-web](https://github.com/Niek/obs-web)
- [t2t2/obs-tablet-remote](https://github.com/t2t2/obs-tablet-remote)
It is **highly recommended** to protect obs-websocket with a password against unauthorized control. To do this, open the "Websocket server settings" dialog under OBS' "Tools" menu. In the settings dialogs, you can enable or disable authentication and set a password for it.
### Possible use cases
- Remote control OBS from a phone or tablet on the same local network
- Change your stream overlay/graphics based on the current scene
- Automate scene switching with a third-party program (e.g. : auto-pilot, foot pedal, ...)
### For developers
The server is a typical Websockets server running by default on port 4444 (the port number can be changed in the Settings dialog).
The protocol understood by the server is documented in [PROTOCOL.md](docs/generated/protocol.md).
Here's a list of available language APIs for obs-websocket :
- Javascript (browser & nodejs): [obs-websocket-js](https://github.com/haganbmj/obs-websocket-js) by Brendan Hagan
- C#/VB.NET: [obs-websocket-dotnet](https://github.com/Palakis/obs-websocket-dotnet)
- Python 2 and 3: [obs-websocket-py](https://github.com/Elektordi/obs-websocket-py) by Guillaume Genty a.k.a Elektordi
- Python 3.5+ with asyncio: [obs-ws-rc](https://github.com/KirillMysnik/obs-ws-rc) by Kirill Mysnik
- Python 3.6+ with asyncio: [simpleobsws](https://github.com/IRLToolkit/simpleobsws) by tt2468
- Java 8+: [obs-websocket-java](https://github.com/Twasi/websocket-obs-java) by TwasiNET
- Java 11+: [obs-java-client](https://github.com/harm27/obs-java-client) by harm27
- Golang: [go-obs-websocket](https://github.com/christopher-dG/go-obs-websocket) by Chris de Graaf
- Rust: [obws](https://github.com/dnaka91/obws) by dnaka91
- HTTP API: [obs-websocket-http](https://github.com/IRLToolkit/obs-websocket-http) by tt2468
- CLI: [obs-cli](https://github.com/leafac/obs-cli) by leafac
I'd like to know what you're building with or for obs-websocket. If you do something in this fashion, feel free to drop a message in `#project-showoff` in the [discord server!](https://discord.gg/WBaSQ3A)
### Securing obs-websocket (via TLS/SSL)
If you are intending to use obs-websocket outside of a LAN environment, it is highly recommended to secure the connection using a tunneling service.
See the SSL [tunnelling guide](SSL-TUNNELLING.md) for easy instructions on how to encrypt your websocket connection.
## Compiling obs-websocket
See the [build instructions](BUILDING.md).
## Contributing
See [the contributing document](/CONTRIBUTING.md)
## Translations
**Your help is welcome on translations.**
Please join the localization project on [Crowdin](https://crowdin.com/project/obs-websocket)
## Special thanks
Thank you so much to all of the contibutors [(here)](https://github.com/Palakis/obs-websocket/graphs/contributors) for your amazing help.
And also: special thanks to supporters of the project!
## Supporters
These supporters have contributed financially to the project and made possible the addition of several features into obs-websocket. Many thanks to them!
---
[Support Class](http://supportclass.net) designs and develops professional livestreams, with services ranging from broadcast graphics design and integration to event organization, along many other skills.
[![Support Class](.github/images/supportclass_logo_blacktext.png)](http://supportclass.net)
---
[MediaUnit](http://www.mediaunit.no) is a Norwegian media company developing products and services for the media industry, primarly focused on web and events.
[![MediaUnit](.github/images/mediaunit_logo_black.png)](http://www.mediaunit.no/)
## Contributors
### Code Contributors
This project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].
<a href="https://github.com/Palakis/obs-websocket/graphs/contributors"><img src="https://opencollective.com/obs-websocket/contributors.svg?width=890&button=false" /></a>
### Financial Contributors
Become a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/obs-websocket/contribute)]
#### Individuals
<a href="https://opencollective.com/obs-websocket"><img src="https://opencollective.com/obs-websocket/individuals.svg?width=890"></a>
#### Organizations
Support this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/obs-websocket/contribute)]
<a href="https://opencollective.com/obs-websocket/organization/0/website"><img src="https://opencollective.com/obs-websocket/organization/0/avatar.svg"></a>
<a href="https://opencollective.com/obs-websocket/organization/1/website"><img src="https://opencollective.com/obs-websocket/organization/1/avatar.svg"></a>
<a href="https://opencollective.com/obs-websocket/organization/2/website"><img src="https://opencollective.com/obs-websocket/organization/2/avatar.svg"></a>
<a href="https://opencollective.com/obs-websocket/organization/3/website"><img src="https://opencollective.com/obs-websocket/organization/3/avatar.svg"></a>
<a href="https://opencollective.com/obs-websocket/organization/4/website"><img src="https://opencollective.com/obs-websocket/organization/4/avatar.svg"></a>
<a href="https://opencollective.com/obs-websocket/organization/5/website"><img src="https://opencollective.com/obs-websocket/organization/5/avatar.svg"></a>
<a href="https://opencollective.com/obs-websocket/organization/6/website"><img src="https://opencollective.com/obs-websocket/organization/6/avatar.svg"></a>
<a href="https://opencollective.com/obs-websocket/organization/7/website"><img src="https://opencollective.com/obs-websocket/organization/7/avatar.svg"></a>
<a href="https://opencollective.com/obs-websocket/organization/8/website"><img src="https://opencollective.com/obs-websocket/organization/8/avatar.svg"></a>
<a href="https://opencollective.com/obs-websocket/organization/9/website"><img src="https://opencollective.com/obs-websocket/organization/9/avatar.svg"></a>

45
SSL-TUNNELLING.md Normal file
View File

@ -0,0 +1,45 @@
# Connecting over a TLS/secure connection (or remotely)
If you want to expose the WebSocket server of obs-websocket over a secure TLS connection (or to connect remotely), the easiest approach is to use a localhost tunneling service like [ngrok](https://ngrok.com/) or [pagekite](https://pagekite.net/).
**Before doing this, secure the WebSocket server first by enabling authentication with a strong password!**
**Please bear in mind that doing this will expose your OBS instance to the open Internet and the security risks it implies. *You've been warned!***
## ngrok
[Install the ngrok CLI tool](https://ngrok.com/download) on a linux OS, then start ngrok bound to port 4444 like this:
```bash
ngrok http 4444
```
The ngrok command will output something like this:
```text
ngrok by @inconshreveable
Tunnel Status online
Version 2.0/2.0
Web Interface http://127.0.0.1:4040
Forwarding http://TUNNEL_ID.ngrok.io -> localhost:4444
Forwarding https://TUNNEL_ID.ngrok.io -> localhost:4444
```
Where `TUNNEL_ID` is, as the name implies, the unique name of your ngrok tunnel. You'll get a new one every time you start ngrok.
Then, use `wss://TUNNEL_ID.ngrok.io` to connect to obs-websocket over TLS.
See the [ngrok documentation](https://ngrok.com/docs) for more tunneling options and settings.
## PageKite
[Install the PageKite CLI tool](http://pagekite.net/downloads), then start PageKite bound to port 4444 like this (replace NAME with one of your choosing):
```bash
python pagekite.py 4444 NAME.pagekite.me
```
Then, use `wss://NAME.pagekite.me` to connect to obs-websocket over TLS.

183
azure-pipelines.yml Normal file
View File

@ -0,0 +1,183 @@
variables:
isReleaseMode: ${{ startsWith(variables['Build.SourceBranch'], 'refs/tags/') }}
trigger:
branches:
include:
- '4.x-current'
tags:
include:
- '*'
jobs:
- job: 'GenerateDocs'
condition: |
or(
eq(variables['Build.SourceBranch'], 'refs/heads/4.x-current'),
eq(variables['Build.SourceBranch'], 'refs/heads/master')
)
pool:
vmImage: 'ubuntu-18.04'
steps:
- checkout: self
submodules: false
- script: ./CI/generate-docs.sh
displayName: 'Generate docs'
env:
CHECKOUT_REF: $(Build.SourceBranch)
GH_TOKEN: $(GithubToken)
- job: 'Build_Windows'
pool:
vmImage: 'windows-2019'
variables:
build_config: RelWithDebInfo
DepsBasePath: 'D:\obsdependencies'
DepsPath32: '$(DepsBasePath)\win32'
DepsPath64: '$(DepsBasePath)\win64'
QtBaseDir: 'D:\QtDep'
QTDIR32: '$(QtBaseDir)\5.10.1\msvc2017'
QTDIR64: '$(QtBaseDir)\5.10.1\msvc2017_64'
OBSPath: 'D:\obs-studio'
steps:
- checkout: self
submodules: true
- script: ./CI/install-qt-win.cmd
displayName: 'Install Qt'
env:
QtBaseDir: $(QtBaseDir)
- task: Cache@2
displayName: Restore cached OBS Studio dependencies
inputs:
key: 'obsdeps | "$(Agent.OS)"'
restoreKeys: |
obsdeps | "$(Agent.OS)"
path: $(DepsBasePath)
- script: ./CI/download-obs-deps.cmd
displayName: 'Download OBS Studio dependencies'
- task: Cache@2
displayName: Restore cached OBS Studio builds
inputs:
key: 'obs | "$(Agent.OS)"'
restoreKeys: |
obs | "$(Agent.OS)"
path: $(OBSPath)
- script: ./CI/prepare-obs-windows.cmd
displayName: 'Checkout & CMake OBS Studio'
env:
build_config: $(build_config)
DepsPath32: $(DepsPath32)
DepsPath64: $(DepsPath64)
QTDIR32: $(QTDIR32)
QTDIR64: $(QTDIR64)
OBSPath: $(OBSPath)
- task: MSBuild@1
displayName: 'Build OBS Studio 32-bit'
inputs:
msbuildArguments: '/m /p:Configuration=$(build_config)'
solution: '$(OBSPath)\build32\obs-studio.sln'
- task: MSBuild@1
displayName: 'Build OBS Studio 64-bit'
inputs:
msbuildArguments: '/m /p:Configuration=$(build_config)'
solution: '$(OBSPath)\build64\obs-studio.sln'
- script: ./CI/prepare-windows.cmd
displayName: 'CMake obs-websocket'
env:
build_config: $(build_config)
QTDIR32: $(QTDIR32)
QTDIR64: $(QTDIR64)
OBSPath: $(OBSPath)
- task: MSBuild@1
displayName: 'Build obs-websocket 32-bit'
inputs:
msbuildArguments: '/m /p:Configuration=$(build_config)'
solution: '.\build32\obs-websocket.sln'
- task: MSBuild@1
displayName: 'Build obs-websocket 64-bit'
inputs:
msbuildArguments: '/m /p:Configuration=$(build_config)'
solution: '.\build64\obs-websocket.sln'
- script: ./CI/package-windows.cmd
displayName: 'Package obs-websocket'
- task: PublishBuildArtifacts@1
displayName: 'Upload package artifacts'
inputs:
pathtoPublish: './package'
artifactName: 'windows_build'
- job: 'Build_Linux'
pool:
vmImage: 'ubuntu-18.04'
variables:
BUILD_REASON: $(Build.Reason)
BRANCH_SHORT_NAME: $(Build.SourceBranchName)
BRANCH_FULL_NAME: $(Build.SourceBranch)
steps:
- checkout: self
submodules: true
- script: ./CI/install-dependencies-ubuntu.sh
displayName: 'Install dependencies'
- script: ./CI/build-ubuntu.sh
displayName: 'Build obs-websocket'
- script: ./CI/package-ubuntu.sh
displayName: 'Package obs-websocket'
- task: PublishBuildArtifacts@1
inputs:
pathtoPublish: './package'
artifactName: 'deb_build'
- job: 'Build_macOS'
pool:
vmImage: 'macos-10.14'
steps:
- checkout: self
submodules: true
- script: ./CI/install-dependencies-macos.sh
displayName: 'Install dependencies'
- script: ./CI/install-build-obs-macos.sh
displayName: 'Build OBS'
- script: ./CI/build-macos.sh
displayName: 'Build obs-websocket'
- task: InstallAppleCertificate@2
displayName: 'Install release signing certificates'
condition: eq(variables['isReleaseMode'], true)
inputs:
certSecureFile: 'Certificates.p12'
certPwd: $(secrets.macOS.certificatesImportPassword)
- script: ./CI/package-macos.sh
displayName: 'Package obs-websocket'
env:
RELEASE_MODE: $(isReleaseMode)
CODE_SIGNING_IDENTITY: $(secrets.macOS.codeSigningIdentity)
INSTALLER_SIGNING_IDENTITY: $(secrets.macOS.installerSigningIdentity)
AC_USERNAME: $(secrets.macOS.notarization.username)
AC_PASSWORD: $(secrets.macOS.notarization.password)
AC_PROVIDER_SHORTNAME: $(secrets.macOS.notarization.providerShortName)
- task: PublishBuildArtifacts@1
inputs:
pathtoPublish: './release'
artifactName: 'macos_build'

3
crowdin.yml Normal file
View File

@ -0,0 +1,3 @@
files:
- source: /data/locale/en-US.ini
translation: /data/locale/%locale%.ini

1
data/locale/ar-SA.ini Normal file
View File

@ -0,0 +1 @@

18
data/locale/de-DE.ini Normal file
View File

@ -0,0 +1,18 @@
OBSWebsocket.Settings.DialogTitle="WebSockets-Servereinstellungen"
OBSWebsocket.Settings.ServerEnable="WebSockets-Server aktivieren"
OBSWebsocket.Settings.ServerPort="Server-Port"
OBSWebsocket.Settings.AuthRequired="Authentifizierung aktivieren"
OBSWebsocket.Settings.Password="Passwort"
OBSWebsocket.Settings.LockToIPv4="Nur IPv4 verwenden (deaktiviert IPv6)"
OBSWebsocket.Settings.DebugEnable="Debug-Protokollierung aktivieren"
OBSWebsocket.Settings.AlertsEnable="Infobereichbenachrichtigungen aktivieren"
OBSWebsocket.NotifyConnect.Title="Neue Websocket-Verbindung"
OBSWebsocket.NotifyConnect.Message="Client %1 verbunden"
OBSWebsocket.NotifyDisconnect.Title="Websocket-Client getrennt"
OBSWebsocket.NotifyDisconnect.Message="Client %1 getrennt"
OBSWebsocket.Server.StartFailed.Title="Websocket-Serverfehler"
OBSWebsocket.Server.StartFailed.Message="Der WebSocket-Server konnte nicht gestartet werden, mögliche Gründe:\n - Der TCP-Port %1 wird möglicherweise gerade von einem anderen Programm verwendet. Versuchen Sie einen anderen Port in den Websocket-Servereinstellungen zu setzen oder alle Programme zu beenden, die den Port möglicherweise verwenden.\n - Fehler: %2"
OBSWebsocket.ProfileChanged.Started="WebSockets-Server in diesem Profil aktiviert. Server gestartet."
OBSWebsocket.ProfileChanged.Stopped="WebSockets-Server in diesem Profil deaktiviert. Server gestoppt."
OBSWebsocket.ProfileChanged.Restarted="WebSockets-Server in diesem Profil geändert. Server startet neu."

21
data/locale/en-US.ini Normal file
View File

@ -0,0 +1,21 @@
OBSWebsocket.Settings.DialogTitle="WebSockets Server Settings"
OBSWebsocket.Settings.ServerEnable="Enable WebSockets server"
OBSWebsocket.Settings.ServerPort="Server Port"
OBSWebsocket.Settings.AuthRequired="Enable authentication"
OBSWebsocket.Settings.Password="Password"
OBSWebsocket.Settings.LockToIPv4="Lock server to only using IPv4"
OBSWebsocket.Settings.DebugEnable="Enable debug logging"
OBSWebsocket.Settings.AlertsEnable="Enable System Tray Alerts"
OBSWebsocket.Settings.AuthDisabledWarning="Running obs-websocket with authentication disabled is not recommended, as it allows attackers to easily collect sensetive data. Are you sure you want to proceed?"
OBSWebsocket.NotifyConnect.Title="New WebSocket connection"
OBSWebsocket.NotifyConnect.Message="Client %1 connected"
OBSWebsocket.NotifyDisconnect.Title="WebSocket client disconnected"
OBSWebsocket.NotifyDisconnect.Message="Client %1 disconnected"
OBSWebsocket.Server.StartFailed.Title="WebSockets Server failure"
OBSWebsocket.Server.StartFailed.Message="The WebSockets server failed to start, maybe because:\n - TCP port %1 may currently be in use elsewhere on this system, possibly by another application. Try setting a different TCP port in the WebSocket server settings, or stop any application that could be using this port.\n - Error message: %2"
OBSWebsocket.ProfileChanged.Started="WebSockets server enabled in this profile. Server started."
OBSWebsocket.ProfileChanged.Stopped="WebSockets server disabled in this profile. Server stopped."
OBSWebsocket.ProfileChanged.Restarted="WebSockets server port changed in this profile. Server restarted."
OBSWebsocket.InitialPasswordSetup.Title="obs-websocket - Server Password Configuration"
OBSWebsocket.InitialPasswordSetup.Text="It looks like you are running obs-websocket for the first time. Do you want to configure a password now for the WebSockets server? Setting a password is highly recommended."
OBSWebsocket.InitialPasswordSetup.DismissedText="You can configure a server password later in the WebSockets Server Settings. (Under the Tools menu of OBS Studio)"

16
data/locale/es-ES.ini Normal file
View File

@ -0,0 +1,16 @@
OBSWebsocket.Settings.DialogTitle="Configuración del servidor WebSocket"
OBSWebsocket.Settings.ServerEnable="Habilitar el servidor WebSockets"
OBSWebsocket.Settings.ServerPort="Puerto del Servidor"
OBSWebsocket.Settings.AuthRequired="Habilitar autenticación"
OBSWebsocket.Settings.Password="Contraseña"
OBSWebsocket.Settings.DebugEnable="Habilitar registro de depuración"
OBSWebsocket.Settings.AlertsEnable="Habilitar alertas en la bandeja de sistema"
OBSWebsocket.NotifyConnect.Title="Nueva conexión WebSocket"
OBSWebsocket.NotifyConnect.Message="Cliente %1 conectado"
OBSWebsocket.NotifyDisconnect.Title="Cliente WebSocket desconectado"
OBSWebsocket.NotifyDisconnect.Message="Cliente %1 desconectado"
OBSWebsocket.Server.StartFailed.Title="Falla en el servidor WebSockets"
OBSWebsocket.ProfileChanged.Started="El servidor WebSocket esta habilitado en este perfil. El servidor ha iniciado."
OBSWebsocket.ProfileChanged.Stopped="Servidor WebSockets deshabilitado en este perfil. Servidor detenido."
OBSWebsocket.ProfileChanged.Restarted="Puerto del servidor WebSockets cambiado en este perfil. Servidor reiniciado."

16
data/locale/fr-FR.ini Normal file
View File

@ -0,0 +1,16 @@
OBSWebsocket.Settings.DialogTitle="Paramètres du serveur WebSockets"
OBSWebsocket.Settings.ServerEnable="Activer le serveur WebSocket"
OBSWebsocket.Settings.ServerPort="Port du serveur"
OBSWebsocket.Settings.AuthRequired="Activer l'authentification"
OBSWebsocket.Settings.Password="Mot de passe"
OBSWebsocket.Settings.DebugEnable="Débogage dans le fichier journal"
OBSWebsocket.Settings.AlertsEnable="Notifications de connexion/déconnexion"
OBSWebsocket.NotifyConnect.Title="Nouvelle connexion WebSocket"
OBSWebsocket.NotifyConnect.Message="Le client %1 s'est connecté"
OBSWebsocket.NotifyDisconnect.Title="Déconnexion WebSocket"
OBSWebsocket.NotifyDisconnect.Message="Le client %1 s'est déconnecté"
OBSWebsocket.Server.StartFailed.Title="Impossible de démarrer le serveur WebSockets"
OBSWebsocket.ProfileChanged.Started="Serveur WebSockets actif dans ce profil."
OBSWebsocket.ProfileChanged.Stopped="Serveur WebSockets désactivé dans ce profil."
OBSWebsocket.ProfileChanged.Restarted="Le port actuel diffère du port configuré dans ce profil. Serveur WebSockets redémarré."

1
data/locale/hi-IN.ini Normal file
View File

@ -0,0 +1 @@

18
data/locale/it-IT.ini Normal file
View File

@ -0,0 +1,18 @@
OBSWebsocket.Settings.DialogTitle="Impostazioni del server di WebSocket"
OBSWebsocket.Settings.ServerEnable="Abilitare il server WebSockets"
OBSWebsocket.Settings.ServerPort="Porta del server"
OBSWebsocket.Settings.AuthRequired="Abilitare l'autenticazione"
OBSWebsocket.Settings.Password="Password"
OBSWebsocket.Settings.LockToIPv4="Blocca il server per usare solo IPv4"
OBSWebsocket.Settings.DebugEnable="Attivare la registrazione di debug"
OBSWebsocket.Settings.AlertsEnable="Attivare gli avvisi di vassoio di sistema"
OBSWebsocket.NotifyConnect.Title="Nuova connessione WebSocket"
OBSWebsocket.NotifyConnect.Message="%1 cliente collegato"
OBSWebsocket.NotifyDisconnect.Title="WebSocket cliente disconnesso"
OBSWebsocket.NotifyDisconnect.Message="%1 cliente disconnesso"
OBSWebsocket.Server.StartFailed.Title="Errore del WebSocket Server"
OBSWebsocket.Server.StartFailed.Message="L'avvio del server WebSockets è fallito, forse perché:\n - La porta TCP %1 può attualmente essere in uso altrove su questo sistema, forse da un'altra applicazione. Provare a impostare una porta TCP diversa nelle impostazioni del server WebSocket o interrompere qualsiasi applicazione che potrebbe utilizzare questa porta.\n - Messaggio di errore: %2"
OBSWebsocket.ProfileChanged.Started="Server WebSockets abilitato in questo profilo. Il server è avviato."
OBSWebsocket.ProfileChanged.Stopped="Server WebSocket disabilitato in questo profilo. Server interrotto."
OBSWebsocket.ProfileChanged.Restarted="La porta del server WebSocket è stata modificata in questo profilo. Il server è stato riavviato."

16
data/locale/ja-JP.ini Normal file
View File

@ -0,0 +1,16 @@
OBSWebsocket.Settings.DialogTitle="Websocket サーバー設定"
OBSWebsocket.Settings.ServerEnable="WebSockets サーバーを有効にする"
OBSWebsocket.Settings.ServerPort="サーバーポート"
OBSWebsocket.Settings.AuthRequired="認証を有効にする"
OBSWebsocket.Settings.Password="パスワード"
OBSWebsocket.Settings.DebugEnable="デバッグログを有効にする"
OBSWebsocket.Settings.AlertsEnable="システムトレイ通知を有効にする"
OBSWebsocket.NotifyConnect.Title="新しい WebSocket 接続"
OBSWebsocket.NotifyConnect.Message="接続されているクライアント %1"
OBSWebsocket.NotifyDisconnect.Title="WebSocket クライアントが切断されました"
OBSWebsocket.NotifyDisconnect.Message="切断されたクライアント %1"
OBSWebsocket.Server.StartFailed.Title="WebSockets サーバー障害"
OBSWebsocket.ProfileChanged.Started="このプロファイルでWebSocketサーバが有効になりました。サーバを起動しました。"
OBSWebsocket.ProfileChanged.Stopped="このプロファイルでWebSocketサーバが無効になりました。サーバを停止しました。"
OBSWebsocket.ProfileChanged.Restarted="このプロファイルでWebSocketサーバの通信ポートが変更されました。サーバを再起動しました。"

18
data/locale/ko-KR.ini Normal file
View File

@ -0,0 +1,18 @@
OBSWebsocket.Settings.DialogTitle="웹소켓 서버 설정"
OBSWebsocket.Settings.ServerEnable="웹소켓 서버 활성화"
OBSWebsocket.Settings.ServerPort="서버 포트"
OBSWebsocket.Settings.AuthRequired="인증 활성화"
OBSWebsocket.Settings.Password="비밀번호"
OBSWebsocket.Settings.LockToIPv4="IPv4만 이용하여 서버를 연결"
OBSWebsocket.Settings.DebugEnable="디버그 로깅 활성화"
OBSWebsocket.Settings.AlertsEnable="시스템 트레이 알림 활성화"
OBSWebsocket.NotifyConnect.Title="새로운 웹소켓 연결"
OBSWebsocket.NotifyConnect.Message="클라이언트 %1 가 연결되었습니다"
OBSWebsocket.NotifyDisconnect.Title="웹소켓 클라이언트가 연결 해제되었습니다"
OBSWebsocket.NotifyDisconnect.Message="클라이언트 %1 가 연결이 해제되었습니다"
OBSWebsocket.Server.StartFailed.Title="웹소켓 서버 시작이 실패하였습니다"
OBSWebsocket.Server.StartFailed.Message="웹소켓 서버가 시작되지 못했습니다. \n 시스템 상의 다른 프로그램이 TCP 포트 %1을 사용 중인 것으로 보입니다. 다른 TCP 포트를 사용하거나, 해당 포트를 사용 중인 프로그램을 종료하고 다시 시도해주세요. \n 에러 메시지: %2"
OBSWebsocket.ProfileChanged.Started="프로파일 설정에 따라 웹소켓 서버가 활성화되었습니다. 서버가 시작되었습니다."
OBSWebsocket.ProfileChanged.Stopped="프로파일 설정에 따라 웹소켓 서버가 비활성화되었습니다. 서버가 중지되었습니다."
OBSWebsocket.ProfileChanged.Restarted="프로파일 설정에 따라 웹소켓 포트가 변경되었습니다. 서버가 재시작되었습니다."

18
data/locale/nl-NL.ini Normal file
View File

@ -0,0 +1,18 @@
OBSWebsocket.Settings.DialogTitle="WebSockets Server Instellingen"
OBSWebsocket.Settings.ServerEnable="WebSockets server inschakelen"
OBSWebsocket.Settings.ServerPort="Serverpoort"
OBSWebsocket.Settings.AuthRequired="Verificatie inschakelen"
OBSWebsocket.Settings.Password="Wachtwoord"
OBSWebsocket.Settings.LockToIPv4="Server vergrendelen om alleen IPv4 te gebruiken"
OBSWebsocket.Settings.DebugEnable="Activeer debug logs"
OBSWebsocket.Settings.AlertsEnable="Systemvak waarschuwingen inschakelen"
OBSWebsocket.NotifyConnect.Title="Nieuwe WebSocket verbinding"
OBSWebsocket.NotifyConnect.Message="Client %1 verbonden"
OBSWebsocket.NotifyDisconnect.Title="WebSocket client connectie verbroken"
OBSWebsocket.NotifyDisconnect.Message="Client %1 losgekoppeld"
OBSWebsocket.Server.StartFailed.Title="Fout in WebSocket server"
OBSWebsocket.Server.StartFailed.Message="De obs-websocket server kan niet worden gestart, misschien omdat: \n - TCP-poort %1 momenteel elders wordt gebruikt op dit systeem, eventueel door een andere toepassing. Probeer een andere TCP-poort in te stellen in de WebSocket Server-instellingen of stop elke toepassing die deze poort zou kunnen gebruiken.\n Een onbekende Netwerkfout op uw systeem. Probeer het opnieuw door de instellingen te wijzigen, OBS te herstarten of uw systeem te herstarten."
OBSWebsocket.ProfileChanged.Started="WebSockets server ingeschakeld in dit profiel. Server gestart."
OBSWebsocket.ProfileChanged.Stopped="WebSockets server uitgeschakeld in dit profiel. Server is gestopt."
OBSWebsocket.ProfileChanged.Restarted="WebSockets server poort is veranderd in dit profiel. Server is herstart."

15
data/locale/pl-PL.ini Normal file
View File

@ -0,0 +1,15 @@
OBSWebsocket.Settings.DialogTitle="Ustawienia serwera WebSockets"
OBSWebsocket.Settings.ServerEnable="Włącz serwer WebSockets"
OBSWebsocket.Settings.ServerPort="Port serwera"
OBSWebsocket.Settings.AuthRequired="Wymagaj uwierzytelniania"
OBSWebsocket.Settings.Password="Hasło"
OBSWebsocket.Settings.LockToIPv4="Zablokuj serwer tylko za pomocą IPv4"
OBSWebsocket.Settings.DebugEnable="Włącz rejestrowanie debugowania"
OBSWebsocket.Settings.AlertsEnable="Włącz powiadomienia w zasobniku systemowym"
OBSWebsocket.NotifyConnect.Title="Nowe połączenie WebSocket"
OBSWebsocket.NotifyConnect.Message="Klient %1 połączony"
OBSWebsocket.NotifyDisconnect.Title="Klient WebSocket odłączony"
OBSWebsocket.NotifyDisconnect.Message="Klient %1 rozłączony"
OBSWebsocket.Server.StartFailed.Title="Awaria serwera WebSockets"
OBSWebsocket.ProfileChanged.Started="Serwer WebSockets włączony w tym profilu. Serwer uruchomiony."

18
data/locale/pt-PT.ini Normal file
View File

@ -0,0 +1,18 @@
OBSWebsocket.Settings.DialogTitle="Configurações do servidor de WebSockets"
OBSWebsocket.Settings.ServerEnable="Habilitar servidor de WebSockets"
OBSWebsocket.Settings.ServerPort="Porta do Servidor"
OBSWebsocket.Settings.AuthRequired="Activar autenticação"
OBSWebsocket.Settings.Password="Palavra passe"
OBSWebsocket.Settings.LockToIPv4="Forçar apenas o uso de IPv4 (desabilitar IPv6)"
OBSWebsocket.Settings.DebugEnable="Habilitar registro de debug"
OBSWebsocket.Settings.AlertsEnable="Ativar Alertas da bandeja do sistema"
OBSWebsocket.NotifyConnect.Title="Nova conexão WebSocket"
OBSWebsocket.NotifyConnect.Message="Cliente %1 conectado"
OBSWebsocket.NotifyDisconnect.Title="WebSocket cliente desconectado"
OBSWebsocket.NotifyDisconnect.Message="Cliente %1 desconectado"
OBSWebsocket.Server.StartFailed.Title="Falha do servidor de WebSocket"
OBSWebsocket.Server.StartFailed.Message="O servidor de WebSockets falhou ao iniciar, possivelmente porque:\n - A porta TCP %1 pode já estar em uso em algum outro lugar neste sistema, possivelmente por outro aplicativo. Tente definir uma porta TCP diferente nas configurações do servidor de WebSockets, ou pare qualquer aplicativo que possa estar usando essa porta.\n - Mensagem de erro: %2"
OBSWebsocket.ProfileChanged.Started="Servidor de WebSockets habilitado nesse perfil. Servidor iniciado."
OBSWebsocket.ProfileChanged.Stopped="Servidor de WebSockets desabilitado nesse perfil. Servidor parado."
OBSWebsocket.ProfileChanged.Restarted="Porta do servidor de WebSockets foi alterada neste perfil. Servidor reiniciado."

18
data/locale/ru-RU.ini Normal file
View File

@ -0,0 +1,18 @@
OBSWebsocket.Settings.DialogTitle="Настройки сервера WebSockets"
OBSWebsocket.Settings.ServerEnable="Включить сервер WebSockets"
OBSWebsocket.Settings.ServerPort="Порт сервера"
OBSWebsocket.Settings.AuthRequired="Включить авторизацию"
OBSWebsocket.Settings.Password="Пароль"
OBSWebsocket.Settings.LockToIPv4="Блокировка сервера только с использованием IPv4"
OBSWebsocket.Settings.DebugEnable="Включить ведение журнала отладки"
OBSWebsocket.Settings.AlertsEnable="Включить оповещения в системном трее"
OBSWebsocket.NotifyConnect.Title="Новое соединение WebSocket"
OBSWebsocket.NotifyConnect.Message="Клиент %1 подключен"
OBSWebsocket.NotifyDisconnect.Title="Клиент WebSocket отключён"
OBSWebsocket.NotifyDisconnect.Message="Клиент %1 отключен"
OBSWebsocket.Server.StartFailed.Title="Сбой сервера WebSockets"
OBSWebsocket.Server.StartFailed.Message="Сервер WebSockets не запустился, возможно, потому, что:\n-TCP-порт %1 в настоящее время может использоваться в другом месте этой системы, возможно, другим приложением. Попробуйте установить другой TCP-порт в настройках сервера WebSocket или остановить любое приложение, которое может использовать этот порт.\n-сообщение об ошибке: %2"
OBSWebsocket.ProfileChanged.Started="Сервер WebSockets включен в этом профиле. Сервер запущен."
OBSWebsocket.ProfileChanged.Stopped="Сервер WebSockets отключен в этом профиле. Сервер остановлен."
OBSWebsocket.ProfileChanged.Restarted="Порт сервера WebSockets изменен в этом профиле. Сервер перезапущен."

16
data/locale/zh-CN.ini Normal file
View File

@ -0,0 +1,16 @@
OBSWebsocket.Settings.DialogTitle="WebSockets 服务器设置"
OBSWebsocket.Settings.ServerEnable="启用 WebSockets 服务器"
OBSWebsocket.Settings.ServerPort="服务器端口"
OBSWebsocket.Settings.AuthRequired="启用身份验证"
OBSWebsocket.Settings.Password="密码"
OBSWebsocket.Settings.DebugEnable="启用调试日志"
OBSWebsocket.Settings.AlertsEnable="启用系统托盘通知"
OBSWebsocket.NotifyConnect.Title="新 WebSocket 连接"
OBSWebsocket.NotifyConnect.Message="客户端 %1 已连接"
OBSWebsocket.NotifyDisconnect.Title="WebSocket 客户端已断开"
OBSWebsocket.NotifyDisconnect.Message="客户端 %1 已断开连接"
OBSWebsocket.Server.StartFailed.Title="WebSockets 服务器错误"
OBSWebsocket.ProfileChanged.Started="此配置文件中启用了 WebSockets 服务器。服务器已启动。"
OBSWebsocket.ProfileChanged.Stopped="此配置文件中禁用了 WebSockets 服务器。服务器已停止。"
OBSWebsocket.ProfileChanged.Restarted="此配置文件中的 WebSockets 服务器端口已更改。服务器已重新启动。"

9
data/locale/zh-TW.ini Normal file
View File

@ -0,0 +1,9 @@
OBSWebsocket.Settings.ServerPort="伺服器連接埠"
OBSWebsocket.Settings.DebugEnable="啟用除錯日誌"
OBSWebsocket.Settings.AlertsEnable="啟用系統列通知"
OBSWebsocket.NotifyConnect.Title="新的 WebSocket 連線"
OBSWebsocket.NotifyConnect.Message="客戶端 %1 已連線"
OBSWebsocket.NotifyDisconnect.Title="WebSocket 客戶端已離線"
OBSWebsocket.NotifyDisconnect.Message="客戶端 %1 已離線"
OBSWebsocket.Server.StartFailed.Title="WebSocket 伺服器錯誤"

1
deps/asio vendored Submodule

@ -0,0 +1 @@
Subproject commit b73dc1d2c0ecb9452a87c26544d7f71e24342df6

1
deps/websocketpp vendored Submodule

@ -0,0 +1 @@
Subproject commit c6d7e295bf5a0ab9b5f896720cc1a0e0fdc397a7

11
docs/.editorconfig Normal file
View File

@ -0,0 +1,11 @@
[*]
end_of_line = lf
charset = utf-8
indent_style = space
indent_size = 4
trim_trailing_whitespace = true
insert_final_newline = true
[*.md, *.mustache]
trim_trailing_whitespace = false
insert_final_newline = false

4
docs/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
node_modules
logs
*.log
npm-debug.log*

1
docs/.npmrc Normal file
View File

@ -0,0 +1 @@
package-lock=false

21
docs/README.md Normal file
View File

@ -0,0 +1,21 @@
## Installation
Install node and update npm if necessary.
```sh
cd obs-websocket/docs
npm install
```
## Build
```sh
# Just extract the comments.
npm run comments
# Just render the markdown.
npm run docs
# Do both comments and markdown.
npm run build
```

104
docs/comments.js Normal file
View File

@ -0,0 +1,104 @@
const fs = require('fs');
const path = require('path');
const glob = require('glob');
const parseComments = require('parse-comments');
const config = require('./config.json');
/**
* Read each file and call `parse-comments` on it.
*
* @param {String|Array} `files` List of file paths to read from.
* @return {Object|Array} Array of `parse-comments` objects.
*/
const parseFiles = files => {
let response = [];
files.forEach(file => {
const f = fs.readFileSync(file, 'utf8').toString();
response = response.concat(parseComments(f));
});
return response;
};
/**
* Filters/sorts the results from `parse-comments`.
* @param {Object|Array} `comments` Array of `parse-comments` objects.
* @return {Object} Filtered comments sorted by `@api` and `@category`.
*/
const processComments = comments => {
let sorted = {};
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);
if (validationFailures) {
errors.push(validationFailures);
}
// Store the object based on its api (ie. requests, events) and category (ie. general, scenes, etc).
comment.category = comment.category || 'miscellaneous';
// Remove some unnecessary properties to avoid result differences in travis.
comment.comment = undefined;
comment.context = undefined;
// Create an entry in sorted for the api/category if one does not exist.
sorted[comment.api] = sorted[comment.api] || {};
sorted[comment.api][comment.category] = sorted[comment.api][comment.category] || [];
// Store the comment in the appropriate api/category.
sorted[comment.api][comment.category].push(comment);
});
if (errors.length) {
throw JSON.stringify(errors, null, 2);
}
return sorted;
};
// Rudimentary validation of documentation content, returns an error object or undefined.
const validateComment = comment => {
let errors = [];
[].concat(comment.params).concat(comment.returns).filter(Boolean).forEach(param => {
if (typeof param.name !== 'string' || param.name === '') {
errors.push({
description: `Invalid param or return value name`,
param: param
});
}
if (typeof param.type !== 'string' || param.type === '') {
errors.push({
description: `Invalid param or return value type`,
param: param
});
}
});
if (errors.length) {
return {
errors: errors,
fullContext: Object.assign({}, comment)
};
}
};
const files = glob.sync(config.srcGlob);
const comments = processComments(parseFiles(files));
if (!fs.existsSync(config.outDirectory)){
fs.mkdirSync(config.outDirectory);
}
fs.writeFileSync(path.join(config.outDirectory, 'comments.json'), JSON.stringify(comments, null, 2));

5
docs/config.json Normal file
View File

@ -0,0 +1,5 @@
{
"srcGlob": "./../src/**/*.@(cpp|h)",
"srcTemplate": "./protocol.hbs",
"outDirectory": "./generated"
}

37
docs/docs.js Normal file
View File

@ -0,0 +1,37 @@
const fs = require('fs');
const path = require('path');
const toc = require('markdown-toc');
const handlebars = require('handlebars');
const config = require('./config.json');
const helpers = require('handlebars-helpers')({
handlebars: handlebars
});
// Allows pipe characters to be used within markdown tables.
handlebars.registerHelper('depipe', (text) => {
return typeof text === 'string' ? text.replace('|', '\\|') : text;
});
const insertHeader = (text) => {
return '<!-- This file was generated based on handlebars templates. Do not edit directly! -->\n\n' + text;
};
/**
* Writes `protocol.md` using `protocol.mustache`.
*
* @param {Object} `data` Data to assign to the mustache template.
*/
const generateProtocol = (templatePath, data) => {
const template = fs.readFileSync(templatePath).toString();
const generated = handlebars.compile(template)(data);
return insertHeader(toc.insert(generated));
};
if (!fs.existsSync(config.outDirectory)){
fs.mkdirSync(config.outDirectory);
}
const comments = fs.readFileSync(path.join(config.outDirectory, 'comments.json'), 'utf8');
const markdown = generateProtocol(config.srcTemplate, JSON.parse(comments));
fs.writeFileSync(path.join(config.outDirectory, 'protocol.md'), markdown);

11161
docs/generated/comments.json Normal file

File diff suppressed because it is too large Load Diff

4448
docs/generated/protocol.md Normal file

File diff suppressed because it is too large Load Diff

21
docs/package.json Normal file
View File

@ -0,0 +1,21 @@
{
"name": "obs-websocket-docs",
"version": "1.0.0",
"description": "",
"main": "docs.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"docs": "node ./docs.js",
"comments": "node ./comments.js",
"build": "npm run comments && npm run docs"
},
"author": "",
"license": "ISC",
"dependencies": {
"glob": "^7.1.2",
"handlebars": "^4.0.10",
"handlebars-helpers": "^0.9.6",
"markdown-toc": "^1.1.0",
"parse-comments": "^0.4.3"
}
}

View File

@ -0,0 +1,11 @@
# Events
Events are broadcast by the server to each connected client when a recognized action occurs within OBS.
An event message will contain at least the following base fields:
- `update-type` _String_: the type of event.
- `stream-timecode` _String (optional)_: time elapsed between now and stream start (only present if OBS Studio is streaming).
- `rec-timecode` _String (optional)_: time elapsed between now and recording start (only present if OBS Studio is recording).
Timecodes are sent using the format: `HH:MM:SS.mmm`
Additional fields may be present in the event message depending on the event type.

View File

@ -0,0 +1,38 @@
# obs-websocket 4.9.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. As of v5.0.0, backwards compatability with the protocol will not be kept.
# Authentication
**Starting with obs-websocket 4.9, authentication is enabled by default and users are encouraged to configure a password on first run.**
`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.
- A `salt`: applied to the password when generating the auth response.
To generate the answer to the auth challenge, follow this procedure:
- Concatenate the user declared password with the `salt` sent by the server (in this order: `password + server salt`).
- Generate a binary SHA256 hash of the result and encode the resulting SHA256 binary hash to base64, known as a `base64 secret`.
- Concatenate the base64 secret with the `challenge` sent by the server (in this order: `base64 secret + server challenge`).
- Generate a binary SHA256 hash of the result and encode it to base64.
- Voilà, this last base64 string is the `auth response`. You may now use it to authenticate to the server with the [`Authenticate`](#authenticate) request.
Pseudo Code Example:
```
password = "supersecretpassword"
challenge = "ztTBnnuqrqaKDzRM3xcVdbYm"
salt = "PZVbYpvAnZut2SS6JNJytDm9"
secret_string = password + salt
secret_hash = binary_sha256(secret_string)
secret = base64_encode(secret_hash)
auth_response_string = secret + challenge
auth_response_hash = binary_sha256(auth_response_string)
auth_response = base64_encode(auth_response_hash)
```
You can also refer to any of the client libraries listed on the [README](README.md) for examples of how to authenticate.

View File

@ -0,0 +1,11 @@
# Requests
Requests are sent by the client and require at least the following two fields:
- `request-type` _String_: String name of the request type.
- `message-id` _String_: Client defined identifier for the message, will be echoed in the response.
Once a request is sent, the server will return a JSON response with at least the following fields:
- `message-id` _String_: The client defined identifier specified in the request.
- `status` _String_: Response status, will be one of the following: `ok`, `error`
- `error` _String (Optional)_: An error message accompanying an `error` status.
Additional information may be required/returned depending on the request type. See below for more information.

View 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.

112
docs/protocol.hbs Normal file
View File

@ -0,0 +1,112 @@
{{#read "partials/introduction.md"}}{{/read}}
# Table of Contents
<!-- toc -->
{{#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}}
## {{capitalizeAll @key}}
{{#each this}}
### {{name}}
{{#if deprecated}}
- **⚠️ Deprecated. {{deprecated}} ⚠️**
{{/if}}
{{#eq since "unreleased"}}
- Unreleased
{{else}}
- Added in v{{since}}
{{/eq}}
{{{description}}}
**Response Items:**
{{#if returns.length}}
| Name | Type | Description |
| ---- | :---: | ------------|
{{#each returns}}
| `{{name}}` | _{{depipe type}}_ | {{{depipe description}}} |
{{/each}}
{{else}}
_No additional response items._
{{/if}}
---
{{/each}}
{{/each}}
{{#read "partials/requestsHeader.md"}}{{/read}}
{{#each requests}}
## {{capitalizeAll @key}}
{{#each this}}
### {{name}}
{{#if deprecated}}
- **⚠️ Deprecated. {{deprecated}} ⚠️**
{{/if}}
{{#eq since "unreleased"}}
- Unreleased
{{else}}
- Added in v{{since}}
{{/eq}}
{{{description}}}
**Request Fields:**
{{#if params.length}}
| Name | Type | Description |
| ---- | :---: | ------------|
{{#each params}}
| `{{name}}` | _{{depipe type}}_ | {{{depipe description}}} |
{{/each}}
{{else}}
_No specified parameters._
{{/if}}
**Response Items:**
{{#if returns.length}}
| Name | Type | Description |
| ---- | :---: | ------------|
{{#each returns}}
| `{{name}}` | _{{depipe type}}_ | {{{depipe description}}} |
{{/each}}
{{else}}
_No additional response items._
{{/if}}
---
{{/each}}
{{/each}}

107
external/FindLibObs.cmake vendored Normal file
View File

@ -0,0 +1,107 @@
# This module can be copied and used by external plugins for OBS
#
# Once done these will be defined:
#
# LIBOBS_FOUND
# LIBOBS_INCLUDE_DIRS
# LIBOBS_LIBRARIES
find_package(PkgConfig QUIET)
if (PKG_CONFIG_FOUND)
pkg_check_modules(_OBS QUIET obs libobs)
endif()
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(_lib_suffix 64)
else()
set(_lib_suffix 32)
endif()
if(DEFINED CMAKE_BUILD_TYPE)
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
set(_build_type_base "debug")
else()
set(_build_type_base "release")
endif()
endif()
find_path(LIBOBS_INCLUDE_DIR
NAMES obs.h
HINTS
ENV obsPath${_lib_suffix}
ENV obsPath
${obsPath}
PATHS
/usr/include /usr/local/include /opt/local/include /sw/include
PATH_SUFFIXES
libobs
)
function(find_obs_lib base_name repo_build_path lib_name)
string(TOUPPER "${base_name}" base_name_u)
if(DEFINED _build_type_base)
set(_build_type_${repo_build_path} "${_build_type_base}/${repo_build_path}")
set(_build_type_${repo_build_path}${_lib_suffix} "${_build_type_base}${_lib_suffix}/${repo_build_path}")
endif()
find_library(${base_name_u}_LIB
NAMES ${_${base_name_u}_LIBRARIES} ${lib_name} lib${lib_name}
HINTS
ENV obsPath${_lib_suffix}
ENV obsPath
${obsPath}
${_${base_name_u}_LIBRARY_DIRS}
PATHS
/usr/lib /usr/local/lib /opt/local/lib /sw/lib
PATH_SUFFIXES
lib${_lib_suffix} lib
libs${_lib_suffix} libs
bin${_lib_suffix} bin
../lib${_lib_suffix} ../lib
../libs${_lib_suffix} ../libs
../bin${_lib_suffix} ../bin
# base repo non-msvc-specific search paths
${_build_type_${repo_build_path}}
${_build_type_${repo_build_path}${_lib_suffix}}
build/${repo_build_path}
build${_lib_suffix}/${repo_build_path}
# base repo msvc-specific search paths on windows
build${_lib_suffix}/${repo_build_path}/Debug
build${_lib_suffix}/${repo_build_path}/RelWithDebInfo
build/${repo_build_path}/Debug
build/${repo_build_path}/RelWithDebInfo
)
endfunction()
find_obs_lib(LIBOBS libobs obs)
if(MSVC)
find_obs_lib(W32_PTHREADS deps/w32-pthreads w32-pthreads)
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Libobs DEFAULT_MSG LIBOBS_LIB LIBOBS_INCLUDE_DIR)
mark_as_advanced(LIBOBS_INCLUDE_DIR LIBOBS_LIB)
if(LIBOBS_FOUND)
if(MSVC)
if (NOT DEFINED W32_PTHREADS_LIB)
message(FATAL_ERROR "Could not find the w32-pthreads library" )
endif()
set(W32_PTHREADS_INCLUDE_DIR ${LIBOBS_INCLUDE_DIR}/../deps/w32-pthreads)
endif()
set(LIBOBS_INCLUDE_DIRS ${LIBOBS_INCLUDE_DIR} ${W32_PTHREADS_INCLUDE_DIR})
set(LIBOBS_LIBRARIES ${LIBOBS_LIB} ${W32_PTHREADS_LIB})
include(${LIBOBS_INCLUDE_DIR}/../cmake/external/ObsPluginHelpers.cmake)
# allows external plugins to easily use/share common dependencies that are often included with libobs (such as FFmpeg)
if(NOT DEFINED INCLUDED_LIBOBS_CMAKE_MODULES)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${LIBOBS_INCLUDE_DIR}/../cmake/Modules/")
set(INCLUDED_LIBOBS_CMAKE_MODULES true)
endif()
else()
message(FATAL_ERROR "Could not find the libobs library" )
endif()

69
installer/installer.iss Normal file
View File

@ -0,0 +1,69 @@
; Script generated by the Inno Setup Script Wizard.
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
#define MyAppName "obs-websocket"
#define MyAppVersion "4.9.0"
#define MyAppPublisher "Stephane Lepin"
#define MyAppURL "http://github.com/Palakis/obs-websocket"
[Setup]
; NOTE: The value of AppId uniquely identifies this application.
; Do not use the same AppId value in installers for other applications.
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
AppId={{117EE44F-48E1-49E5-A381-CC8D9195CF35}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
;AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={code:GetDirName}
DefaultGroupName={#MyAppName}
OutputBaseFilename=obs-websocket-Windows-Installer
Compression=lzma
SolidCompression=yes
DirExistsWarning=no
[Languages]
Name: "english"; MessagesFile: "compiler:Default.isl"
[Files]
Source: "..\release\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "..\LICENSE"; Flags: dontcopy
; NOTE: Don't use "Flags: ignoreversion" on any shared system files
[Icons]
Name: "{group}\{cm:ProgramOnTheWeb,{#MyAppName}}"; Filename: "{#MyAppURL}"
Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "{uninstallexe}"
[Code]
procedure InitializeWizard();
var
GPLText: AnsiString;
Page: TOutputMsgMemoWizardPage;
begin
ExtractTemporaryFile('LICENSE');
LoadStringFromFile(ExpandConstant('{tmp}\LICENSE'), GPLText);
Page := CreateOutputMsgMemoPage(wpWelcome,
'License Information', 'Please review the license terms before installing obs-websocket',
'Press Page Down to see the rest of the agreement. Once you are aware of your rights, click Next to continue.',
String(GPLText)
);
end;
// credit where it's due :
// following function come from https://github.com/Xaymar/obs-studio_amf-encoder-plugin/blob/master/%23Resources/Installer.in.iss#L45
function GetDirName(Value: string): string;
var
InstallPath: string;
begin
// initialize default path, which will be returned when the following registry
// key queries fail due to missing keys or for some different reason
Result := '{pf}\obs-studio';
// query the first registry value; if this succeeds, return the obtained value
if RegQueryStringValue(HKLM32, 'SOFTWARE\OBS Studio', '', InstallPath) then
Result := InstallPath
end;

View File

@ -0,0 +1,39 @@
#include "settings-dialog.h"
#include <obs-frontend-api.h>
#include <obs-module.h>
#include <QtWidgets/QMessageBox>
#include "../obs-websocket.h"
#define CHANGE_ME "changeme"
SettingsDialog::SettingsDialog(QWidget* parent) :
QDialog(parent, Qt::Dialog),
ui(new Ui::SettingsDialog)
{
ui->setupUi(this);
connect(ui->buttonBox, &QDialogButtonBox::accepted,
this, &SettingsDialog::FormAccepted);
}
void SettingsDialog::showEvent(QShowEvent* event) {
;
}
void SettingsDialog::ToggleShowHide() {
if (!isVisible())
setVisible(true);
else
setVisible(false);
}
void SettingsDialog::FormAccepted() {
;
}
SettingsDialog::~SettingsDialog() {
delete ui;
}

View File

@ -0,0 +1,40 @@
/*
obs-websocket
Copyright (C) 2016-2019 Stéphane Lepin <stephane.lepin@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program. If not, see <https://www.gnu.org/licenses/>
*/
#pragma once
#include <QtWidgets/QDialog>
#include "ui_settings-dialog.h"
class SettingsDialog : public QDialog
{
Q_OBJECT
public:
explicit SettingsDialog(QWidget* parent = 0);
~SettingsDialog();
void showEvent(QShowEvent* event);
void ToggleShowHide();
private Q_SLOTS:
void FormAccepted();
private:
Ui::SettingsDialog* ui;
};

View File

@ -0,0 +1,158 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SettingsDialog</class>
<widget class="QDialog" name="SettingsDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>407</width>
<height>216</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>OBSWebsocket.Settings.DialogTitle</string>
</property>
<property name="sizeGripEnabled">
<bool>false</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="sizeConstraint">
<enum>QLayout::SetDefaultConstraint</enum>
</property>
<item>
<layout class="QFormLayout" name="formLayout">
<item row="3" column="1">
<widget class="QCheckBox" name="authRequired">
<property name="text">
<string>OBSWebsocket.Settings.AuthRequired</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="lbl_password">
<property name="text">
<string>OBSWebsocket.Settings.Password</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLineEdit" name="password">
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="serverEnabled">
<property name="text">
<string>OBSWebsocket.Settings.ServerEnable</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="lbl_serverPort">
<property name="text">
<string>OBSWebsocket.Settings.ServerPort</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QSpinBox" name="serverPort">
<property name="minimum">
<number>1024</number>
</property>
<property name="maximum">
<number>65535</number>
</property>
<property name="value">
<number>4444</number>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QCheckBox" name="alertsEnabled">
<property name="text">
<string>OBSWebsocket.Settings.AlertsEnable</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QCheckBox" name="debugEnabled">
<property name="text">
<string>OBSWebsocket.Settings.DebugEnable</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QCheckBox" name="lockToIPv4">
<property name="text">
<string>OBSWebsocket.Settings.LockToIPv4</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>SettingsDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>294</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>314</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>SettingsDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>300</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>314</y>
</hint>
</hints>
</connection>
</connections>
</ui>

57
src/obs-websocket.cpp Normal file
View File

@ -0,0 +1,57 @@
#include <obs-module.h>
#include <obs-frontend-api.h>
#include <obs-data.h>
#include <QtCore/QTimer>
#include <QtWidgets/QAction>
#include <QtWidgets/QMainWindow>
#include "obs-websocket.h"
#include "forms/settings-dialog.h"
void ___source_dummy_addref(obs_source_t*) {}
void ___sceneitem_dummy_addref(obs_sceneitem_t*) {}
void ___data_dummy_addref(obs_data_t*) {}
void ___data_array_dummy_addref(obs_data_array_t*) {}
void ___output_dummy_addref(obs_output_t*) {}
void ___data_item_dummy_addref(obs_data_item_t*) {}
void ___data_item_release(obs_data_item_t* dataItem) {
obs_data_item_release(&dataItem);
}
OBS_DECLARE_MODULE()
OBS_MODULE_USE_DEFAULT_LOCALE("obs-websocket", "en-US")
SettingsDialog* settingsDialog = nullptr;
bool obs_module_load(void) {
blog(LOG_INFO, "you can haz websockets (version %s)", OBS_WEBSOCKET_VERSION);
blog(LOG_INFO, "qt version (compile-time): %s ; qt version (run-time): %s",
QT_VERSION_STR, qVersion());
// UI setup
obs_frontend_push_ui_translation(obs_module_get_string);
QMainWindow* mainWindow = (QMainWindow*)obs_frontend_get_main_window();
settingsDialog = new SettingsDialog(mainWindow);
obs_frontend_pop_ui_translation();
const char* menuActionText =
obs_module_text("OBSWebsocket.Settings.DialogTitle");
QAction* menuAction =
(QAction*)obs_frontend_add_tools_menu_qaction(menuActionText);
QObject::connect(menuAction, &QAction::triggered, [] {
// The settings dialog belongs to the main window. Should be ok
// to pass the pointer to this QAction belonging to the main window
settingsDialog->ToggleShowHide();
});
// Loading finished
blog(LOG_INFO, "module loaded!");
return true;
}
void obs_module_unload() {
blog(LOG_INFO, "goodbye!");
}

30
src/obs-websocket.h Normal file
View File

@ -0,0 +1,30 @@
#pragma once
#include <obs.hpp>
#include <memory>
void ___source_dummy_addref(obs_source_t*);
void ___sceneitem_dummy_addref(obs_sceneitem_t*);
void ___data_dummy_addref(obs_data_t*);
void ___data_array_dummy_addref(obs_data_array_t*);
void ___output_dummy_addref(obs_output_t*);
using OBSSourceAutoRelease =
OBSRef<obs_source_t*, ___source_dummy_addref, obs_source_release>;
using OBSSceneItemAutoRelease =
OBSRef<obs_sceneitem_t*, ___sceneitem_dummy_addref, obs_sceneitem_release>;
using OBSDataAutoRelease =
OBSRef<obs_data_t*, ___data_dummy_addref, obs_data_release>;
using OBSDataArrayAutoRelease =
OBSRef<obs_data_array_t*, ___data_array_dummy_addref, obs_data_array_release>;
using OBSOutputAutoRelease =
OBSRef<obs_output_t*, ___output_dummy_addref, obs_output_release>;
void ___data_item_dummy_addref(obs_data_item_t*);
void ___data_item_release(obs_data_item_t*);
using OBSDataItemAutoRelease =
OBSRef<obs_data_item_t*, ___data_item_dummy_addref, ___data_item_release>;
#define OBS_WEBSOCKET_VERSION "5.0.0"
#define blog(level, msg, ...) blog(level, "[obs-websocket] " msg, ##__VA_ARGS__)

14
src/rpc/RpcEvent.cpp Normal file
View File

@ -0,0 +1,14 @@
#include "RpcEvent.h"
RpcEvent::RpcEvent (
const QString& updateType,
obs_data_t* additionalFields
) :
_updateType(updateType),
_additionalFields(nullptr)
{
if (additionalFields) {
_additionalFields = obs_data_create();
obs_data_apply(_additionalFields, additionalFields);
}
}

28
src/rpc/RpcEvent.h Normal file
View File

@ -0,0 +1,28 @@
#pragma once
#include <obs-data.h>
#include <QtCore/QString>
#include "../obs-websocket.h"
class RpcEvent {
public:
explicit RpcEvent (
const QString& updateType,
obs_data_t* additionalFields = nullptr
);
const QString& updateType() const
{
return _updateType;
}
const OBSData additionalFields() const
{
return OBSData(_additionalFields);
}
private:
QString _updateType;
OBSDataAutoRelease _additionalFields;
};

123
src/rpc/RpcRequest.h Normal file
View File

@ -0,0 +1,123 @@
#pragma once
#include <obs-data.h>
#include <QtCore/QString>
#include "../obs-websocket.h"
namespace RequestStatus {
typedef uint16_t ResponseCode;
static ResponseCode const Unknown = 0;
static ResponseCode const Success = 100;
// The request is denied because the client is not authenticated
static ResponseCode const AuthenticationMissing = 200;
// Connection has already been authenticated (for modules utilizing a request to provide authentication)
static ResponseCode const AlreadyAuthenticated = 201;
// Authentication request was denied (for modules utilizing a request to provide authentication)
static ResponseCode const AuthenticationDenied = 202;
// The request type is invalid (does not exist)
static ResponseCode const InvalidRequestType = 203;
// Generic error code (comment is expected to be provided)
static ResponseCode const GenericError = 204;
// A required request parameter is missing
static ResponseCode const MissingRequestParameter = 300;
// Generic invalid request parameter message
static ResponseCode const InvalidRequestParameter = 400;
// A request parameter has the wrong data type
static ResponseCode const InvalidRequestParameterDataType = 401;
// A request parameter (float or int) is out of valid range
static ResponseCode const RequestParameterOutOfRange = 402;
// A request parameter (string or array) is empty and cannot be
static ResponseCode const RequestParameterEmpty = 403;
// An output is running and cannot be in order to perform the request (generic)
static ResponseCode const OutputRunning = 500;
// An output is not running and should be
static ResponseCode const OutputNotRunning = 501;
// Stream is running and cannot be
static ResponseCode const StreamRunning = 502;
// Stream is not running and should be
static ResponseCode const StreamNotRunning = 503;
// Record is running and cannot be
static ResponseCode const RecordRunning = 504;
// Record is not running and should be
static ResponseCode const RecordNotRunning = 505;
// Record is paused and cannot be
static ResponseCode const RecordPaused = 506;
// Replay buffer is running and cannot be
static ResponseCode const ReplayBufferRunning = 507;
// Replay buffer is not running and should be
static ResponseCode const ReplayBufferNotRunning = 508;
// Replay buffer is disabled and cannot be
static ResponseCode const ReplayBufferDisabled = 509;
// Studio mode is active and cannot be
static ResponseCode const StudioModeActive = 510;
// Studio mode is not active and should be
static ResponseCode const StudioModeNotActive = 511;
// The specified source was of the invalid type (Eg. input instead of scene)
static ResponseCode const InvalidSourceType = 600;
// The specified source was not found (generic for input, filter, transition, scene)
static ResponseCode const SourceNotFound = 601;
// The specified source already exists. Applicable to inputs, filters, transitions, scenes
static ResponseCode const SourceAlreadyExists = 602;
// The specified input was not found
static ResponseCode const InputNotFound = 603;
// The specified input had the wrong kind
static ResponseCode const InvalidInputKind = 604;
// The specified filter was not found
static ResponseCode const FilterNotFound = 605;
// The specified transition was not found
static ResponseCode const TransitionNotFound = 606;
// The specified transition does not support setting its position (transition is of fixed type)
static ResponseCode const TransitionDurationFixed = 607;
// The specified scene was not found
static ResponseCode const SceneNotFound = 608;
// The specified scene item was not found
static ResponseCode const SceneItemNotFound = 609;
// The specified scene collection was not found
static ResponseCode const SceneCollectionNotFound = 610;
// The specified profile was not found
static ResponseCode const ProfileNotFound = 611;
// The specified output was not found
static ResponseCode const OutputNotFound = 612;
// The specified encoder was not found
static ResponseCode const EncoderNotFound = 613;
// The specified service was not found
static ResponseCode const ServiceNotFound = 614;
// Processing the request failed unexpectedly
static ResponseCode const RequestProcessingFailed = 700;
// Starting the Output failed
static ResponseCode const OutputStartFailed = 701;
// Duplicating the scene item failed
static ResponseCode const SceneItemDuplicationFailed = 702;
// Rendering the screenshot failed
static ResponseCode const ScreenshotRenderFailed = 703;
// Encoding the screenshot failed
static ResponseCode const ScreenshotEncodeFailed = 704;
// Saving the screenshot failed
static ResponseCode const ScreenshotSaveFailed = 705;
};
class RpcRequest;
class RpcResponse {
public:
;
private:
;
};
class RpcRequest {
public:
;
private:
;
};

View File

@ -0,0 +1 @@
#include "RpcRequest.h"

View File

@ -0,0 +1 @@
#include "RpcRequest.h"