mirror of
https://github.com/Palakis/obs-websocket.git
synced 2024-08-30 18:12:16 +00:00
Docs: Initial generation of docs from code comments (#106)
This commit is contained in:
parent
1eccf4c899
commit
a263d8a364
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 54 KiB |
Before Width: | Height: | Size: 7.8 KiB After Width: | Height: | Size: 7.8 KiB |
2
.gitignore
vendored
2
.gitignore
vendored
@ -5,3 +5,5 @@
|
||||
/build64/
|
||||
/release/
|
||||
/installer/Output/
|
||||
|
||||
.vscode
|
17
.travis.yml
17
.travis.yml
@ -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
32
CI/generate-docs.sh
Executable 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
|
1004
PROTOCOL.md
1004
PROTOCOL.md
File diff suppressed because it is too large
Load Diff
@ -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.
|
||||
|
||||
[](http://supportclass.net)
|
||||
[](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.
|
||||
|
||||
[](http://www.mediaunit.no/)
|
||||
[](http://www.mediaunit.no/)
|
||||
|
262
WSEvents.cpp
262
WSEvents.cpp
@ -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);
|
||||
|
File diff suppressed because it is too large
Load Diff
11
docs/.editorconfig
Normal file
11
docs/.editorconfig
Normal 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
4
docs/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
node_modules
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
1
docs/.npmrc
Normal file
1
docs/.npmrc
Normal file
@ -0,0 +1 @@
|
||||
package-lock=false
|
21
docs/README.md
Normal file
21
docs/README.md
Normal 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
52
docs/comments.js
Normal 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
31
docs/docs.js
Normal 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
3464
docs/generated/comments.json
Normal file
File diff suppressed because it is too large
Load Diff
1508
docs/generated/protocol.md
Normal file
1508
docs/generated/protocol.md
Normal file
File diff suppressed because it is too large
Load Diff
21
docs/package.json
Normal file
21
docs/package.json
Normal 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"
|
||||
}
|
||||
}
|
11
docs/partials/eventsHeader.md
Normal file
11
docs/partials/eventsHeader.md
Normal 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.
|
37
docs/partials/introduction.md
Normal file
37
docs/partials/introduction.md
Normal 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)
|
||||
```
|
11
docs/partials/requestsHeader.md
Normal file
11
docs/partials/requestsHeader.md
Normal 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
80
docs/protocol.hbs
Normal 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}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user