Javascript

The Javascript API for RTCBot is provided for simple interoperability of RTCBot and the browser. Wherever possible, the Javascript API mirrors the Python API, and can be used in exactly the same way.

Note

The Javascript API includes only a minimal subset of the functionality of RTCBot’s Python version. While this may change in the future, many of the functions available in Python can’t be used in javascript.

Basic Usage

To start using the Javascript API, all you need to do is include the RTCBot.js file in a script tag, and use the following javascript:

// The connection object
var conn = new rtcbot.RTCConnection();

// Here we set up the connection. We put it in an async function, since we will be
// waiting for results from the server (Promises).
async function connect() {
    // Get the information needed to connect from the server to the browser
    let offer = await conn.getLocalDescription();

    // POST the information to the server, which will respond with the corresponding remote
    // connection's description
    let response = await fetch("/connect", {
        method: "POST",
        cache: "no-cache",
        body: JSON.stringify(offer)
    });

    // Set the remote server's information
    await conn.setRemoteDescription(await response.json());
}

connect(); // Run the async function in the background.

Next, to establish the connection with Python, you include the Python counterpart:

from aiohttp import web
routes = web.RouteTableDef()

from rtcbot import RTCConnection, getRTCBotJS
conn= None

@routes.get("/") # Serve the html file
async def index(request):
    with open("index.html", "r") as f:
        return web.Response(content_type="text/html", text=f.read())

# Serve the RTCBot javascript library at /rtcbot.js
@routes.get("/rtcbot.js")
async def rtcbotjs(request):
    return web.Response(content_type="application/javascript", text=getRTCBotJS())


@routes.post("/connect")
async def connect(request):
    global conn
    clientOffer = await request.json()
    conn = RTCConnection()

    response = await conn.getLocalDescription(clientOffer)
    return web.json_response(response)


async def cleanup(app):
    if conn is not None:
        await conn.close()

app = web.Application()
app.add_routes(routes)
app.on_shutdown.append(cleanup)
web.run_app(app, port=8080)

Python API

rtcbot.javascript.getRTCBotJS()[source]

Returns the RTCBot javascript. This allows you to easily write self-contained scripts. You can serve it like this:

from rtcbot import getRTCBotJS
from aiohttp import web
routes = web.RouteTableDef()

@routes.get("/rtcbot.js")
async def rtcbotJS(request):
    return web.Response(content_type="application/javascript", text=getRTCBotJS())

app = web.Application()
app.add_routes(routes)
web.run_app(app, port=8000)

If you are writing a more complex application, you might want to bundle RTCBot’s javascript with your code using rollup or webpack instead of including it in script tags. To do this, you can install the js library separately with npm, and bundle it however you’d like:

npm i rtcbot

Javascript API

class RTCConnection(defaultOrdered=true, rtcConfiguration)

RTCConnection mirrors the Python RTCConnection in API. Whatever differences in functionality that may exist can be considered bugs unless explictly documented as such.

For detailed documentation, see the RTCConnection docs for Python.

Arguments:
  • defaultOrdered (*) –
  • rtcConfiguration (*) – is the configuration given to the RTC connection
RTCConnection.audio

The audio element allows you to directly access audio streams. The following functions are available:

  • subscribe(): Unlike in Python, this is given a callback which is called once, when the stream

is received.

conn.audio.subscribe(function(stream) {
  document.querySelector("audio").srcObject = stream;
});
  • putSubscription(): Allows to send a video stream:
let streams = await navigator.mediaDevices.getUserMedia({audio: true, video: false});
conn.audio.putSubscription(streams.getAudioTracks()[0]);
RTCConnection.close()

Close the connection

RTCConnection.getLocalDescription(description=null)

Sets up the connection. If no description is passed in, creates an initial description. If a description is given, creates a response to it.

Arguments:
  • description (*) – (optional)
RTCConnection.put_nowait(msg)

Send the given data over a data stream.

Arguments:
  • msg (*) – Message to send
RTCConnection.setRemoteDescription(description)

When initializing a connection, this response reads the remote response to an initial description.

Arguments:
  • description (*) –
RTCConnection.subscribe(s)

Subscribe to incoming messages. Unlike in the Python libary, which can accept a wide variety of inputs, the subscribe function in javascript only allows simple callbacks.

Arguments:
  • s (*) – A function to call each time a new message comes in
RTCConnection.video

Just like in the Python version, the video element allows you to directly access video streams. The following functions are available:

  • subscribe(): Unlike in Python, this is given a callback which is called once, when the stream

is received.

conn.video.subscribe(function(stream) {
  document.querySelector("video").srcObject = stream;
});
  • putSubscription(): Allows to send a video stream:
let streams = await navigator.mediaDevices.getUserMedia({audio: false, video: true});
conn.video.putSubscription(streams.getVideoTracks()[0]);
class Keyboard()

Keyboard subscribes to keypresses on the keyboard. Internally, the keydown and keyup events are used to get keys.

var kb = new rtcbot.Keyboard();
kb.subscribe(function(event) {
  console.log(event); // prints the button and joystick events
})
Keyboard.close()

Stop listening to keypresses

Keyboard.subscribe(s)

Subscribe to the events. Unlike in the Python libary, which can accept a wide variety of inputs, the subscribe function in javascript only allows simple callbacks.

Arguments:
  • s (*) – A function to call on each event
class Gamepad()

Gamepad allows you to use an Xbox controller. It uses the browser Gamepad API, polling at 10Hz by default. Use rtcbot.setGamepadRate to change polling frequency.

You must plug in the gamepad, and press a button on it for it to be recognized by the browser:

var gp = new rtcbot.Gamepad();
gp.subscribe(function(event) {
  console.log(event); // prints the button and joystick events
})
Gamepad.close()

Stop polling the gamepad.

Gamepad.subscribe(s)

Subscribe to the events. Unlike in the Python libary, which can accept a wide variety of inputs, the subscribe function in javascript only allows simple callbacks.

Arguments:
  • s (*) – A function to call on each event
setGamepadRate(rate)

Gamepads are polled at 10Hz by default, so that when moving joystick axes a connection is not immediately flooded with every miniscule joystick change. To modify this behavior, you can set the rate in Hz, allowing lower latency, with the downside of potentially lots of data suddenly overwhelming a connection.

Arguments:
  • rate (number) – Rate at which gamepad is polled in Hz
class Queue()

A simple async queue. Useful for converting callbacks into async operations. The API imitates Python’s asyncio.Queue, making it easy to avoid callback hell