Skip to content

Latest commit

 

History

History
470 lines (362 loc) · 8.89 KB

rpc_protocol.md

File metadata and controls

470 lines (362 loc) · 8.89 KB

RPC Protocol

The RPC protocol is an encrypted JSON-RPC protocol.

Wire format and encryption

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.

  1. A JSON string is produced containing the JSON-RPC message
  2. This string is converted to UTF-8, with no leading or trailing whitespace, and no trailing null byte.
  3. The resulting blob is encrypted using crypto_secretstream_xchacha20poly1305_push()
  4. The receiving end decrypts the blob using crypto_secretstream_xchacha20poly1305_pull() and decodes the JSON

Overview of JSON-RPC

See the full specification for details.

JSON-RPC provides 3 main kinds of message:

  • requests
  • responses
  • notifications

Requests

A request has the form:

{
  "jsonrpc" : "2.0",
  "id" : string|int|null, // generated by requestor
  "method" : string,
  "params" ?: array|object, // method-specific
}

Responses

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

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
}

Types

OutputType

OutputType = "unknown" | "local_recording" | "local_stream" | "remote_stream"

NDI is an example of a local stream.

OutputState

OutputState = "unknown" | "starting" | "active" | "stopping" | "stopped"

Output

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

Scene = {
  id: string,
  name: string,
  active: bool,
}

Server-To-Client Notifications

hello

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"
}

outputs/stateChanged

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 output
  • state: OutputState: the new state of the output

Example:

{
  "jsonrpc": "2.0",
  "method": "outputs/stateChanged",
  "params": {
    "id": "twitch://fredemmott",
    "state": "starting"
  }
}

scenes/currentSceneChanged

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"
  }
}

Client-To-Server Requests

outputs/get

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"
    }
  }
}

outputs/start

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.

outputs/stop

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.

outputs/setDelay

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

scenes/get

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

scenes/activate

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"
  }
}

scenes/getThumbnail

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"
  }
}