Docs: Initial generation of docs from code comments (#106)

This commit is contained in:
Brendan Hagan 2017-08-13 11:41:42 -04:00 committed by Stéphane L
parent 1eccf4c899
commit a263d8a364
22 changed files with 6189 additions and 1070 deletions

View File

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 54 KiB

View File

Before

Width:  |  Height:  |  Size: 7.8 KiB

After

Width:  |  Height:  |  Size: 7.8 KiB

2
.gitignore vendored
View File

@ -5,3 +5,5 @@
/build64/
/release/
/installer/Output/
.vscode

View File

@ -1,7 +1,4 @@
language: cpp
branches:
except:
- gh-pages
env:
global:
@ -10,8 +7,15 @@ env:
# AWS key secret
- secure: bGwljoP3E1OVBXLXox0O6p8kwQXLcNQ8YDKVa4H8u9Y+Ic7uqE4iV3rYS3ynNWSBMVRWY3ZbyClnhrCNwRhBAlcd8qWSJdpjVzs6HdQyzhuKa1P3V4FJPb7upGP/5R/DECGwex8Mun9dmXpYDak75LxfKIJUidPis5VDCYqul7k/xVVCou6Ctjpj7vQhWXDj2G/py+mdB8DERhymnQCtyK1Ziu8c4QlFKByZmnD72GFm/h3JPI1Pq1V2mz3x6x6GaYjb9Rdbd0UNwqjGQX4q2M/c3GEJa6B2JBCoTncawNZBNnPUF9qtv+zh0TNaNHMRWX13AJ/qYB+nVDub0C9b/6Mc48mt0Tv4ze15MproVrylZdV6qHYEG8yGPBqpTVbRP6gv6Y2TXIHWoTzqA+F/Gv2IDChyHXsld/MQQS2MSo5iaYktIrZKtX8Z0qAmTzPwIVBromaSI3vrE7UH0fRSQ6fAM8+Tn+MRthOBdqu23kS1dnG+X2CPbUhBfsJp0OSwVQD5jQtA51/sREVeGFiJvzQIkvwQDjb5MYilsRnwmoBXemkLmqaviXVY4rz1o5AIvz2pgZS2YggK1xHZCuI5tSjcNEkb77VwZTfsqrdDo9EJh6VgfdnGlHQhR2/A5hUJ4ANpJ/LgZlgfVp71Xg2GWQW6M4Znc5uj6A6xLBkO6FA=
cache:
directories:
- node_modules
matrix:
include:
- os: linux
script: "./CI/generate-docs.sh"
- os: linux
dist: trusty
sudo: required
@ -30,7 +34,8 @@ matrix:
osx_image: xcode8.3
before_install: "./CI/install-dependencies-osx.sh"
script: "./CI/build-osx.sh"
after_success: "./CI/package-osx.sh"
after_success:
- ./CI/package-osx.sh
deploy:
- provider: s3
@ -43,7 +48,9 @@ deploy:
acl: public_read
on:
repo: Palakis/obs-websocket
condition: "$TRAVIS_OS_NAME = linux"
condition:
- "$TRAVIS_OS_NAME = linux"
- "-d /home/travis/package"
all_branches: true
- provider: s3
region: eu-central-1

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

@ -0,0 +1,32 @@
#!/bin/bash
echo "-- Generating documentation."
echo "-- Node version: $(node -v)"
echo "-- NPM version: $(npm -v)"
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
if [ "$TRAVIS_PULL_REQUEST" != "false" -o "$TRAVIS_BRANCH" != "master" ]; then
echo "-- Skipping documentation deployment because this is either a pull request or a non-master branch."
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 "Travis CI"
git config user.email "$COMMIT_AUTHOR_EMAIL"
git add ./generated
git pull
git commit -m "docs(travis): Update protocol.md - $(git rev-parse --short HEAD) [skip ci]"
git push -q $GITHUB_REPO HEAD:$TRAVIS_BRANCH

File diff suppressed because it is too large Load Diff

View File

@ -21,7 +21,7 @@ It is **highly recommended** to protect obs-websocket with a password against un
### 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](PROTOCOL.md).
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
@ -39,7 +39,7 @@ See the [build instructions](BUILDING.md).
## Special thanks
In order of appearance:
- [Brendan H.](https://github.com/haganbmj) : Code contributions and better English in the Protocol specification
- [Brendan H.](https://github.com/haganbmj) : Code contributions and gooder English in the Protocol specification
- [Mikhail Swift](https://github.com/mikhailswift) : Code contributions
- [Tobias Frahmer](https://github.com/Frahmer) : German translation
- [Genture](https://github.com/Genteure) : Simplified Chinese and Traditional Chinese translations
@ -61,10 +61,10 @@ They have contributed financially to the project and made possible the addition
[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](doc/supportclass_logo_blacktext.png)](http://supportclass.net)
[![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](doc/mediaunit_logo_black.png)](http://www.mediaunit.no/)
[![MediaUnit](.github/images/mediaunit_logo_black.png)](http://www.mediaunit.no/)

View File

@ -1,21 +1,21 @@
/*
obs-websocket
Copyright (C) 2016-2017 Stéphane Lepin <stephane.lepin@gmail.com>
Copyright (C) 2017 Brendan Hagan <https://github.com/haganbmj>
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/>
*/
/**
* obs-websocket
* Copyright (C) 2016-2017 Stéphane Lepin <stephane.lepin@gmail.com>
* Copyright (C) 2017 Brendan Hagan <https://github.com/haganbmj>
*
* 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/>
*/
#include <util/platform.h>
@ -259,6 +259,16 @@ const char* WSEvents::GetRecordingTimecode() {
return ns_to_timestamp(GetRecordingTime());
}
/**
* Indicates a scene change.
*
* @return {String} `scene-name` The new scene.
* @return {Array} `sources` List of sources in the new scene.
*
* @api events
* @name OnSceneChange
* @category scenes
*/
void WSEvents::OnSceneChange() {
obs_data_t* data = obs_data_create();
@ -283,10 +293,25 @@ void WSEvents::OnSceneChange() {
}
}
/**
* The scene list has been modified.
* Scenes have been added, removed, or renamed.
*
* @api events
* @name ScenesChanged
* @category scenes
*/
void WSEvents::OnSceneListChange() {
broadcastUpdate("ScenesChanged");
}
/**
* Triggered when switching to another scene collection or when renaming the current scene collection.
*
* @api events
* @name SceneCollectionChanged
* @category scenes
*/
void WSEvents::OnSceneCollectionChange() {
broadcastUpdate("SceneCollectionChanged");
@ -300,10 +325,26 @@ void WSEvents::OnSceneCollectionChange() {
OnSceneChange();
}
/**
* Triggered when a scene collection is created, added, renamed, or removed.
*
* @api events
* @name SceneCollectionListChanged
* @category scenes
*/
void WSEvents::OnSceneCollectionListChange() {
broadcastUpdate("SceneCollectionListChanged");
}
/**
* The active transition has been changed.
*
* @return {String} `transition-name` The name of the new active transition.
*
* @api events
* @name SwitchTransition
* @category transitions
*/
void WSEvents::OnTransitionChange() {
obs_source_t* current_transition = obs_frontend_get_current_transition();
connectTransitionSignals(current_transition);
@ -318,18 +359,49 @@ void WSEvents::OnTransitionChange() {
obs_source_release(current_transition);
}
/**
* The list of available transitions has been modified.
* Transitions have been added, removed, or renamed.
*
* @api events
* @name TransitionListChanged
* @category transitions
*/
void WSEvents::OnTransitionListChange() {
broadcastUpdate("TransitionListChanged");
}
/**
* Triggered when switching to another profile or when renaming the current profile.
*
* @api events
* @name ProfileChanged
* @category profiles
*/
void WSEvents::OnProfileChange() {
broadcastUpdate("ProfileChanged");
}
/**
* Triggered when a profile is created, added, renamed, or removed.
*
* @api events
* @name ProfileListChanged
* @category profiles
*/
void WSEvents::OnProfileListChange() {
broadcastUpdate("ProfileListChanged");
}
/**
* A request to start streaming has been issued.
*
* @return {boolean} `preview-only` Always false (retrocompatibility).
*
* @api events
* @name StreamStarting
* @category streaming
*/
void WSEvents::OnStreamStarting() {
obs_data_t* data = obs_data_create();
obs_data_set_bool(data, "preview-only", false);
@ -339,12 +411,28 @@ void WSEvents::OnStreamStarting() {
obs_data_release(data);
}
/**
* Streaming started successfully.
*
* @api events
* @name StreamStarted
* @category streaming
*/
void WSEvents::OnStreamStarted() {
_stream_starttime = os_gettime_ns();
_lastBytesSent = 0;
broadcastUpdate("StreamStarted");
}
/**
* A request to stop streaming has been issued.
*
* @return {boolean} `preview-only` Always false (retrocompatibility).
*
* @api events
* @name StreamStopping
* @category streaming
*/
void WSEvents::OnStreamStopping() {
obs_data_t* data = obs_data_create();
obs_data_set_bool(data, "preview-only", false);
@ -354,33 +442,93 @@ void WSEvents::OnStreamStopping() {
obs_data_release(data);
}
/**
* Streaming stopped successfully.
*
* @api events
* @name StreamStopped
* @category streaming
*/
void WSEvents::OnStreamStopped() {
_stream_starttime = 0;
broadcastUpdate("StreamStopped");
}
/**
* A request to start recording has been issued.
*
* @api events
* @name RecordingStarting
* @category recording
*/
void WSEvents::OnRecordingStarting() {
broadcastUpdate("RecordingStarting");
}
/**
* Recording started successfully.
*
* @api events
* @name RecordingStarted
* @category recording
*/
void WSEvents::OnRecordingStarted() {
_rec_starttime = os_gettime_ns();
broadcastUpdate("RecordingStarted");
}
/**
* A request to stop recording has been issued.
*
* @api events
* @name RecordingStopping
* @category recording
*/
void WSEvents::OnRecordingStopping() {
broadcastUpdate("RecordingStopping");
}
/**
* Recording stopped successfully.
*
* @api events
* @name RecordingStopped
* @category recording
*/
void WSEvents::OnRecordingStopped() {
_rec_starttime = 0;
broadcastUpdate("RecordingStopped");
}
/**
* OBS is exiting.
*
* @api events
* @name Exiting
* @category other
*/
void WSEvents::OnExit() {
broadcastUpdate("Exiting");
}
/**
* Emit every 2 seconds.
*
* @return {boolean} `streaming` Current streaming state.
* @return {boolean} `recording` Current recording state.
* @return {boolean} `preview-only` Always false (retrocompatibility).
* @return {int} `bytes-per-sec` Amount of data per second (in bytes) transmitted by the stream encoder.
* @return {int} `kbits-per-sec` Amount of data per second (in kilobits) transmitted by the stream encoder.
* @return {double} `strain` Percentage of dropped frames.
* @return {int} `total-stream-time` Total time (in seconds) since the stream started.
* @return {int} `num-total-frames` Total number of frames transmitted since the stream started.
* @return {int} `num-dropped-frames` Number of frames dropped by the encoder since the stream started.
* @return {double} `fps` Current framerate.
*
* @api events
* @name StreamStatus
* @category streaming
*/
void WSEvents::StreamStatus() {
bool streaming_active = obs_frontend_streaming_active();
bool recording_active = obs_frontend_recording_active();
@ -438,6 +586,15 @@ void WSEvents::StreamStatus() {
obs_output_release(stream_output);
}
/**
* The active transition duration has been changed.
*
* @return {int} `new-duration` New transition duration.
*
* @api events
* @name TransitionDurationChanged
* @category transitions
*/
void WSEvents::TransitionDurationChanged(int ms) {
obs_data_t* fields = obs_data_create();
obs_data_set_int(fields, "new-duration", ms);
@ -446,6 +603,16 @@ void WSEvents::TransitionDurationChanged(int ms) {
obs_data_release(fields);
}
/**
* A transition (other than "cut") has begun.
*
* @return {String} `name` Transition name.
* @return {int} `duration` Transition duration (in milliseconds).
*
* @api events
* @name TransitionBegin
* @category transitions
*/
void WSEvents::OnTransitionBegin(void* param, calldata_t* data) {
UNUSED_PARAMETER(data);
WSEvents* instance = static_cast<WSEvents*>(param);
@ -463,6 +630,15 @@ void WSEvents::OnTransitionBegin(void* param, calldata_t* data) {
obs_source_release(current_transition);
}
/**
* Scene items have been reordered.
*
* @return {String} `scene-name` Name of the scene where items have been reordered.
*
* @api events
* @name SourceOrderChanged
* @category sources
*/
void WSEvents::OnSceneReordered(void* param, calldata_t* data) {
WSEvents* instance = static_cast<WSEvents*>(param);
@ -477,6 +653,16 @@ void WSEvents::OnSceneReordered(void* param, calldata_t* data) {
obs_data_release(fields);
}
/**
* An item has been added to the current scene.
*
* @return {String} `scene-name` Name of the scene.
* @return {String} `item-name` Name of the item added to the scene.
*
* @api events
* @name SceneItemAdded
* @category sources
*/
void WSEvents::OnSceneItemAdd(void* param, calldata_t* data) {
WSEvents* instance = static_cast<WSEvents*>(param);
@ -499,6 +685,16 @@ void WSEvents::OnSceneItemAdd(void* param, calldata_t* data) {
obs_data_release(fields);
}
/**
* An item has been removed from the current scene.
*
* @return {String} `scene-name` Name of the scene.
* @return {String} `item-name` Name of the item removed from the scene.
*
* @api events
* @name SceneItemRemoved
* @category sources
*/
void WSEvents::OnSceneItemDelete(void* param, calldata_t* data) {
WSEvents* instance = static_cast<WSEvents*>(param);
@ -521,6 +717,17 @@ void WSEvents::OnSceneItemDelete(void* param, calldata_t* data) {
obs_data_release(fields);
}
/**
* An item's visibility has been toggled.
*
* @return {String} `scene-name` Name of the scene.
* @return {String} `item-name` Name of the item in the scene.
* @return {boolean} `item-visible` New visibility state of the item.
*
* @api events
* @name SceneItemVisibilityChanged
* @category sources
*/
void WSEvents::OnSceneItemVisibilityChanged(void* param, calldata_t* data) {
WSEvents* instance = static_cast<WSEvents*>(param);
@ -547,6 +754,16 @@ void WSEvents::OnSceneItemVisibilityChanged(void* param, calldata_t* data) {
obs_data_release(fields);
}
/**
* The selected preview scene has changed (only available in Studio Mode).
*
* @return {String} `scene-name` Name of the scene being previewed.
* @return {Source|Array} `sources` List of sources composing the scene. Same specification as [`GetCurrentScene`](#getcurrentscene).
*
* @api events
* @name PreviewSceneChanged
* @category studio mode
*/
void WSEvents::SelectedSceneChanged(QListWidgetItem* current, QListWidgetItem* prev) {
if (Utils::IsPreviewModeActive()) {
obs_scene_t* scene = Utils::SceneListItemToScene(current);
@ -566,6 +783,15 @@ void WSEvents::SelectedSceneChanged(QListWidgetItem* current, QListWidgetItem* p
}
}
/**
* Studio Mode has been enabled or disabled.
*
* @return {boolean} `new-state` The new enabled state of Studio Mode.
*
* @api events
* @name StudioModeSwitched
* @category studio mode
*/
void WSEvents::ModeSwitchClicked(bool checked) {
obs_data_t* data = obs_data_create();
obs_data_set_bool(data, "new-state", checked);

View File

@ -1,21 +1,21 @@
/*
obs-websocket
Copyright (C) 2016-2017 Stéphane Lepin <stephane.lepin@gmail.com>
Copyright (C) 2017 Mikhail Swift <https://github.com/mikhailswift>
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/>
*/
/**
* obs-websocket
* Copyright (C) 2016-2017 Stéphane Lepin <stephane.lepin@gmail.com>
* Copyright (C) 2017 Mikhail Swift <https://github.com/mikhailswift>
*
* 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/>
*/
#include <obs-data.h>
@ -195,6 +195,18 @@ bool WSRequestHandler::hasField(const char* name) {
return obs_data_has_user_value(data, name);
}
/**
* Returns the latest version of the plugin and the API.
*
* @return {double} `version` OBSRemote compatible API version. Fixed to 1.1 for retrocompatibility.
* @return {String} `obs-websocket-version` obs-websocket plugin version.
* @return {String} `obs-studio-version` OBS Studio program version.
* @return {String|Array} `available-requests` List of available request types.
*
* @api requests
* @name GetVersion
* @category general
*/
void WSRequestHandler::HandleGetVersion(WSRequestHandler* req) {
const char* obs_version = Utils::OBSVersionString();
@ -217,6 +229,18 @@ void WSRequestHandler::HandleGetVersion(WSRequestHandler* req) {
bfree((void*)obs_version);
}
/**
* Tells the client if authentication is required. If so, returns authentication parameters `challenge`
* and `salt` (see "Authentication" for more information).
*
* @return {boolean} `authRequired` Indicates whether authentication is required.
* @return {String (optional)} `challenge`
* @return {String (optional)} `salt`
*
* @api requests
* @name GetAuthRequired
* @category general
*/
void WSRequestHandler::HandleGetAuthRequired(WSRequestHandler* req) {
bool authRequired = Config::Current()->AuthRequired;
@ -235,6 +259,15 @@ void WSRequestHandler::HandleGetAuthRequired(WSRequestHandler* req) {
obs_data_release(data);
}
/**
* Attempt to authenticate the client to the server.
*
* @param {String} `auth` Response to the auth challenge (see "Authentication" for more information).
*
* @api requests
* @name Authenticate
* @category general
*/
void WSRequestHandler::HandleAuthenticate(WSRequestHandler* req) {
if (!req->hasField("auth")) {
req->SendErrorResponse("missing request parameters");
@ -256,6 +289,15 @@ void WSRequestHandler::HandleAuthenticate(WSRequestHandler* req) {
}
}
/**
* Switch to the specified scene.
*
* @param {String} `scene-name` Name of the scene to switch to.
*
* @api requests
* @name SetCurrentScene
* @category scenes
*/
void WSRequestHandler::HandleSetCurrentScene(WSRequestHandler* req) {
if (!req->hasField("scene-name")) {
req->SendErrorResponse("missing request parameters");
@ -275,6 +317,16 @@ void WSRequestHandler::HandleSetCurrentScene(WSRequestHandler* req) {
obs_source_release(source);
}
/**
* Get the current scene's name and source items.
*
* @return {String} `name` Name of the currently active scene.
* @return {Source|Array} `sources` Ordered list of the current scene's source items.
*
* @api requests
* @name GetCurrentScene
* @category scenes
*/
void WSRequestHandler::HandleGetCurrentScene(WSRequestHandler* req) {
obs_source_t* current_scene = obs_frontend_get_current_scene();
const char* name = obs_source_get_name(current_scene);
@ -292,6 +344,16 @@ void WSRequestHandler::HandleGetCurrentScene(WSRequestHandler* req) {
obs_source_release(current_scene);
}
/**
* Get a list of scenes in the currently active profile.
*
* @return {String} `current-scene` Name of the currently active scene.
* @return {Scene|Array} `scenes` Ordered list of the current profile's scenes (See `[GetCurrentScene](#getcurrentscene)` for more information).
*
* @api requests
* @name GetSceneList
* @category scenes
*/
void WSRequestHandler::HandleGetSceneList(WSRequestHandler* req) {
obs_source_t* current_scene = obs_frontend_get_current_scene();
obs_data_array_t* scenes = Utils::GetScenes();
@ -308,6 +370,17 @@ void WSRequestHandler::HandleGetSceneList(WSRequestHandler* req) {
obs_source_release(current_scene);
}
/**
* Show or hide a specified source item in a specified scene.
*
* @param {String} `source` Name of the source in the specified scene.
* @param {boolean} `render` Desired visibility.
* @param {String (optional)} `scene-name` Name of the scene where the source resides. Defaults to the currently active scene.
*
* @api requests
* @name SetSourceRender
* @category sources
*/
void WSRequestHandler::HandleSetSceneItemRender(WSRequestHandler* req) {
if (!req->hasField("source") ||
!req->hasField("render")) {
@ -342,6 +415,19 @@ void WSRequestHandler::HandleSetSceneItemRender(WSRequestHandler* req) {
obs_source_release(scene);
}
/**
* Get current streaming and recording status.
*
* @return {boolean} `streaming` Current streaming status.
* @return {boolean} `recording` Current recording status.
* @return {String (optional)} `stream-timecode` Time elapsed since streaming started (only present if currently streaming).
* @return {String (optional)} `rec-timecode` Time elapsed since recording started (only present if currently recording).
* @return {boolean} `preview-only` Always false. Retrocompatibility with OBSRemote.
*
* @api requests
* @name GetStreamingStatus
* @category streaming
*/
void WSRequestHandler::HandleGetStreamingStatus(WSRequestHandler* req) {
obs_data_t* data = obs_data_create();
obs_data_set_bool(data, "streaming", obs_frontend_streaming_active());
@ -365,6 +451,13 @@ void WSRequestHandler::HandleGetStreamingStatus(WSRequestHandler* req) {
obs_data_release(data);
}
/**
* Toggle streaming on or off.
*
* @api requests
* @name StartStopStreaming
* @category streaming
*/
void WSRequestHandler::HandleStartStopStreaming(WSRequestHandler* req) {
if (obs_frontend_streaming_active())
HandleStopStreaming(req);
@ -372,6 +465,13 @@ void WSRequestHandler::HandleStartStopStreaming(WSRequestHandler* req) {
HandleStartStreaming(req);
}
/**
* Toggle recording on or off.
*
* @api requests
* @name StartStopRecording
* @category recording
*/
void WSRequestHandler::HandleStartStopRecording(WSRequestHandler* req)
{
if (obs_frontend_recording_active())
@ -382,6 +482,24 @@ void WSRequestHandler::HandleStartStopRecording(WSRequestHandler* req)
req->SendOKResponse();
}
/**
* Start streaming.
* Will return an `error` if streaming is already active.
*
* @param {Object (optional)} `stream` Special stream configuration.
* @param {String (optional)} `type` If specified ensures the type of stream matches the given type (usually 'rtmp_custom' or 'rtmp_common'). If the currently configured stream type does not match the given stream type, all settings must be specified in the `settings` object or an error will occur when starting the stream.
* @param {Object (optional)} `metadata` Adds the given object parameters as encoded query string parameters to the 'key' of the RTMP stream. Used to pass data to the RTMP service about the streaming. May be any String, Numeric, or Boolean field.
* @param {Object (optional)} `settings` Settings for the stream.
* @param {String (optional)} `settings.server` The publish URL.
* @param {String (optional)} `settings.key` The publish key of the stream.
* @param {boolean (optional)} `settings.use-auth` Indicates whether authentication should be used when connecting to the streaming server.
* @param {String (optional)} `settings.username` If authentication is enabled, the username for the streaming server. Ignored if `use-auth` is not set to `true`.
* @param {String (optional)} `settings.password` If authentication is enabled, the password for the streaming server. Ignored if `use-auth` is not set to `true`.
*
* @api requests
* @name StartStreaming
* @category streaming
*/
void WSRequestHandler::HandleStartStreaming(WSRequestHandler* req)
{
if (obs_frontend_streaming_active() == false) {
@ -475,6 +593,14 @@ void WSRequestHandler::HandleStartStreaming(WSRequestHandler* req)
}
}
/**
* Stop streaming.
* Will return an `error` if streaming is not active.
*
* @api requests
* @name StopStreaming
* @category streaming
*/
void WSRequestHandler::HandleStopStreaming(WSRequestHandler* req) {
if (obs_frontend_streaming_active() == true) {
obs_frontend_streaming_stop();
@ -484,6 +610,14 @@ void WSRequestHandler::HandleStopStreaming(WSRequestHandler* req) {
}
}
/**
* Start recording.
* Will return an `error` if recording is already active.
*
* @api requests
* @name StartRecording
* @category recording
*/
void WSRequestHandler::HandleStartRecording(WSRequestHandler* req) {
if (obs_frontend_recording_active() == false) {
obs_frontend_recording_start();
@ -493,6 +627,14 @@ void WSRequestHandler::HandleStartRecording(WSRequestHandler* req) {
}
}
/**
* Stop recording.
* Will return an `error` if recording is not active.
*
* @api requests
* @name StopRecording
* @category recording
*/
void WSRequestHandler::HandleStopRecording(WSRequestHandler* req) {
if (obs_frontend_recording_active() == true) {
obs_frontend_recording_stop();
@ -502,6 +644,17 @@ void WSRequestHandler::HandleStopRecording(WSRequestHandler* req) {
}
}
/**
* List of all transitions available in the frontend's dropdown menu.
*
* @return {String} `current-transition` Name of the currently active transition.
* @return {Object|Array} `transitions` List of transitions.
* @return {String} `transitions[].name` Name of the transition.
*
* @api requests
* @name GetTransitionList
* @category transitions
*/
void WSRequestHandler::HandleGetTransitionList(WSRequestHandler* req) {
obs_source_t* current_transition = obs_frontend_get_current_transition();
obs_frontend_source_list transitionList = {};
@ -531,6 +684,16 @@ void WSRequestHandler::HandleGetTransitionList(WSRequestHandler* req) {
obs_source_release(current_transition);
}
/**
* Get the name of the currently selected transition in the frontend's dropdown menu.
*
* @return {String} `name` Name of the selected transition.
* @return {int (optional)} `duration` Transition duration (in milliseconds) if supported by the transition.
*
* @api requests
* @name GetCurrentTransition
* @category transitions
*/
void WSRequestHandler::HandleGetCurrentTransition(WSRequestHandler* req) {
obs_source_t* current_transition = obs_frontend_get_current_transition();
@ -547,6 +710,15 @@ void WSRequestHandler::HandleGetCurrentTransition(WSRequestHandler* req) {
obs_source_release(current_transition);
}
/**
* Set the active transition.
*
* @param {String} `transition-name` The name of the transition.
*
* @api requests
* @name SetCurrentTransition
* @category transitions
*/
void WSRequestHandler::HandleSetCurrentTransition(WSRequestHandler* req) {
if (!req->hasField("transition-name")) {
req->SendErrorResponse("missing request parameters");
@ -561,6 +733,15 @@ void WSRequestHandler::HandleSetCurrentTransition(WSRequestHandler* req) {
req->SendErrorResponse("requested transition does not exist");
}
/**
* Set the duration of the currently selected transition if supported.
*
* @param {int} `duration` Desired duration of the transition (in milliseconds).
*
* @api requests
* @name SetTransitionDuration
* @category transitions
*/
void WSRequestHandler::HandleSetTransitionDuration(WSRequestHandler* req) {
if (!req->hasField("duration")) {
req->SendErrorResponse("missing request parameters");
@ -572,6 +753,15 @@ void WSRequestHandler::HandleSetTransitionDuration(WSRequestHandler* req) {
req->SendOKResponse();
}
/**
* Get the duration of the currently selected transition if supported.
*
* @return {int} `transition-duration` Duration of the current transition (in milliseconds).
*
* @api requests
* @name GetTransitionDuration
* @category transitions
*/
void WSRequestHandler::HandleGetTransitionDuration(WSRequestHandler* req) {
obs_data_t* response = obs_data_create();
obs_data_set_int(response, "transition-duration",
@ -581,6 +771,16 @@ void WSRequestHandler::HandleGetTransitionDuration(WSRequestHandler* req) {
obs_data_release(response);
}
/**
* Set the volume of the specified source.
*
* @param {String} `source` Name of the source.
* @param {double} `volume` Desired volume. Must be between `0.0` and `1.0`.
*
* @api requests
* @name SetVolume
* @category sources
*/
void WSRequestHandler::HandleSetVolume(WSRequestHandler* req) {
if (!req->hasField("source") ||
!req->hasField("volume")) {
@ -609,6 +809,19 @@ void WSRequestHandler::HandleSetVolume(WSRequestHandler* req) {
obs_source_release(source);
}
/**
* Get the volume of the specified source.
*
* @param {String} `source` Name of the source.
*
* @return {String} `name` Name of the source.
* @return {double} `volume` Volume of the source. Between `0.0` and `1.0`.
* @return {boolean} `mute` Indicates whether the source is muted.
*
* @api requests
* @name GetVolume
* @category sources
*/
void WSRequestHandler::HandleGetVolume(WSRequestHandler* req) {
if (!req->hasField("source")) {
req->SendErrorResponse("missing request parameters");
@ -633,6 +846,15 @@ void WSRequestHandler::HandleGetVolume(WSRequestHandler* req) {
}
}
/**
* Inverts the mute status of a specified source.
*
* @param {String} `source` The name of the source.
*
* @api requests
* @name ToggleMute
* @category sources
*/
void WSRequestHandler::HandleToggleMute(WSRequestHandler* req) {
if (!req->hasField("source")) {
req->SendErrorResponse("missing request parameters");
@ -657,6 +879,16 @@ void WSRequestHandler::HandleToggleMute(WSRequestHandler* req) {
obs_source_release(source);
}
/**
* Sets the mute status of a specified source.
*
* @param {String} `source` The name of the source.
* @param {boolean} `mute` Desired mute status.
*
* @api requests
* @name SetMute
* @category sources
*/
void WSRequestHandler::HandleSetMute(WSRequestHandler* req) {
if (!req->hasField("source") ||
!req->hasField("mute")) {
@ -684,6 +916,18 @@ void WSRequestHandler::HandleSetMute(WSRequestHandler* req) {
obs_source_release(source);
}
/**
* Get the mute status of a specified source.
*
* @param {String} `source` The name of the source.
*
* @return {String} `name` The name of the source.
* @return {boolean} `muted` Mute status of the source.
*
* @api requests
* @name GetMute
* @category sources
*/
void WSRequestHandler::HandleGetMute(WSRequestHandler* req) {
if (!req->hasField("source")) {
req->SendErrorResponse("mssing request parameters");
@ -712,9 +956,18 @@ void WSRequestHandler::HandleGetMute(WSRequestHandler* req) {
obs_data_release(response);
}
/**
* Set the audio sync offset of a specified source.
*
* @param {String} `source` The name of the source.
* @param {int} `offset` The desired audio sync offset (in nanoseconds).
*
* @api requests
* @name SetSyncOffset
* @category sources
*/
void WSRequestHandler::HandleSetSyncOffset(WSRequestHandler* req) {
if (!req->hasField("source") ||
!req->hasField("offset")) {
if (!req->hasField("source") || !req->hasField("offset")) {
req->SendErrorResponse("missing request parameters");
return;
}
@ -722,8 +975,7 @@ void WSRequestHandler::HandleSetSyncOffset(WSRequestHandler* req) {
const char* source_name = obs_data_get_string(req->data, "source");
int64_t source_sync_offset = (int64_t)obs_data_get_int(req->data, "offset");
if (!source_name || strlen(source_name) < 1 ||
source_sync_offset < 0) {
if (!source_name || strlen(source_name) < 1 || source_sync_offset < 0) {
req->SendErrorResponse("invalid request parameters");
return;
}
@ -740,6 +992,18 @@ void WSRequestHandler::HandleSetSyncOffset(WSRequestHandler* req) {
obs_source_release(source);
}
/**
* Get the audio sync offset of a specified source.
*
* @param {String} `source` The name of the source.
*
* @return {String} `name` The name of the source.
* @return {int} `offset` The audio sync offset (in nanoseconds).
*
* @api requests
* @name GetSyncOffset
* @category sources
*/
void WSRequestHandler::HandleGetSyncOffset(WSRequestHandler* req) {
if (!req->hasField("source")) {
req->SendErrorResponse("missing request parameters");
@ -758,12 +1022,24 @@ void WSRequestHandler::HandleGetSyncOffset(WSRequestHandler* req) {
obs_data_release(response);
obs_source_release(source);
}
else {
} else {
req->SendErrorResponse("invalid request parameters");
}
}
/**
* Sets the coordinates of a specified source item.
*
* @param {String (optional)} `scene-name` The name of the scene that the source item belongs to. Defaults to the current scene.
* @param {String} `item` The name of the source item.
* @param {double} `x` X coordinate.
* @param {double} `y` Y coordinate.
*
* @api requests
* @name SetSceneItemPosition
* @category sources
*/
void WSRequestHandler::HandleSetSceneItemPosition(WSRequestHandler* req) {
if (!req->hasField("item") ||
!req->hasField("x") || !req->hasField("y")) {
@ -801,6 +1077,19 @@ void WSRequestHandler::HandleSetSceneItemPosition(WSRequestHandler* req) {
obs_source_release(scene);
}
/**
* Set the transform of the specified source item.
*
* @param {String (optional)} `scene-name` The name of the scene that the source item belongs to. Defaults to the current scene.
* @param {String} `item` The name of the source item.
* @param {double} `x-scale` Width scale factor.
* @param {double} `y-scale` Height scale factor.
* @param {double} `rotation` Source item rotation (in degrees).
*
* @api requests
* @name SetSceneItemTransform
* @category sources
*/
void WSRequestHandler::HandleSetSceneItemTransform(WSRequestHandler* req) {
if (!req->hasField("item") ||
!req->hasField("x-scale") ||
@ -842,6 +1131,20 @@ void WSRequestHandler::HandleSetSceneItemTransform(WSRequestHandler* req) {
obs_source_release(scene);
}
/**
* Sets the crop coordinates of the specified source item.
*
* @param {String (optional)} `scene-name` the name of the scene that the source item belongs to. Defaults to the current scene.
* @param {String} `item` The name of the source.
* @param {int} `top` Pixel position of the top of the source item.
* @param {int} `bottom` Pixel position of the bottom of the source item.
* @param {int} `left` Pixel position of the left of the source item.
* @param {int} `right` Pixel position of the right of the source item.
*
* @api requests
* @name SetSceneItemCrop
* @category sources
*/
void WSRequestHandler::HandleSetSceneItemCrop(WSRequestHandler* req) {
if (!req->hasField("item")) {
req->SendErrorResponse("missing request parameters");
@ -880,6 +1183,15 @@ void WSRequestHandler::HandleSetSceneItemCrop(WSRequestHandler* req) {
obs_source_release(scene);
}
/**
* Change the active scene collection.
*
* @param {String} `sc-name` Name of the desired scene collection.
*
* @api requests
* @name SetCurrentSceneCollection
* @category scene collections
*/
void WSRequestHandler::HandleSetCurrentSceneCollection(WSRequestHandler* req) {
if (!req->hasField("sc-name")) {
req->SendErrorResponse("missing request parameters");
@ -896,6 +1208,15 @@ void WSRequestHandler::HandleSetCurrentSceneCollection(WSRequestHandler* req) {
}
}
/**
* Get the name of the current scene collection.
*
* @return {String} `sc-name` Name of the currently active scene collection.
*
* @api requests
* @name GetCurrentSceneCollection
* @category scene collections
*/
void WSRequestHandler::HandleGetCurrentSceneCollection(WSRequestHandler* req) {
obs_data_t* response = obs_data_create();
obs_data_set_string(response, "sc-name",
@ -916,6 +1237,15 @@ void WSRequestHandler::HandleListSceneCollections(WSRequestHandler* req) {
obs_data_array_release(scene_collections);
}
/**
* Set the currently active profile.
*
* @param {String} `profile-name` Name of the desired profile.
*
* @api requests
* @name SetCurrentProfile
* @category profiles
*/
void WSRequestHandler::HandleSetCurrentProfile(WSRequestHandler* req) {
if (!req->hasField("profile-name")) {
req->SendErrorResponse("missing request parameters");
@ -932,6 +1262,15 @@ void WSRequestHandler::HandleSetCurrentProfile(WSRequestHandler* req) {
}
}
/**
* Get the name of the current profile.
*
* @return {String} `profile-name` Name of the currently active profile.
*
* @api requests
* @name GetCurrentProfile
* @category profiles
*/
void WSRequestHandler::HandleGetCurrentProfile(WSRequestHandler* req) {
obs_data_t* response = obs_data_create();
obs_data_set_string(response, "profile-name",
@ -941,6 +1280,22 @@ void WSRequestHandler::HandleGetCurrentProfile(WSRequestHandler* req) {
obs_data_release(response);
}
/**
* Sets one or more attributes of the current streaming server settings. Any options not passed will remain unchanged. Returns the updated settings in response. If 'type' is different than the current streaming service type, all settings are required. Returns the full settings of the stream (the same as GetStreamSettings).
*
* @param {String} `type` The type of streaming service configuration, usually `rtmp_custom` or `rtmp_common`.
* @param {Object} `settings` The actual settings of the stream.
* @param {String (optional)} `settings.server` The publish URL.
* @param {String (optional)} `settings.key` The publish key.
* @param {boolean (optional)} `settings.use-auth` Indicates whether authentication should be used when connecting to the streaming server.
* @param {String (optional)} `settings.username` The username for the streaming service.
* @param {String (optional)} `settings.password` The password for the streaming service.
* @param {boolean} `save` Persist the settings to disk.
*
* @api requests
* @name SetStreamingSettings
* @category settings
*/
void WSRequestHandler::HandleSetStreamSettings(WSRequestHandler* req) {
obs_service_t* service = obs_frontend_get_streaming_service();
@ -987,6 +1342,21 @@ void WSRequestHandler::HandleSetStreamSettings(WSRequestHandler* req) {
obs_data_release(response);
}
/**
* Get the current streaming server settings.
*
* @return {String} `type` The type of streaming service configuration. Usually 'rtmp_custom' or 'rtmp_common'.
* @return {Object} `settings` Setings of the stream.
* @return {String} `settings.server` The publish URL.
* @return {String} `settings.key` The publish key of the stream.
* @return {boolean} `settings.use-auth` Indicates whether audentication should be used when connecting to the streaming server.
* @return {String} `settings.username` The username to use when accessing the streaming server. Only present if `use-auth` is `true`.
* @return {String} `settings.password` The password to use when accessing the streaming server. Only present if `use-auth` is `true`.
*
* @api requests
* @name GetStreamSettings
* @category settings
*/
void WSRequestHandler::HandleGetStreamSettings(WSRequestHandler* req) {
obs_service_t* service = obs_frontend_get_streaming_service();
const char* serviceType = obs_service_get_type(service);
@ -1001,11 +1371,27 @@ void WSRequestHandler::HandleGetStreamSettings(WSRequestHandler* req) {
obs_data_release(response);
}
/**
* Save the current streaming server settings to disk.
*
* @api requests
* @name SaveStreamSettings
* @category settings
*/
void WSRequestHandler::HandleSaveStreamSettings(WSRequestHandler* req) {
obs_frontend_save_streaming_service();
req->SendOKResponse();
}
/**
* Get a list of available profiles.
*
* @return {Object|Array} `profiles` List of available profiles.
*
* @api requests
* @name ListProfiles
* @category profiles
*/
void WSRequestHandler::HandleListProfiles(WSRequestHandler* req) {
obs_data_array_t* profiles = Utils::GetProfiles();
@ -1017,6 +1403,15 @@ void WSRequestHandler::HandleListProfiles(WSRequestHandler* req) {
obs_data_array_release(profiles);
}
/**
* Indicates if Studio Mode is currently enabled.
*
* @return {boolean} `studio-mode` Indicates if Studio Mode is enabled.
*
* @api requests
* @name GetStudioModeStatus
* @category studio mode
*/
void WSRequestHandler::HandleGetStudioModeStatus(WSRequestHandler* req) {
bool previewActive = Utils::IsPreviewModeActive();
@ -1027,6 +1422,17 @@ void WSRequestHandler::HandleGetStudioModeStatus(WSRequestHandler* req) {
obs_data_release(response);
}
/**
* Get the name of the currently previewed scene and its list of sources.
* Will return an `error` if Studio Mode is not enabled.
*
* @return {String} `name` The name of the active preview scene.
* @return {Source|Array} `sources`
*
* @api requests
* @name GetPreviewScene
* @category studio mode
*/
void WSRequestHandler::HandleGetPreviewScene(WSRequestHandler* req) {
if (!Utils::IsPreviewModeActive()) {
req->SendErrorResponse("studio mode not enabled");
@ -1049,6 +1455,16 @@ void WSRequestHandler::HandleGetPreviewScene(WSRequestHandler* req) {
obs_scene_release(preview_scene);
}
/**
* Set the active preview scene.
* Will return an `error` if Studio Mode is not enabled.
*
* @param {String} `scene-name` The name of the scene to preview.
*
* @api requests
* @name SetPreviewScene
* @category studio mode
*/
void WSRequestHandler::HandleSetPreviewScene(WSRequestHandler* req) {
if (!Utils::IsPreviewModeActive()) {
req->SendErrorResponse("studio mode not enabled");
@ -1068,6 +1484,18 @@ void WSRequestHandler::HandleSetPreviewScene(WSRequestHandler* req) {
req->SendErrorResponse("specified scene doesn't exist");
}
/**
* Transitions the currently previewed scene to the main output.
* Will return an `error` if Studio Mode is not enabled.
*
* @param {Object (optional)} `with-transition` Change the active transition before switching scenes. Defaults to the active transition.
* @param {String} `with-transition.name` Name of the transition.
* @param {int (optional)} `with-transition.duration` Transition duration (in milliseconds).
*
* @api requests
* @name TransitionToProgram
* @category studio mode
*/
void WSRequestHandler::HandleTransitionToProgram(WSRequestHandler* req) {
if (!Utils::IsPreviewModeActive()) {
req->SendErrorResponse("studio mode not enabled");
@ -1107,21 +1535,55 @@ void WSRequestHandler::HandleTransitionToProgram(WSRequestHandler* req) {
req->SendOKResponse();
}
/**
* Enables Studio Mode.
*
* @api requests
* @name EnableStudioMode
* @category studio mode
*/
void WSRequestHandler::HandleEnableStudioMode(WSRequestHandler* req) {
Utils::EnablePreviewMode();
req->SendOKResponse();
}
/**
* Disables Studio Mode.
*
* @api requests
* @name DisableStudioMode
* @category studio mode
*/
void WSRequestHandler::HandleDisableStudioMode(WSRequestHandler* req) {
Utils::DisablePreviewMode();
req->SendOKResponse();
}
/**
* Toggles Studio Mode.
*
* @api requests
* @name ToggleStudioMode
* @category studio mode
*/
void WSRequestHandler::HandleToggleStudioMode(WSRequestHandler* req) {
Utils::TogglePreviewMode();
req->SendOKResponse();
}
/**
* Get configured special sources like Desktop Audio and Mic/Aux sources.
*
* @return {String (optional)} `desktop-1` Name of the first Desktop Audio capture source.
* @return {String (optional)} `desktop-2` Name of the second Desktop Audio capture source.
* @return {String (optional)} `mic-1` Name of the first Mic/Aux input source.
* @return {String (optional)} `mic-2` Name of the second Mic/Aux input source.
* @return {String (optional)} `mic-3` NAme of the third Mic/Aux input source.
*
* @api requests
* @name GetSpecialSources
* @category studio mode
*/
void WSRequestHandler::HandleGetSpecialSources(WSRequestHandler* req) {
obs_data_t* response = obs_data_create();
@ -1150,6 +1612,15 @@ void WSRequestHandler::HandleGetSpecialSources(WSRequestHandler* req) {
obs_data_release(response);
}
/**
* Change the current recording folder.
*
* @param {Stsring} `rec-folder` Path of the recording folder.
*
* @api requests
* @name SetRecordingFolder
* @category recording
*/
void WSRequestHandler::HandleSetRecordingFolder(WSRequestHandler* req) {
if (!req->hasField("rec-folder")) {
req->SendErrorResponse("missing request parameters");
@ -1164,6 +1635,15 @@ void WSRequestHandler::HandleSetRecordingFolder(WSRequestHandler* req) {
req->SendErrorResponse("invalid request parameters");
}
/**
* Get the path of the current recording folder.
*
* @return {Stsring} `rec-folder` Path of the recording folder.
*
* @api requests
* @name GetRecordingFolder
* @category recording
*/
void WSRequestHandler::HandleGetRecordingFolder(WSRequestHandler* req) {
const char* recFolder = Utils::GetRecordingFolder();
@ -1174,6 +1654,45 @@ void WSRequestHandler::HandleGetRecordingFolder(WSRequestHandler* req) {
obs_data_release(response);
}
/**
* Get the current properties of a Text GDI Plus source.
*
* @param {String (optional)} `scene-name` Name of the scene to retrieve. Defaults to the current scene.
* @param {String} `source` Name of the source.
*
* @return {String} `align` Text Alignment ("left", "center", "right").
* @return {int} `bk-color` Background color.
* @return {int} `bk-opacity` Background opacity (0-100).
* @return {boolean} `chatlog` Chat log.
* @return {int} `chatlog_lines` Chat log lines.
* @return {int} `color` Text color.
* @return {boolean} `extents` Extents wrap.
* @return {int} `extents_cx` Extents cx.
* @return {int} `extents_cy` Extents cy.
* @return {String} `file` File path name.
* @return {boolean} `read_from_file` Read text from the specified file.
* @return {Object} `font` Holds data for the font. Ex: `"font": { "face": "Arial", "flags": 0, "size": 150, "style": "" }`
* @return {String} `font.face` Font face.
* @return {int} `font.flags` Font text styling flag. `Bold=1, Italic=2, Bold Italic=3, Underline=5, Strikeout=8`
* @return {int} `font.size` Font text size.
* @return {String} `font.style` Font Style (unknown function).
* @return {boolean} `gradient` Gradient enabled.
* @return {int} `gradient_color` Gradient color.
* @return {float} `gradient_dir` Gradient direction.
* @return {int} `gradient_opacity` Gradient opacity (0-100).
* @return {boolean} `outline` Outline.
* @return {int} `outline_color` Outline color.
* @return {int} `outline_size` Outline size.
* @return {int} `outline_opacity` Outline opacity (0-100).
* @return {String} `text` Text content to be displayed.
* @return {String} `valign` Text vertical alignment ("top", "center", "bottom").
* @return {boolean} `vertical` Vertical text enabled.
* @return {boolean} `render` Visibility of the scene item.
*
* @api requests
* @name GetTextGDIPlusProperties
* @category sources
*/
void WSRequestHandler::HandleGetTextGDIPlusProperties(WSRequestHandler* req) {
const char* itemName = obs_data_get_string(req->data, "source");
if (!itemName) {
@ -1214,6 +1733,44 @@ void WSRequestHandler::HandleGetTextGDIPlusProperties(WSRequestHandler* req) {
obs_source_release(scene);
}
/**
* Get the current properties of a Text GDI Plus source.
*
* @param {String (optional)} `scene-name` Name of the scene to retrieve. Defaults to the current scene.
* @param {String} `source` Name of the source.
* @param {String (optional)} `align` Text Alignment ("left", "center", "right").
* @param {int (optional)} `bk-color` Background color.
* @param {int (optional)} `bk-opacity` Background opacity (0-100).
* @param {boolean (optional)} `chatlog` Chat log.
* @param {int (optional)} `chatlog_lines` Chat log lines.
* @param {int (optional)} `color` Text color.
* @param {boolean (optional)} `extents` Extents wrap.
* @param {int (optional)} `extents_cx` Extents cx.
* @param {int (optional)} `extents_cy` Extents cy.
* @param {String (optional)} `file` File path name.
* @param {boolean (optional)} `read_from_file` Read text from the specified file.
* @param {Object (optional)} `font` Holds data for the font. Ex: `"font": { "face": "Arial", "flags": 0, "size": 150, "style": "" }`
* @param {String (optional)} `font.face` Font face.
* @param {int (optional)} `font.flags` Font text styling flag. `Bold=1, Italic=2, Bold Italic=3, Underline=5, Strikeout=8`
* @param {int (optional)} `font.size` Font text size.
* @param {String (optional)} `font.style` Font Style (unknown function).
* @param {boolean (optional)} `gradient` Gradient enabled.
* @param {int (optional)} `gradient_color` Gradient color.
* @param {float (optional)} `gradient_dir` Gradient direction.
* @param {int (optional)} `gradient_opacity` Gradient opacity (0-100).
* @param {boolean (optional)} `outline` Outline.
* @param {int (optional)} `outline_color` Outline color.
* @param {int (optional)} `outline_size` Outline size.
* @param {int (optional)} `outline_opacity` Outline opacity (0-100).
* @param {String (optional)} `text` Text content to be displayed.
* @param {String (optional)} `valign` Text vertical alignment ("top", "center", "bottom").
* @param {boolean (optional)} `vertical` Vertical text enabled.
* @param {boolean (optional)} `render` Visibility of the scene item.
*
* @api requests
* @name SetTextGDIPlusProperties
* @category sources
*/
void WSRequestHandler::HandleSetTextGDIPlusProperties(WSRequestHandler* req) {
if (!req->hasField("source")) {
req->SendErrorResponse("missing request parameters");
@ -1406,6 +1963,25 @@ void WSRequestHandler::HandleSetTextGDIPlusProperties(WSRequestHandler* req) {
obs_source_release(scene);
}
/**
* Get current properties for a Browser Source.
*
* @param {String (optional)} `scene-name` Name of the scene that the source belongs to. Defaults to the current scene.
* @param {String} `source` Name of the source.
*
* @return {boolean} `is_local_file` Indicates that a local file is in use.
* @return {String} `url` Url or file path.
* @return {String} `css` CSS to inject.
* @return {int} `width` Width.
* @return {int} `height` Height.
* @return {int} `fps` Framerate.
* @return {boolean} `shutdown` Indicates whether the source should be shutdown when not visible.
* @return {boolean (optional)} `render` Visibility of the scene item.
*
* @api requests
* @name GetBrowserSourceProperties
* @category sources
*/
void WSRequestHandler::HandleGetBrowserSourceProperties(WSRequestHandler* req) {
const char* itemName = obs_data_get_string(req->data, "source");
if (!itemName) {
@ -1445,6 +2021,24 @@ void WSRequestHandler::HandleGetBrowserSourceProperties(WSRequestHandler* req) {
obs_source_release(scene);
}
/**
* Set current properties for a Browser Source.
*
* @param {String (optional)} `scene-name` Name of the scene that the source belongs to. Defaults to the current scene.
* @param {String} `source` Name of the source.
* @param {boolean (optional)} `is_local_file` Indicates that a local file is in use.
* @param {String (optional)} `url` Url or file path.
* @param {String (optional)} `css` CSS to inject.
* @param {int (optional)} `width` Width.
* @param {int (optional)} `height` Height.
* @param {int (optional)} `fps` Framerate.
* @param {boolean (optional)} `shutdown` Indicates whether the source should be shutdown when not visible.
* @param {boolean (optional)} `render` Visibility of the scene item.
*
* @api requests
* @name SetBrowserSourceProperties
* @category sources
*/
void WSRequestHandler::HandleSetBrowserSourceProperties(WSRequestHandler* req) {
if (!req->hasField("source")) {
req->SendErrorResponse("missing request parameters");
@ -1532,6 +2126,16 @@ void WSRequestHandler::HandleSetBrowserSourceProperties(WSRequestHandler* req) {
obs_source_release(scene);
}
/**
* Reset a source item.
*
* @param {String (optional)} `scene-name` Name of the scene the source belogns to. Defaults to the current scene.
* @param {String} `item` Name of the source item.
*
* @api requests
* @name ResetSceneItem
* @category sources
*/
void WSRequestHandler::HandleResetSceneItem(WSRequestHandler* req) {
if (!req->hasField("item")) {
req->SendErrorResponse("missing request parameters");

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
```

52
docs/comments.js Normal file
View File

@ -0,0 +1,52 @@
const fs = require('fs');
const glob = require('glob');
const parseComments = require('parse-comments');
/**
* 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 = {};
comments.forEach(comment => {
if (typeof comment.api === 'undefined') return;
// 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);
});
return sorted;
};
const files = glob.sync("./../*.@(cpp|h)");
const comments = processComments(parseFiles(files));
fs.writeFileSync('./generated/comments.json', JSON.stringify(comments, null, 2));

31
docs/docs.js Normal file
View File

@ -0,0 +1,31 @@
const fs = require('fs');
const toc = require('markdown-toc');
const handlebars = require('handlebars');
const helpers = require('handlebars-helpers')({
handlebars: handlebars
});
// Allows pipe characters to be used within markdown tables.
handlebars.registerHelper('depipe', (text) => {
return text.replace('|', `\\|`);
});
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));
};
const comments = fs.readFileSync('./generated/comments.json', 'utf8');
const markdown = generateProtocol('./protocol.hbs', JSON.parse(comments));
fs.writeFileSync('./generated/protocol.md', markdown);

3464
docs/generated/comments.json Normal file

File diff suppressed because it is too large Load Diff

1508
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,37 @@
# obs-websocket 4.1 protocol reference
**This is the reference for the latest 4.1 development build. [See here for obs-websocket 4.0.0!](https://github.com/Palakis/obs-websocket/blob/4.0.0/PROTOCOL.md)**
# General Introduction
Messages are exchanged between the client and the server as JSON objects.
This protocol is based on the original OBS Remote protocol created by Bill Hamilton, with new commands specific to OBS Studio.
# Authentication
OBSWebSocket uses SHA256 to transmit credentials.
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)
```

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_: An error message accompanying an `error` status.
Additional information may be required/returned depending on the request type. See below for more information.

80
docs/protocol.hbs Normal file
View File

@ -0,0 +1,80 @@
{{#read "partials/introduction.md"}}{{/read}}
# Table of Contents
<!-- toc -->
{{#read "partials/eventsHeader.md"}}{{/read}}
{{#each events}}
## {{capitalizeAll @key}}
{{#each this}}
### {{name}}
{{{description}}}
**Response Items:**
{{#if returns.length}}
| Name | Type | Description |
| ---- | :---: | ------------|
{{#each returns}}
| `{{name}}` | _{{depipe type}}_ | {{{description}}} |
{{/each}}
{{else}}
_No additional response items._
{{/if}}
---
{{/each}}
{{/each}}
{{#read "partials/requestsHeader.md"}}{{/read}}
{{#each requests}}
## {{capitalizeAll @key}}
{{#each this}}
### {{name}}
{{{description}}}
**Request Fields:**
{{#if params.length}}
| Name | Type | Description |
| ---- | :---: | ------------|
{{#each params}}
| `{{name}}` | _{{depipe type}}_ | {{{description}}} |
{{/each}}
{{else}}
_No specified parameters._
{{/if}}
**Response Items:**
{{#if returns.length}}
| Name | Type | Description |
| ---- | :---: | ------------|
{{#each returns}}
| `{{name}}` | _{{depipe type}}_ | {{{description}}} |
{{/each}}
{{else}}
_No additional response items._
{{/if}}
---
{{/each}}
{{/each}}