Skip to main content
Cyberwave exposes an active camera stream as a WebRTC SFU consumer connection. Use the Python SDK unless you need to render the stream in your own browser or native client. There is no anonymous stream URL, HLS playlist, RTSP output, or WHEP endpoint. Install the camera dependencies and authenticate with a Cyberwave API token:
get_video() joins the existing SFU room as a receive-only consumer. It does not replace the producer or interrupt other viewers. It raises NoOngoingVideoStreamAvailable when the selected twin or sensor has no active producer. For an executable smoke test and inline viewer, open the live_video.ipynb Colab notebook.

Custom browser or native client

Custom clients use MQTT for WebRTC signaling and WebRTC for media:

Requirements

  • Connect to the MQTT endpoint for the deployment. Production browser clients use wss://mqtt.cyberwave.com; native clients can use MQTT over TLS on port 8883.
  • For API-token authentication, use the token as the MQTT password and your own Cyberwave username as the MQTT username — the username field from GET /api/v1/users/@me/status/, not your email address. A per-user session credential must be paired with its corresponding username.
  • The token’s principal must be able to read and write the twin. Subscribing to the answer topic requires read access; publishing the offer currently requires write access.
  • Use the deployment’s topic prefix outside production, if one is configured.
  • Supply a working STUN/TURN configuration. Contact Cyberwave for the current ICE configuration instead of embedding shared credentials in an application.
Do not put an API token in public frontend source or ship it to untrusted browsers. A browser integration should authenticate each user and use that user’s MQTT credential. Keep workspace API tokens in a trusted native or backend client.

Signaling topics

For a production twin UUID of abc, use: Subscribe to the answer topic before publishing the offer. Both topics are shared by every consumer of the twin, so generate a unique session_id and ignore messages for other sessions. The consumer offer payload is:
Use sender: "frontend" for a custom browser/native consumer. The media service also recognizes client_python_sdk, which is reserved for the SDK consumer. When selecting a simulation or another non-default stream, also include its stream_source and stream_instance_id. The answer topic can return:
  • type: "answer" with an SDP answer: call setRemoteDescription().
  • type: "wait": no matching producer is registered yet; retry with a new peer connection after a short delay.
  • type: "error": negotiation failed; surface the included message or error value.

Browser outline

The following omits application-specific credential delivery, reconnect logic, and SDP normalization, but shows the required ordering and message filtering:

Codec compatibility

Cyberwave’s SFU uses pinned RTP payload types. A browser must advertise the same payload numbers in its local offer; an SDP answer cannot safely redefine them. This matters in particular for recent Chrome versions. Before setLocalDescription(), normalize the video section to the SFU table: The canonical implementation is normalizeVideoOfferSdp. Keep a vendored implementation in sync with that file and the media-service router. If maintaining this protocol is undesirable, use get_video() from the Python SDK instead.

Cleanup

Close all three resources when the viewer exits:
For production integrations, also handle MQTT reconnects, WebRTC connection failure, stalled-frame detection, and a signaling-answer timeout.