mirror of
https://github.com/Palakis/obs-websocket.git
synced 2024-08-30 18:12:16 +00:00
Merge pull request #879 from dnaka91/docs-formatting
docs: Improve generated docs formatting
This commit is contained in:
commit
828dbde75c
24
.github/workflows/lint.yml
vendored
Normal file
24
.github/workflows/lint.yml
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
name: Code Quality
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
markdown:
|
||||
name: Lint Markdown
|
||||
runs-on: ubuntu-latest
|
||||
if: contains(github.event.head_commit.message, '[skip ci]') != true
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
- name: Generate docs
|
||||
run: cd docs && ./build_docs.sh
|
||||
- name: Run markdownlint-cli
|
||||
uses: nosborn/github-action-markdown-cli@v3.0.1
|
||||
with:
|
||||
files: .
|
2
.markdownlintignore
Normal file
2
.markdownlintignore
Normal file
@ -0,0 +1,2 @@
|
||||
/deps
|
||||
/docs/comments/node_modules
|
3
.markdownlintrc
Normal file
3
.markdownlintrc
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"line-length": false
|
||||
}
|
@ -1,3 +1,5 @@
|
||||
<!-- markdownlint-disable no-inline-html -->
|
||||
|
||||
# obs-websocket
|
||||
|
||||
<p align="center">
|
||||
@ -27,11 +29,13 @@ It is **highly recommended** to protect obs-websocket with a password against un
|
||||
- Automate scene switching with a third-party program (e.g. : auto-pilot, foot pedal, ...)
|
||||
|
||||
### Client software
|
||||
|
||||
- (No known clients supporting 5.0.0 at the moment. Ping us in the Discord if you have one!)
|
||||
|
||||
### Client libraries (for developers)
|
||||
|
||||
Here's a list of available language APIs for obs-websocket:
|
||||
|
||||
- Python 3.7+ (Asyncio): [simpleobsws](https://github.com/IRLToolkit/simpleobsws/tree/master) by IRLToolkit
|
||||
- Rust: [obws](https://github.com/dnaka91/obws/tree/v5-api) by dnaka91
|
||||
- Godot 3.4.x: [obs-websocket-gd](https://github.com/you-win/obs-websocket-gd) by you-win
|
||||
|
265
docs/README.md
265
docs/README.md
@ -1,127 +1,138 @@
|
||||
# obs-websocket documentation
|
||||
|
||||
This is the documentation for obs-websocket. Run `build_docs.sh` to auto generate the latest docs from the `src` directory. There are 3 components to the docs generation:
|
||||
- `comments/comments.js`: Generates the `work/comments.json` file from the code comments in the src directory.
|
||||
- `docs/process_comments.py`: Processes `work/comments.json` to create `generated/protocol.json`, which is a machine-readable documentation format that can be used to create obs-websocket client libraries.
|
||||
- `docs/generate_md.py`: Processes `generated/protocol.json` to create `generated/protocol.md`, which is the actual human-readable documentation.
|
||||
|
||||
Some notes about documenting:
|
||||
- The `complexity` comment line is a suggestion to the user about how much knowledge about OBS's inner workings is required to safely use the associated feature. `1` for easy, `5` for megadeath-expert.
|
||||
- The `rpcVersion` comment line is used to specify the latest available version that the feature is available in. If a feature is deprecated, then the placeholder value of `-1` should be replaced with the last RPC version that the feature will be available in. Manually specifying an RPC version automatically adds the `Deprecated` line to the entry in `generated/protocol.md`.
|
||||
- The description can be multiple lines, but must be contained above the first documentation property (the lines starting with `@`).
|
||||
- Value types are in reference to JSON values. The only ones you should use are `Any`, `String`, `Boolean`, `Number`, `Array`, `Object`.
|
||||
- `Array` types follow this format: `Array<subtype>`, for example `Array<String>` to specify an array of strings.
|
||||
|
||||
Formatting notes:
|
||||
- Fields should have their columns aligned. So in a request, the columns of all `@requestField`s should be aligned.
|
||||
- We suggest looking at how other enums/events/requests have been documented before documenting one of your own, to get a general feel of how things have been formatted.
|
||||
|
||||
## Creating enum documentation
|
||||
|
||||
Enums follow this code comment format:
|
||||
```
|
||||
/**
|
||||
* [description]
|
||||
*
|
||||
* @enumIdentifier [identifier]
|
||||
* @enumValue [value]
|
||||
* @enumType [type]
|
||||
* @rpcVersion [latest available RPC version, use `-1` unless deprecated.]
|
||||
* @initialVersion [first obs-websocket version this is found in]
|
||||
* @api enums
|
||||
*/
|
||||
```
|
||||
|
||||
Example code comment:
|
||||
```
|
||||
/**
|
||||
* The initial message sent by obs-websocket to newly connected clients.
|
||||
*
|
||||
* @enumIdentifier Hello
|
||||
* @enumValue 0
|
||||
* @enumType WebSocketOpCode
|
||||
* @rpcVersion -1
|
||||
* @initialVersion 5.0.0
|
||||
* @api enums
|
||||
*/
|
||||
```
|
||||
- This is the documentation for the `WebSocketOpCode::Hello` enum identifier.
|
||||
|
||||
## Creating event documentation
|
||||
|
||||
Events follow this code comment format:
|
||||
```
|
||||
/**
|
||||
* [description]
|
||||
*
|
||||
* @dataField [field name] | [value type] | [field description]
|
||||
* [... more @dataField entries ...]
|
||||
*
|
||||
* @eventType [type]
|
||||
* @eventSubscription [EventSubscription requirement]
|
||||
* @complexity [complexity rating, 1-5]
|
||||
* @rpcVersion [latest available RPC version, use `-1` unless deprecated.]
|
||||
* @initialVersion [first obs-websocket version this is found in]
|
||||
* @category [event category]
|
||||
* @api events
|
||||
*/
|
||||
```
|
||||
|
||||
Example code comment:
|
||||
```
|
||||
/**
|
||||
* Studio mode has been enabled or disabled.
|
||||
*
|
||||
* @dataField studioModeEnabled | Boolean | True == Enabled, False == Disabled
|
||||
*
|
||||
* @eventType StudioModeStateChanged
|
||||
* @eventSubscription General
|
||||
* @complexity 1
|
||||
* @rpcVersion -1
|
||||
* @initialVersion 5.0.0
|
||||
* @category general
|
||||
* @api events
|
||||
*/
|
||||
```
|
||||
|
||||
## Creating request documentation
|
||||
|
||||
Requests follow this code comment format:
|
||||
```
|
||||
/**
|
||||
* [description]
|
||||
*
|
||||
* @requestField [optional flag][field name] | [value type] | [field description] | [value restrictions (only include if the value type is `Number`)] | [default behavior (only include if optional flag is set)]
|
||||
* [... more @requestField entries ...]
|
||||
*
|
||||
* @responseField [field name] | [value type] | [field description]
|
||||
* [... more @responseField entries ...]
|
||||
*
|
||||
* @requestType [type]
|
||||
* @complexity [complexity rating, 1-5]
|
||||
* @rpcVersion [latest available RPC version, use `-1` unless deprecated.]
|
||||
* @initialVersion [first obs-websocket version this is found in]
|
||||
* @category [request category]
|
||||
* @api requests
|
||||
*/
|
||||
```
|
||||
- The optional flag is a `?` that prefixes the field name, telling the docs processor that the field is optionally specified.
|
||||
|
||||
Example code comment:
|
||||
```
|
||||
/**
|
||||
* Gets the value of a "slot" from the selected persistent data realm.
|
||||
*
|
||||
* @requestField realm | String | The data realm to select. `OBS_WEBSOCKET_DATA_REALM_GLOBAL` or `OBS_WEBSOCKET_DATA_REALM_PROFILE`
|
||||
* @requestField slotName | String | The name of the slot to retrieve data from
|
||||
*
|
||||
* @responseField slotValue | String | Value associated with the slot. `null` if not set
|
||||
*
|
||||
* @requestType GetPersistentData
|
||||
* @complexity 2
|
||||
* @rpcVersion -1
|
||||
* @initialVersion 5.0.0
|
||||
* @category config
|
||||
* @api requests
|
||||
*/
|
||||
```
|
||||
# obs-websocket documentation
|
||||
|
||||
This is the documentation for obs-websocket. Run `build_docs.sh` to auto generate the latest docs from the `src` directory. There are 3 components to the docs generation:
|
||||
|
||||
- `comments/comments.js`: Generates the `work/comments.json` file from the code comments in the src directory.
|
||||
- `docs/process_comments.py`: Processes `work/comments.json` to create `generated/protocol.json`, which is a machine-readable documentation format that can be used to create obs-websocket client libraries.
|
||||
- `docs/generate_md.py`: Processes `generated/protocol.json` to create `generated/protocol.md`, which is the actual human-readable documentation.
|
||||
|
||||
Some notes about documenting:
|
||||
|
||||
- The `complexity` comment line is a suggestion to the user about how much knowledge about OBS's inner workings is required to safely use the associated feature. `1` for easy, `5` for megadeath-expert.
|
||||
- The `rpcVersion` comment line is used to specify the latest available version that the feature is available in. If a feature is deprecated, then the placeholder value of `-1` should be replaced with the last RPC version that the feature will be available in. Manually specifying an RPC version automatically adds the `Deprecated` line to the entry in `generated/protocol.md`.
|
||||
- The description can be multiple lines, but must be contained above the first documentation property (the lines starting with `@`).
|
||||
- Value types are in reference to JSON values. The only ones you should use are `Any`, `String`, `Boolean`, `Number`, `Array`, `Object`.
|
||||
- `Array` types follow this format: `Array<subtype>`, for example `Array<String>` to specify an array of strings.
|
||||
|
||||
Formatting notes:
|
||||
|
||||
- Fields should have their columns aligned. So in a request, the columns of all `@requestField`s should be aligned.
|
||||
- We suggest looking at how other enums/events/requests have been documented before documenting one of your own, to get a general feel of how things have been formatted.
|
||||
|
||||
## Creating enum documentation
|
||||
|
||||
Enums follow this code comment format:
|
||||
|
||||
```js
|
||||
/**
|
||||
* [description]
|
||||
*
|
||||
* @enumIdentifier [identifier]
|
||||
* @enumValue [value]
|
||||
* @enumType [type]
|
||||
* @rpcVersion [latest available RPC version, use `-1` unless deprecated.]
|
||||
* @initialVersion [first obs-websocket version this is found in]
|
||||
* @api enums
|
||||
*/
|
||||
```
|
||||
|
||||
Example code comment:
|
||||
|
||||
```js
|
||||
/**
|
||||
* The initial message sent by obs-websocket to newly connected clients.
|
||||
*
|
||||
* @enumIdentifier Hello
|
||||
* @enumValue 0
|
||||
* @enumType WebSocketOpCode
|
||||
* @rpcVersion -1
|
||||
* @initialVersion 5.0.0
|
||||
* @api enums
|
||||
*/
|
||||
```
|
||||
|
||||
- This is the documentation for the `WebSocketOpCode::Hello` enum identifier.
|
||||
|
||||
## Creating event documentation
|
||||
|
||||
Events follow this code comment format:
|
||||
|
||||
```js
|
||||
/**
|
||||
* [description]
|
||||
*
|
||||
* @dataField [field name] | [value type] | [field description]
|
||||
* [... more @dataField entries ...]
|
||||
*
|
||||
* @eventType [type]
|
||||
* @eventSubscription [EventSubscription requirement]
|
||||
* @complexity [complexity rating, 1-5]
|
||||
* @rpcVersion [latest available RPC version, use `-1` unless deprecated.]
|
||||
* @initialVersion [first obs-websocket version this is found in]
|
||||
* @category [event category]
|
||||
* @api events
|
||||
*/
|
||||
```
|
||||
|
||||
Example code comment:
|
||||
|
||||
```js
|
||||
/**
|
||||
* Studio mode has been enabled or disabled.
|
||||
*
|
||||
* @dataField studioModeEnabled | Boolean | True == Enabled, False == Disabled
|
||||
*
|
||||
* @eventType StudioModeStateChanged
|
||||
* @eventSubscription General
|
||||
* @complexity 1
|
||||
* @rpcVersion -1
|
||||
* @initialVersion 5.0.0
|
||||
* @category general
|
||||
* @api events
|
||||
*/
|
||||
```
|
||||
|
||||
## Creating request documentation
|
||||
|
||||
Requests follow this code comment format:
|
||||
|
||||
```js
|
||||
/**
|
||||
* [description]
|
||||
*
|
||||
* @requestField [optional flag][field name] | [value type] | [field description] | [value restrictions (only include if the value type is `Number`)] | [default behavior (only include if optional flag is set)]
|
||||
* [... more @requestField entries ...]
|
||||
*
|
||||
* @responseField [field name] | [value type] | [field description]
|
||||
* [... more @responseField entries ...]
|
||||
*
|
||||
* @requestType [type]
|
||||
* @complexity [complexity rating, 1-5]
|
||||
* @rpcVersion [latest available RPC version, use `-1` unless deprecated.]
|
||||
* @initialVersion [first obs-websocket version this is found in]
|
||||
* @category [request category]
|
||||
* @api requests
|
||||
*/
|
||||
```
|
||||
|
||||
- The optional flag is a `?` that prefixes the field name, telling the docs processor that the field is optionally specified.
|
||||
|
||||
Example code comment:
|
||||
|
||||
```js
|
||||
/**
|
||||
* Gets the value of a "slot" from the selected persistent data realm.
|
||||
*
|
||||
* @requestField realm | String | The data realm to select. `OBS_WEBSOCKET_DATA_REALM_GLOBAL` or `OBS_WEBSOCKET_DATA_REALM_PROFILE`
|
||||
* @requestField slotName | String | The name of the slot to retrieve data from
|
||||
*
|
||||
* @responseField slotValue | String | Value associated with the slot. `null` if not set
|
||||
*
|
||||
* @requestType GetPersistentData
|
||||
* @complexity 2
|
||||
* @rpcVersion -1
|
||||
* @initialVersion 5.0.0
|
||||
* @category config
|
||||
* @api requests
|
||||
*/
|
||||
```
|
||||
|
@ -30,7 +30,6 @@ categoryOrder = [
|
||||
]
|
||||
|
||||
requestFieldHeader = """
|
||||
|
||||
**Request Fields:**
|
||||
|
||||
| Name | Type | Description | Value Restrictions | ?Default Behavior |
|
||||
@ -38,7 +37,6 @@ requestFieldHeader = """
|
||||
"""
|
||||
|
||||
responseFieldHeader = """
|
||||
|
||||
**Response Fields:**
|
||||
|
||||
| Name | Type | Description |
|
||||
@ -46,7 +44,6 @@ responseFieldHeader = """
|
||||
"""
|
||||
|
||||
dataFieldHeader = """
|
||||
|
||||
**Data Fields:**
|
||||
|
||||
| Name | Type | Description |
|
||||
@ -130,6 +127,8 @@ def get_enums(enums):
|
||||
ret += '- Added in v{}\n'.format(enumIdentifier['initialVersion'])
|
||||
if enumIdentifier != enum['enumIdentifiers'][-1]:
|
||||
ret += '\n---\n\n'
|
||||
else:
|
||||
ret += '\n'
|
||||
return ret
|
||||
|
||||
def get_requests_toc(requests):
|
||||
@ -143,7 +142,7 @@ def get_requests_toc(requests):
|
||||
if not len(requestsOut):
|
||||
continue
|
||||
categoryFragment = get_fragment(category, False)
|
||||
ret += '- [{}](#{})\n'.format(category, categoryFragment)
|
||||
ret += '- [{} Requests](#{}-requests)\n'.format(category, categoryFragment)
|
||||
for request in requestsOut:
|
||||
requestType = request['requestType']
|
||||
requestTypeFragment = get_fragment(requestType, False)
|
||||
@ -161,7 +160,7 @@ def get_requests(requests):
|
||||
if not len(requestsOut):
|
||||
continue
|
||||
categoryFragment = get_fragment(category)
|
||||
ret += '\n\n## {}\n\n'.format(category)
|
||||
ret += '## {} Requests\n\n'.format(category)
|
||||
for request in requestsOut:
|
||||
requestType = request['requestType']
|
||||
requestTypeFragment = get_fragment(requestType)
|
||||
@ -193,6 +192,8 @@ def get_requests(requests):
|
||||
|
||||
if request != requestsOut[-1]:
|
||||
ret += '\n---\n\n'
|
||||
else:
|
||||
ret += '\n'
|
||||
return ret
|
||||
|
||||
def get_events_toc(events):
|
||||
@ -206,7 +207,7 @@ def get_events_toc(events):
|
||||
if not len(eventsOut):
|
||||
continue
|
||||
categoryFragment = get_fragment(category, False)
|
||||
ret += '- [{}](#{})\n'.format(category, categoryFragment)
|
||||
ret += '- [{} Events](#{}-events)\n'.format(category, categoryFragment)
|
||||
for event in eventsOut:
|
||||
eventType = event['eventType']
|
||||
eventTypeFragment = get_fragment(eventType, False)
|
||||
@ -224,7 +225,7 @@ def get_events(events):
|
||||
if not len(eventsOut):
|
||||
continue
|
||||
categoryFragment = get_fragment(category)
|
||||
ret += '## {}\n\n'.format(category)
|
||||
ret += '## {} Events\n\n'.format(category)
|
||||
for event in eventsOut:
|
||||
eventType = event['eventType']
|
||||
eventTypeFragment = get_fragment(eventType)
|
||||
@ -247,6 +248,8 @@ def get_events(events):
|
||||
|
||||
if event != eventsOut[-1]:
|
||||
ret += '\n---\n\n'
|
||||
else:
|
||||
ret += '\n'
|
||||
return ret
|
||||
|
||||
# Actual code
|
||||
@ -264,40 +267,41 @@ except IOError:
|
||||
with open('../generated/protocol.json', 'r') as f:
|
||||
protocol = json.load(f)
|
||||
|
||||
output = "<!-- This file was automatically generated. Do not edit directly! -->\n\n"
|
||||
output = "<!-- This file was automatically generated. Do not edit directly! -->\n"
|
||||
output += "<!-- markdownlint-disable no-bare-urls -->\n"
|
||||
|
||||
# Insert introduction partial
|
||||
output += read_file('partials/introduction.md')
|
||||
logging.info('Inserted introduction section.')
|
||||
|
||||
output += '\n\n'
|
||||
output += '\n'
|
||||
|
||||
# Generate enums MD
|
||||
output += read_file('partials/enumsHeader.md')
|
||||
output += '\n'
|
||||
output += get_enums_toc(protocol['enums'])
|
||||
output += '\n\n'
|
||||
output += '\n'
|
||||
output += get_enums(protocol['enums'])
|
||||
logging.info('Inserted enums section.')
|
||||
|
||||
output += '\n\n'
|
||||
|
||||
# Generate events MD
|
||||
output += read_file('partials/eventsHeader.md')
|
||||
output += '\n'
|
||||
output += get_events_toc(protocol['events'])
|
||||
output += '\n\n'
|
||||
output += '\n'
|
||||
output += get_events(protocol['events'])
|
||||
logging.info('Inserted events section.')
|
||||
|
||||
output += '\n\n'
|
||||
|
||||
# Generate requests MD
|
||||
output += read_file('partials/requestsHeader.md')
|
||||
output += '\n'
|
||||
output += get_requests_toc(protocol['requests'])
|
||||
output += '\n\n'
|
||||
output += '\n'
|
||||
output += get_requests(protocol['requests'])
|
||||
logging.info('Inserted requests section.')
|
||||
|
||||
output += '\n\n'
|
||||
if output.endswith('\n\n'):
|
||||
output = output[:-1]
|
||||
|
||||
# Write new protocol MD
|
||||
with open('../generated/protocol.md', 'w') as f:
|
||||
|
@ -1,4 +1,5 @@
|
||||
# Enums
|
||||
|
||||
These are enumeration declarations, which are referenced throughout obs-websocket's protocol.
|
||||
|
||||
### Enumerations Table of Contents
|
||||
## Enumerations Table of Contents
|
||||
|
@ -1,3 +1,3 @@
|
||||
# Events
|
||||
|
||||
### Events Table of Contents
|
||||
## Events Table of Contents
|
||||
|
@ -1,28 +1,31 @@
|
||||
# Main Table of Contents
|
||||
- [obs-websocket 5.0.0 Protocol](#obs-websocket-500-protocol)
|
||||
- [Connecting to obs-websocket](#connecting-to-obs-websocket)
|
||||
- [Connection steps](#connection-steps)
|
||||
- [Creating an authentication string](#creating-an-authentication-string)
|
||||
- [Base message types](#message-types)
|
||||
- [OpCode 0 Hello](#hello-opcode-0)
|
||||
- [OpCode 1 Identify](#identify-opcode-1)
|
||||
- [OpCode 2 Identified](#identified-opcode-2)
|
||||
- [OpCode 3 Reidentify](#reidentify-opcode-3)
|
||||
- [OpCode 5 Event](#event-opcode-5)
|
||||
- [OpCode 6 Request](#request-opcode-6)
|
||||
- [OpCode 7 RequestResponse](#requestresponse-opcode-7)
|
||||
- [OpCode 8 RequestBatch](#requestbatch-opcode-8)
|
||||
- [OpCode 9 RequestBatchResponse](#requestbatchresponse-opcode-9)
|
||||
- [Enums](#enums)
|
||||
- [Events](#events)
|
||||
- [Requests](#requests)
|
||||
|
||||
# obs-websocket 5.0.0 Protocol
|
||||
|
||||
## Main Table of Contents
|
||||
|
||||
- [General Intro](#general-intro)
|
||||
- [Design Goals](#design-goals)
|
||||
- [Connecting to obs-websocket](#connecting-to-obs-websocket)
|
||||
- [Connection steps](#connection-steps)
|
||||
- [Connection Notes](#connection-notes)
|
||||
- [Creating an authentication string](#creating-an-authentication-string)
|
||||
- [Message Types (OpCodes)](#message-types-opcodes)
|
||||
- [Hello (OpCode 0)](#hello-opcode-0)
|
||||
- [Identify (OpCode 1)](#identify-opcode-1)
|
||||
- [Identified (OpCode 2)](#identified-opcode-2)
|
||||
- [Reidentify (OpCode 3)](#reidentify-opcode-3)
|
||||
- [Event (OpCode 5)](#event-opcode-5)
|
||||
- [Request (OpCode 6)](#request-opcode-6)
|
||||
- [RequestResponse (OpCode 7)](#requestresponse-opcode-7)
|
||||
- [RequestBatch (OpCode 8)](#requestbatch-opcode-8)
|
||||
- [RequestBatchResponse (OpCode 9)](#requestbatchresponse-opcode-9)
|
||||
|
||||
## General Intro
|
||||
|
||||
obs-websocket provides a feature-rich RPC communication protocol, giving access to much of OBS's feature set. This document contains everything you should know in order to make a connection and use obs-websocket's functionality to the fullest.
|
||||
|
||||
### Design Goals
|
||||
|
||||
- Abstraction of identification, events, requests, and batch requests into dedicated message types
|
||||
- Conformity of request naming using similar terms like `Get`, `Set`, `Get[x]List`, `Start[x]`, `Toggle[x]`
|
||||
- Conformity of OBS data field names like `sourceName`, `sourceKind`, `sourceType`, `sceneName`, `sceneItemName`
|
||||
@ -31,13 +34,14 @@ obs-websocket provides a feature-rich RPC communication protocol, giving access
|
||||
- PubSub system - Allow clients to specify which events they do or don't want to receive from OBS
|
||||
- RPC versioning - Client and server negotiate the latest version of the obs-websocket protocol to communicate with.
|
||||
|
||||
|
||||
## Connecting to obs-websocket
|
||||
|
||||
Here's info on how to connect to obs-websocket
|
||||
|
||||
---
|
||||
|
||||
### Connection steps
|
||||
|
||||
These steps should be followed precisely. Failure to connect to the server as instructed will likely result in your client being treated in an undefined way.
|
||||
|
||||
- Initial HTTP request made to the obs-websocket server.
|
||||
@ -64,6 +68,7 @@ These steps should be followed precisely. Failure to connect to the server as in
|
||||
- At any time after a client has been identified, it may send an [OpCode 3 `Reidentify`](#reidentify-opcode-3) message to update certain allowed session parameters. The server will respond in the same way it does during initial identification.
|
||||
|
||||
#### Connection Notes
|
||||
|
||||
- If a binary frame is received when using the `obswebsocket.json` (default) subprotocol, or a text frame is received while using the `obswebsocket.msgpack` subprotocol, the connection is closed with `WebSocketCloseCode::MessageDecodeError`.
|
||||
- The obs-websocket server listens for any messages containing a `request-type` field in the first level JSON from unidentified clients. If a message matches, the connection is closed with `WebSocketCloseCode::UnsupportedRpcVersion` and a warning is logged.
|
||||
- If a message with a `messageType` is not recognized to the obs-websocket server, the connection is closed with `WebSocketCloseCode::UnknownOpCode`.
|
||||
@ -72,11 +77,13 @@ These steps should be followed precisely. Failure to connect to the server as in
|
||||
---
|
||||
|
||||
### Creating an authentication string
|
||||
|
||||
obs-websocket uses SHA256 to transmit authentication credentials. The server starts by sending an object in the `authentication` field of its `Hello` message data. The client processes the authentication challenge and responds via the `authentication` string in the `Identify` message data.
|
||||
|
||||
For this guide, we'll be using `supersecretpassword` as the password.
|
||||
|
||||
The `authentication` object in `Hello` looks like this (example):
|
||||
|
||||
```json
|
||||
{
|
||||
"challenge": "+IxH4CnCiqpX1rM9scsNynZzbOe4KhDeYcTNS3PDaeY=",
|
||||
@ -85,6 +92,7 @@ The `authentication` object in `Hello` looks like this (example):
|
||||
```
|
||||
|
||||
To generate the authentication string, follow these steps:
|
||||
|
||||
- Concatenate the websocket password with the `salt` provided by the server (`password + salt`)
|
||||
- Generate an SHA256 binary hash of the result and base64 encode it, known as a base64 secret.
|
||||
- Concatenate the base64 secret with the `challenge` sent by the server (`base64_secret + challenge`)
|
||||
@ -92,39 +100,45 @@ To generate the authentication string, follow these steps:
|
||||
|
||||
For real-world examples of the `authentication` string creation, refer to the obs-websocket client libraries listed on the [README](README.md).
|
||||
|
||||
|
||||
## Message Types (OpCodes)
|
||||
The following message types are the low-level message types which may be sent to and from obs-websocket.
|
||||
|
||||
The following message types are the low-level message types which may be sent to and from obs-websocket.
|
||||
|
||||
Messages sent from the obs-websocket server or client may contain these first-level fields, known as the base object:
|
||||
```
|
||||
|
||||
```txt
|
||||
{
|
||||
"op": number,
|
||||
"d": object
|
||||
}
|
||||
```
|
||||
|
||||
- `op` is a `WebSocketOpCode` OpCode.
|
||||
- `d` is an object of the data fields associated with the operation.
|
||||
|
||||
---
|
||||
|
||||
### Hello (OpCode 0)
|
||||
|
||||
- Sent from: obs-websocket
|
||||
- Sent to: Freshly connected websocket client
|
||||
- Description: First message sent from the server immediately on client connection. Contains authentication information if auth is required. Also contains RPC version for version negotiation.
|
||||
|
||||
**Data Keys:**
|
||||
```
|
||||
|
||||
```txt
|
||||
{
|
||||
"obsWebSocketVersion": string,
|
||||
"rpcVersion": number,
|
||||
"authentication": object(optional)
|
||||
}
|
||||
```
|
||||
|
||||
- `rpcVersion` is a version number which gets incremented on each **breaking change** to the obs-websocket protocol. Its usage in this context is to provide the current rpc version that the server would like to use.
|
||||
|
||||
**Example Messages:**
|
||||
Authentication is required
|
||||
|
||||
```json
|
||||
{
|
||||
"op": 0,
|
||||
@ -140,6 +154,7 @@ Authentication is required
|
||||
```
|
||||
|
||||
Authentication is not required
|
||||
|
||||
```json
|
||||
{
|
||||
"op": 0,
|
||||
@ -153,22 +168,26 @@ Authentication is not required
|
||||
---
|
||||
|
||||
### Identify (OpCode 1)
|
||||
|
||||
- Sent from: Freshly connected websocket client
|
||||
- Sent to: obs-websocket
|
||||
- Description: Response to `Hello` message, should contain authentication string if authentication is required, along with PubSub subscriptions and other session parameters.
|
||||
|
||||
**Data Keys:**
|
||||
```
|
||||
|
||||
```txt
|
||||
{
|
||||
"rpcVersion": number,
|
||||
"authentication": string(optional),
|
||||
"eventSubscriptions": number(optional) = (EventSubscription::All)
|
||||
}
|
||||
```
|
||||
|
||||
- `rpcVersion` is the version number that the client would like the obs-websocket server to use.
|
||||
- `eventSubscriptions` is a bitmask of `EventSubscriptions` items to subscribe to events and event categories at will. By default, all event categories are subscribed, except for events marked as high volume. High volume events must be explicitly subscribed to.
|
||||
|
||||
**Example Message:**
|
||||
|
||||
```json
|
||||
{
|
||||
"op": 1,
|
||||
@ -183,19 +202,23 @@ Authentication is not required
|
||||
---
|
||||
|
||||
### Identified (OpCode 2)
|
||||
|
||||
- Sent from: obs-websocket
|
||||
- Sent to: Freshly identified client
|
||||
- Description: The identify request was received and validated, and the connection is now ready for normal operation.
|
||||
|
||||
**Data Keys:**
|
||||
```
|
||||
|
||||
```txt
|
||||
{
|
||||
"negotiatedRpcVersion": number
|
||||
}
|
||||
```
|
||||
|
||||
- If rpc version negotiation succeeds, the server determines the RPC version to be used and gives it to the client as `negotiatedRpcVersion`
|
||||
|
||||
**Example Message:**
|
||||
|
||||
```json
|
||||
{
|
||||
"op": 2,
|
||||
@ -208,36 +231,43 @@ Authentication is not required
|
||||
---
|
||||
|
||||
### Reidentify (OpCode 3)
|
||||
|
||||
- Sent from: Identified client
|
||||
- Sent to: obs-websocket
|
||||
- Description: Sent at any time after initial identification to update the provided session parameters.
|
||||
|
||||
**Data Keys:**
|
||||
```
|
||||
|
||||
```txt
|
||||
{
|
||||
"eventSubscriptions": number(optional) = (EventSubscription::All)
|
||||
}
|
||||
```
|
||||
|
||||
- Only the listed parameters may be changed after initial identification. To change a parameter not listed, you must reconnect to the obs-websocket server.
|
||||
|
||||
---
|
||||
|
||||
### Event (OpCode 5)
|
||||
|
||||
- Sent from: obs-websocket
|
||||
- Sent to: All subscribed and identified clients
|
||||
- Description: An event coming from OBS has occured. Eg scene switched, source muted.
|
||||
|
||||
**Data Keys:**
|
||||
```
|
||||
|
||||
```txt
|
||||
{
|
||||
"eventType": string,
|
||||
"eventIntent": number,
|
||||
"eventData": object(optional)
|
||||
}
|
||||
```
|
||||
|
||||
- `eventIntent` is the original intent required to be subscribed to in order to receive the event.
|
||||
|
||||
**Example Message:**
|
||||
|
||||
```json
|
||||
{
|
||||
"op": 5,
|
||||
@ -254,21 +284,24 @@ Authentication is not required
|
||||
---
|
||||
|
||||
### Request (OpCode 6)
|
||||
|
||||
- Sent from: Identified client
|
||||
- Sent to: obs-websocket
|
||||
- Description: Client is making a request to obs-websocket. Eg get current scene, create source.
|
||||
|
||||
**Data Keys:**
|
||||
```
|
||||
|
||||
```txt
|
||||
{
|
||||
"requestType": string,
|
||||
"requestId": string,
|
||||
"requestData": object(optional),
|
||||
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
**Example Message:**
|
||||
|
||||
```json
|
||||
{
|
||||
"op": 6,
|
||||
@ -285,12 +318,14 @@ Authentication is not required
|
||||
---
|
||||
|
||||
### RequestResponse (OpCode 7)
|
||||
|
||||
- Sent from: obs-websocket
|
||||
- Sent to: Identified client which made the request
|
||||
- Description: obs-websocket is responding to a request coming from a client.
|
||||
|
||||
**Data Keys:**
|
||||
```
|
||||
|
||||
```txt
|
||||
{
|
||||
"requestType": string,
|
||||
"requestId": string,
|
||||
@ -298,22 +333,26 @@ Authentication is not required
|
||||
"responseData": object(optional)
|
||||
}
|
||||
```
|
||||
|
||||
- The `requestType` and `requestId` are simply mirrors of what was sent by the client.
|
||||
|
||||
`requestStatus` object:
|
||||
```
|
||||
|
||||
```txt
|
||||
{
|
||||
"result": bool,
|
||||
"code": number,
|
||||
"comment": string(optional)
|
||||
}
|
||||
```
|
||||
|
||||
- `result` is `true` if the request resulted in `RequestStatus::Success`. False if otherwise.
|
||||
- `code` is a `RequestStatus` code.
|
||||
- `comment` may be provided by the server on errors to offer further details on why a request failed.
|
||||
|
||||
**Example Messages:**
|
||||
Successful Response
|
||||
|
||||
```json
|
||||
{
|
||||
"op": 7,
|
||||
@ -329,6 +368,7 @@ Successful Response
|
||||
```
|
||||
|
||||
Failure Response
|
||||
|
||||
```json
|
||||
{
|
||||
"op": 7,
|
||||
@ -347,12 +387,14 @@ Failure Response
|
||||
---
|
||||
|
||||
### RequestBatch (OpCode 8)
|
||||
|
||||
- Sent from: Identified client
|
||||
- Sent to: obs-websocket
|
||||
- Description: Client is making a batch of requests for obs-websocket. Requests are processed serially (in order) by the server.
|
||||
|
||||
**Data Keys:**
|
||||
```
|
||||
|
||||
```txt
|
||||
{
|
||||
"requestId": string,
|
||||
"haltOnFailure": bool(optional) = false,
|
||||
@ -360,18 +402,21 @@ Failure Response
|
||||
"requests": array<object>
|
||||
}
|
||||
```
|
||||
|
||||
- When `haltOnFailure` is `true`, the processing of requests will be halted on first failure. Returns only the processed requests in [`RequestBatchResponse`](#requestbatchresponse-opcode-9).
|
||||
- Requests in the `requests` array follow the same structure as the `Request` payload data format, however `requestId` is an optional field.
|
||||
|
||||
---
|
||||
|
||||
### RequestBatchResponse (OpCode 9)
|
||||
|
||||
- Sent from: obs-websocket
|
||||
- Sent to: Identified client which made the request
|
||||
- Description: obs-websocket is responding to a request batch coming from the client.
|
||||
|
||||
**Data Keys:**
|
||||
```
|
||||
|
||||
```txt
|
||||
{
|
||||
"requestId": string,
|
||||
"results": array<object>
|
||||
|
@ -1,3 +1,3 @@
|
||||
# Requests
|
||||
|
||||
### Requests Table of Contents
|
||||
## Requests Table of Contents
|
||||
|
@ -344,6 +344,7 @@ void EventHandler::HandleInputAudioTracksChanged(void *param, calldata_t *data)
|
||||
* The monitor type of an input has changed.
|
||||
*
|
||||
* Available types are:
|
||||
*
|
||||
* - `OBS_MONITORING_TYPE_NONE`
|
||||
* - `OBS_MONITORING_TYPE_MONITOR_ONLY`
|
||||
* - `OBS_MONITORING_TYPE_MONITOR_AND_OUTPUT`
|
||||
|
@ -672,6 +672,7 @@ RequestResult RequestHandler::SetInputAudioSyncOffset(const Request& request)
|
||||
* Gets the audio monitor type of an input.
|
||||
*
|
||||
* The available audio monitor types are:
|
||||
*
|
||||
* - `OBS_MONITORING_TYPE_NONE`
|
||||
* - `OBS_MONITORING_TYPE_MONITOR_ONLY`
|
||||
* - `OBS_MONITORING_TYPE_MONITOR_AND_OUTPUT`
|
||||
|
@ -29,6 +29,7 @@ bool IsMediaTimeValid(obs_source_t *input)
|
||||
* Gets the status of a media input.
|
||||
*
|
||||
* Media States:
|
||||
*
|
||||
* - `OBS_MEDIA_STATE_NONE`
|
||||
* - `OBS_MEDIA_STATE_PLAYING`
|
||||
* - `OBS_MEDIA_STATE_OPENING`
|
||||
|
Loading…
Reference in New Issue
Block a user