Skip to main content
The official @rhombussystems/react package provides drop-in React components for streaming Rhombus cameras. Two player modes are available:
  • RhombusBufferedPlayer — MPEG-DASH live streaming via Dash.js (buffered, reliable)
  • RhombusRealtimePlayer — Low-latency H.264 over WebSocket via WebCodecs (near real-time)
Requires React 18+ and a backend endpoint that generates federated session tokens. Your Rhombus API key must never be exposed to the browser.

Install

npm install @rhombussystems/react
yarn add @rhombussystems/react
pnpm add @rhombussystems/react
Peer dependencies: react and react-dom >= 18. The dashjs library is included automatically for DASH playback.

Quick Start

import { RhombusBufferedPlayer } from "@rhombussystems/react";

export function CameraView() {
  return <RhombusBufferedPlayer cameraUuid="YOUR_CAMERA_UUID" />;
}
This renders a DASH-based buffered video player. The component automatically:
  1. Requests a federated session token from your backend (POST /api/federated-token)
  2. Fetches media URIs from the Rhombus API
  3. Initializes Dash.js playback
Your backend must implement a POST /api/federated-token endpoint (or configure a custom path via the paths.federatedToken prop). See Backend Setup below.

Buffered Player (DASH)

The RhombusBufferedPlayer streams MPEG-DASH live video with configurable quality levels.
import { RhombusBufferedPlayer } from "@rhombussystems/react";

export function BufferedCamera() {
  return (
    <RhombusBufferedPlayer
      cameraUuid="YOUR_CAMERA_UUID"
      bufferedStreamQuality="HIGH"
    />
  );
}

Stream Quality

Control server-side downscaling with the bufferedStreamQuality prop:
ValueDescription
"HIGH"Full resolution (default)
"MEDIUM"Medium downscale
"LOW"Low resolution, lowest bandwidth
Changing quality does not re-fetch the manifest or token — the Dash.js RequestModifier applies the change on the next segment request.
import { useState } from "react";
import {
  RhombusBufferedPlayer,
  type RhombusBufferedStreamQuality,
} from "@rhombussystems/react";

export function CameraWithQuality() {
  const [quality, setQuality] = useState<RhombusBufferedStreamQuality>("HIGH");

  return (
    <>
      <select
        value={quality}
        onChange={(e) => setQuality(e.target.value as RhombusBufferedStreamQuality)}
      >
        <option value="HIGH">High</option>
        <option value="MEDIUM">Medium</option>
        <option value="LOW">Low</option>
      </select>
      <RhombusBufferedPlayer
        cameraUuid="YOUR_CAMERA_UUID"
        bufferedStreamQuality={quality}
      />
    </>
  );
}

Realtime Player (WebSocket)

The RhombusRealtimePlayer decodes H.264 frames over WebSocket using the browser’s WebCodecs API and renders to a <canvas>. This provides lower latency than DASH.
import { RhombusRealtimePlayer } from "@rhombussystems/react";

export function RealtimeCamera() {
  return (
    <RhombusRealtimePlayer
      cameraUuid="YOUR_CAMERA_UUID"
      connectionMode="wan"
    />
  );
}

Connection Modes

ModeDescription
"wan"Uses the WAN H.264 WebSocket URI with federated token auth appended to the URL
"lan"Uses the LAN H.264 WebSocket URI. Federated token auth is appended to the URL the same way as WAN (x-auth-scheme=federated-token and x-auth-ft query parameters)

Stream Quality

ValueDescription
"HD"Full resolution (default)
"SD"Lower resolution via /wsl path — changing this prop reconnects the WebSocket
Browser compatibility: WebCodecs with H.264 decoding is supported in Chrome, Edge, and Safari 16.4+. Firefox support is limited.

LAN Mode Considerations

In LAN mode, the SDK appends the federated token to the WebSocket URL as query parameters (x-auth-scheme=federated-token and x-auth-ft), the same way it does for WAN. This works from any origin, including localhost. The practical requirement for LAN mode is network reachability: the browser must be able to reach the camera/NVR host directly (routing, firewall, and HTTPS-vs-HTTP mixed-content rules all apply). Your Rhombus deployment must also accept the federated-token query parameters on the LAN endpoint.
Earlier SDK versions (pre-1.0) authenticated LAN mode with an RFT cookie and an applyLanAuthCookie prop. That mechanism was removed in v1.0 — LAN now uses URL query parameters like WAN. If you are following an older guide, update your integration accordingly.

Backend Setup

The SDK requires a server-side endpoint to generate federated session tokens. Your Rhombus API key stays on the server — it is never sent to the browser.

Token Endpoint

Your backend must expose a POST endpoint (default path: /api/federated-token):
const express = require("express");
const app = express();
app.use(express.json());

app.post("/api/federated-token", async (req, res) => {
  const response = await fetch(
    "https://api2.rhombussystems.com/api/org/generateFederatedSessionToken",
    {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "x-auth-scheme": "api-token",
        "x-auth-apikey": process.env.RHOMBUS_API_KEY,
      },
      body: JSON.stringify({
        durationSec: req.body.durationSec || 3600,
        domain: req.headers.origin,
      }),
    }
  );
  const data = await response.json();
  res.json(data);
});
from fastapi import FastAPI, Request
import httpx, os

app = FastAPI()

@app.post("/api/federated-token")
async def federated_token(request: Request):
    body = await request.json()
    async with httpx.AsyncClient() as client:
        response = await client.post(
            "https://api2.rhombussystems.com/api/org/generateFederatedSessionToken",
            headers={
                "Content-Type": "application/json",
                "x-auth-scheme": "api-token",
                "x-auth-apikey": os.environ["RHOMBUS_API_KEY"],
            },
            json={
                "durationSec": body.get("durationSec", 3600),
                "domain": request.headers.get("origin", ""),
            },
        )
    return response.json()
// app/api/federated-token/route.ts
import { NextResponse } from "next/server";

export async function POST(request: Request) {
  const body = await request.json();
  const response = await fetch(
    "https://api2.rhombussystems.com/api/org/generateFederatedSessionToken",
    {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "x-auth-scheme": "api-token",
        "x-auth-apikey": process.env.RHOMBUS_API_KEY!,
      },
      body: JSON.stringify({
        durationSec: body.durationSec || 3600,
        domain: request.headers.get("origin") || "",
      }),
    }
  );
  const data = await response.json();
  return NextResponse.json(data);
}
The domain parameter in the token request must match your app’s origin. Without it, the browser will get CORS errors when fetching media URIs from api2.rhombussystems.com.

Override Mode (Proxy All Requests)

If you prefer to keep all Rhombus traffic server-side (the browser never talks to Rhombus directly), use apiOverrideBaseUrl:
<RhombusBufferedPlayer
  cameraUuid="YOUR_CAMERA_UUID"
  apiOverrideBaseUrl="https://your-api.example.com"
/>
In this mode, your backend must also expose a POST /api/media-uris endpoint that proxies to Rhombus’s POST /camera/getMediaUris.

Props Reference

Shared Props

PropTypeDefaultDescription
cameraUuidstringrequiredCamera UUID to stream
apiOverrideBaseUrlstringRoute both token and media requests through your server
rhombusApiBaseUrlstringhttps://api2.rhombussystems.com/apiRhombus API base URL (when not using override)
paths.federatedTokenstring/api/federated-tokenPath to your token endpoint
paths.mediaUrisstring/camera/getMediaUris or /api/media-urisPath for media URI resolution
federatedSessionTokenstringSkip token fetch; use this token directly
headersobjectExtra headers merged into the token request
getRequestHeaders() => objectDynamic headers for each request
onError(error: Error) => voidError callback

RhombusBufferedPlayer Props

PropTypeDefaultDescription
bufferedStreamQuality"HIGH" | "MEDIUM" | "LOW""HIGH"Server-side downscale level
applyBufferedStreamQualitybooleantrueSet false to disable quality parameter

RhombusRealtimePlayer Props

PropTypeDefaultDescription
connectionMode"wan" | "lan"requiredWAN or LAN media URIs; both append the token as URL query parameters
realtimeStreamQuality"HD" | "SD""HD"Stream resolution; changing reconnects the WebSocket

Troubleshooting

Your backend does not have a token endpoint at the expected path. Either implement POST /api/federated-token or set the paths.federatedToken prop to match your route.
The federated token was generated without a domain matching your app’s origin. Pass your app’s origin as the domain parameter when calling generateFederatedSessionToken on your backend.
Check browser compatibility — WebCodecs H.264 requires Chrome, Edge, or Safari 16.4+. Check the browser console for [RhombusRealtimePlayer] messages.
LAN mode appends the federated token to the WebSocket URL as query parameters (the same as WAN), so it works from any origin including localhost. If LAN mode fails, confirm the browser can reach the camera/NVR host directly (routing, firewall, and HTTPS-vs-HTTP mixed-content rules), and that your Rhombus deployment accepts federated-token query parameters on the LAN endpoint. If the LAN host is unreachable from the browser, use connectionMode="wan" or proxy through your backend.

Resources

npm Package

Package details and version history

GitHub Repository

Source code, examples, and issues

Streaming Video Guide

Low-level streaming implementation without the SDK

Video Player Guide

Custom Dash.js player implementation
Last modified on July 8, 2026