The RPC protocol is an encrypted JSON-RPC protocol.
Once the handshake protocol is complete, both the client and server have state objects for both client-to-server and server-to-client message encryption.
- A JSON string is produced containing the JSON-RPC message
- This string is converted to UTF-8, with no leading or trailing whitespace, and no trailing null byte.
- The resulting blob is encrypted using
crypto_secretstream_xchacha20poly1305_push()
- The receiving end decrypts the blob using
crypto_secretstream_xchacha20poly1305_pull()
and decodes the JSON
See the full specification for details.
JSON-RPC provides 3 main kinds of message:
- requests
- responses
- notifications
A request has the form:
{
"jsonrpc" : "2.0",
"id" : string|int|null, // generated by requestor
"method" : string,
"params" ?: array|object, // method-specific
}
A request has the form:
{
"jsonrpc" : "2.0",
"id" : (string|int|null), // matches request
"result" ?: mixed, // method-specific
"error" ?: {
"code" : int,
"message" : string,
"data" ?: mixed, // method-specific
},
}
- Either result or error will be set
- result must be set on success and unset on error
- error must be set on error and unset on success
Notifications are like commands, but do not have an ID, and no response is expected.
{
"jsonrpc": "2.0",
"method": string,
"params" ?: array|object, // method-specific
}
OutputType = "unknown" | "local_recording" | "local_stream" | "remote_stream"
NDI is an example of a local stream.
OutputState = "unknown" | "starting" | "active" | "stopping" | "stopped"
Output = {
id: string,
name: string,
type: OutputType,
state: OutputState,
delaySeconds ?: int,
}
The 'id' is an opaque string to uniquely identify the output. The name
is suitable for displaying to the end user.
If delaySeconds
is 0, there is no delay. If delaySeconds
is negative or absent,
delay is not supported. Implementations should omit delaySeconds
for outputs
where it is not supported.
Scene = {
id: string,
name: string,
active: bool,
}
This notification is sent by the server as soon as the handshake protocol is complete. No response is required - however
clients are likely to want to make requests such as outputs/get
after receiving this.
This notification has no parameters.
Example:
{
"jsonrpc": "2.0",
"method": "hello"
}
This notification is sent by the server when the state of an output changes.
This notification has two parameters:
id: string
: the ID of the outputstate: OutputState
: the new state of the output
Example:
{
"jsonrpc": "2.0",
"method": "outputs/stateChanged",
"params": {
"id": "twitch://fredemmott",
"state": "starting"
}
}
This notification is sent by the server when the current scene is changed.
This notification has one parameter:
id: string
: the ID of the new scene
Example:
{
"jsonrpc": "2.0",
"method": "scenes/currentSceneChanged",
"params": {
"id": "aaaaa-bb-cc-ddd"
}
}
The client invokes this method when it wants information on the available outputs.
This method has no parameters.
This method returns a map from output ID to Output
objects.
Example request:
{
"jsonrpc": "2.0",
"method": "outputs/get",
"id": 1
}
Example response:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"recording": {
"id": "recording",
"name': "Local Recording",
"type": "local_recording",
"state": "active"
},
"twitch://fredemmott" {
"id": "twitch://fredemmott",
"name": "Twitch",
"type": "remote_stream",
"state": "stopped",
"delaySeconds": 0
},
"ndi" {
"id": "ndi",
"name": "NDI Broadcast",
"type": "local_stream",
"state": "starting"
}
}
}
This method is sent by the client when it wants to start an output (recording or stream).
This method takes { id: string }
for its' parameters.
Success indicates that the software was asked to start the output - however, this can take some time,
so clients should not consider the state of the output to have changed until they receive an outputs/stateChanged
notification.
Example request:
{
"jsonrpc": "2.0",
"method": "outputs/start",
"id": "startTwitch/1",
"params": { "id": "twitch://fredemmott" }
}
Example response and notifications:
{
"jsonrpc": "2.0",
"id": "startTwitch/1",
"result": {}
}
{
"jsonrpc": "2.0",
"method": "outputs/stateChanged",
"params": {
"id": "twitch://fredemmott",
"state": "starting"
}
}
{
"jsonrpc": "2.0",
"method": "outputs/stateChanged",
"params": {
"id": "twitch://fredemmott",
"state": "active"
}
}
There is likely to be a significant amount of time between receiving success and receiving the notifications.
This method is sent by the client when it wants to stop an output (recording or stream).
This method takes { id: string }
for its' parameters.
Success indicates that the software was asked to stop the output - however, this can take some time,
so clients should not consider the state of the output to have changed until they receive an outputs/stateChanged
notification.
Example request:
{
"jsonrpc": "2.0",
"method": "outputs/stop",
"id": "stopTwitch/1",
"params": { "id": "twitch://fredemmott" }
}
Example response and notifications:
{
"jsonrpc": "2.0",
"id": "stopTwitch/1",
"result": {}
}
{
"jsonrpc": "2.0",
"method": "outputs/stateChanged",
"params": {
"id": "twitch://fredemmott",
"state": "stopping"
}
}
{
"jsonrpc": "2.0",
"method": "outputs/stateChanged",
"params": {
"id": "twitch://fredemmott",
"state": "stopped"
}
}
There is likely to be a significant amount of time between receiving success and receiving the notifications.
This method is sent by the client when it wants to set a delay on an output.
This method takes { id: string; seconds: int}
for its' parameters. If 0, the
delay is disabled.
Clients should not send this message unless the output is stopped.
Example request:
{
"jsonrpc": "2.0",
"method": "outputs/setDelay",
"id": "setDelay/1",
"params": { "id": "twitch://fredemmott", "seconds": 300 }
}
Example response:
{
"jsonrpc": "2.0",
"id": "setDelay/1",
"result": { "seconds": 300 }
}
The client invokes this method when it wants information on the available scenes.
This method has no parameters.
This method returns a map from scene ID to Scene
objects.
Example request:
{
"jsonrpc": "2.0",
"method": "scenes/get",
"id": 1
}
Example response:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"scene123": {
"id": "scene123",
"name": "Game",
"active": true
},
"scene456": {
"id": "scene456",
"name": "On a Break",
"active": false
}
}
This method is sent by the client when it wants to switch scenes.
This method takes { id: string }
for its' parameters.
Success indicates the scene is available and not currently active, and the
streaming software (e.g. OBS, XSplit) has been asked to start the transition,
however it is not necessarily the new active scene until a
scenes/currentSceneChanged
notification is received.
Example request:
{
"jsonrpc": "2.0",
"method": "scenes/activate",
"id": "select-taking-a-break",
"params": { "id": "scene1234" }
}
Example response and notifications:
{
"jsonrpc": "2.0",
"id": "select-taking-a-break",
"result": {}
}
{
"jsonrpc": "2.0",
"method": "scenes/currentSceneChanged",
"params": {
"id": "scene1234"
}
}
This method is sent by the client when it wants a screenshot of a scene.
This method takes { id: string, content_type: string }
for its' parameters.
This method returns the content type and base64-encoded data.
Servers should support image/png
as a content type.
Note that screenshotting a scene that is not currently active might produce an image that is not particularly useful if the elements of that scene are not in use in an active scene.
Example request:
{
"jsonrpc": "2.0",
"method": "scenes/getThumbnail",
"id": 1,
"params": {
"id": "scene1234",
"content_type": "image/png"
}
}
Example response:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"id": "scene1234",
"base64_data": "abcdef",
"content_type": "image/png"
}
}