Ir al contenido

React SDK

Integra transmisiones de cámaras de Rhombus en aplicaciones React con el SDK oficial, que ofrece reproducción con búfer DASH y reproductores H.264 en tiempo real por WebSocket mediante WebCodecs.

En esta página

El paquete oficial @rhombussystems/react ofrece componentes React listos para usar que transmiten cámaras de Rhombus. Hay dos modos de reproductor disponibles:

  • RhombusBufferedPlayer — Transmisión en vivo MPEG-DASH mediante Dash.js (con búfer, confiable)
  • RhombusRealtimePlayer — H.264 de baja latencia por WebSocket mediante WebCodecs (casi en tiempo real)
Información

Requiere React 18+ y un endpoint de backend que genere tokens de sesión federados. Tu clave de API de Rhombus nunca debe exponerse al navegador.

Instalación

bash
npm install @rhombussystems/react

Dependencias de pares (peer dependencies): react y react-dom >= 18. La biblioteca dashjs se incluye automáticamente para la reproducción DASH.

Inicio rápido

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

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

Esto renderiza un reproductor de video con búfer basado en DASH. El componente automáticamente:

  1. Solicita un token de sesión federado a tu backend (POST /api/federated-token)
  2. Obtiene los URIs de medios desde la API de Rhombus
  3. Inicializa la reproducción con Dash.js
Advertencia

Tu backend debe implementar un endpoint POST /api/federated-token (o configurar una ruta personalizada mediante la prop paths.federatedToken). Consulta Configuración del backend más abajo.

Reproductor con búfer (DASH)

El RhombusBufferedPlayer transmite video en vivo MPEG-DASH con niveles de calidad configurables.

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

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

Calidad de la transmisión

Controla el reescalado del lado del servidor con la prop bufferedStreamQuality:

ValorDescripción
"HIGH"Resolución completa (predeterminado)
"MEDIUM"Reescalado medio
"LOW"Baja resolución, menor ancho de banda

Cambiar la calidad no vuelve a obtener el manifiesto ni el token: el RequestModifier de Dash.js aplica el cambio en la siguiente solicitud de segmento.

tsx
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}
      />
    </>
  );
}

Reproductor en tiempo real (WebSocket)

El RhombusRealtimePlayer decodifica fotogramas H.264 por WebSocket usando la API WebCodecs del navegador y los renderiza en un <canvas>. Esto ofrece menor latencia que DASH.

tsx
import { RhombusRealtimePlayer } from "@rhombussystems/react";

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

Modos de conexión

ModoDescripción
"wan"Usa el URI WebSocket H.264 por WAN con la autenticación de token federado añadida a la URL
"lan"Usa el URI WebSocket H.264 por LAN. La autenticación de token federado se añade a la URL igual que en WAN (parámetros de consulta x-auth-scheme=federated-token y x-auth-ft)

Calidad de la transmisión

ValorDescripción
"HD"Resolución completa (predeterminado)
"SD"Menor resolución mediante la ruta /wsl: cambiar esta prop reconecta el WebSocket

Consideraciones del modo LAN

En modo LAN, el SDK añade el token federado a la URL del WebSocket como parámetros de consulta (x-auth-scheme=federated-token y x-auth-ft), de la misma forma que en WAN. Esto funciona desde cualquier origen, incluido localhost.

El requisito práctico del modo LAN es la accesibilidad de red: el navegador debe poder alcanzar directamente el host de la cámara/NVR (se aplican reglas de enrutamiento, firewall y de contenido mixto HTTPS-vs-HTTP). Consulta Streaming por LAN para ver cómo funciona la autenticación LAN y por qué los dispositivos solo aceptan tokens federados.

Configuración del backend

El SDK requiere un endpoint del lado del servidor para generar tokens de sesión federados. Tu clave de API de Rhombus permanece en el servidor: nunca se envía al navegador.

Endpoint del token

Tu backend debe exponer un endpoint POST (ruta predeterminada: /api/federated-token):

javascript
const express = require("express");
const app = express();
app.use(express.json());

// The exact origin your pages are served from, such as https://app.example.com
const APP_ORIGIN = process.env.APP_ORIGIN;

app.post("/api/federated-token", async (req, res) => {
  // At most 24 hours; 1 hour if the request doesn't say
  const durationSec = Math.min(Number(req.body.durationSec) || 3600, 86400);
  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, domain: APP_ORIGIN }),
    }
  );
  if (!response.ok) return res.status(502).json({ error: "Could not mint a token" });
  // Return the whole response: the SDK reads expiresAtMs and renews the token before it expires
  res.json(await response.json());
});
Advertencia

Establece domain con el origen exacto de tu aplicación: un origen absoluto con esquema, host y cualquier puerto no predeterminado, y sin ruta, como https://app.example.com (o http://localhost:5173 en desarrollo). El navegador solicita los URIs de medios directamente a api2.rhombussystems.com, y sin un domain que coincida con el origen de tu aplicación esas solicitudes fallan con errores de CORS. Rhombus acepta un token con domain solo en solicitudes cuyo Origin (o, si no hay, Referer) coincide con él, y responde a cualquier otra con 403 DOMAIN_NOT_ALLOWED. Un valor que no es un origen absoluto hace fallar la generación con 400.

El SDK le pide a tu endpoint una duración (tokenDurationSec, 86400 de forma predeterminada) y obtiene un token nuevo poco antes del expiresAtMs que devuelve tu endpoint, así que devuelve la respuesta de generación sin cambios. Rhombus limita los tokens federados a 24 horas y usa una hora cuando se omite durationSec.

Modo de anulación (proxy de todas las solicitudes)

Si prefieres mantener todo el tráfico de Rhombus en el lado del servidor (el navegador nunca se comunica directamente con Rhombus), usa apiOverrideBaseUrl:

tsx
<RhombusBufferedPlayer
  cameraUuid="YOUR_CAMERA_UUID"
  apiOverrideBaseUrl="https://your-api.example.com"
/>

En este modo, tu backend también debe exponer un endpoint POST /api/media-uris que actúe como proxy hacia el POST /camera/getMediaUris de Rhombus.

Referencia de props

Props compartidas

PropTipoPredeterminadoDescripción
cameraUuidstringrequeridoUUID de la cámara a transmitir
apiOverrideBaseUrlstring—Enruta tanto las solicitudes de token como las de medios a través de tu servidor
rhombusApiBaseUrlstringhttps://api2.rhombussystems.com/apiURL base de la API de Rhombus (cuando no se usa la anulación)
paths.federatedTokenstring/api/federated-tokenRuta a tu endpoint de token
paths.mediaUrisstring/camera/getMediaUris o /api/media-urisRuta para la resolución de URIs de medios
federatedSessionTokenstring—Omite la obtención del token; usa este token directamente
tokenDurationSecnumber86400Duración del token, en segundos, que el SDK solicita a tu endpoint de token; 86400 como máximo
headersobject—Encabezados adicionales fusionados en la solicitud del token
getRequestHeaders() => object—Encabezados dinámicos para cada solicitud
onError(error: Error) => void—Callback de error

Props de RhombusBufferedPlayer

PropTipoPredeterminadoDescripción
bufferedStreamQuality"HIGH" | "MEDIUM" | "LOW""HIGH"Nivel de reescalado del lado del servidor
applyBufferedStreamQualitybooleantrueEstablece false para deshabilitar el parámetro de calidad

Props de RhombusRealtimePlayer

PropTipoPredeterminadoDescripción
connectionMode"wan" | "lan"requeridoURIs de medios WAN o LAN; ambos añaden el token como parámetros de consulta en la URL
realtimeStreamQuality"HD" | "SD""HD"Resolución de la transmisión; cambiarla reconecta el WebSocket

Solución de problemas

404 en /api/federated-token

Tu backend no tiene un endpoint de token en la ruta esperada. Implementa POST /api/federated-token o establece la prop paths.federatedToken para que coincida con tu ruta.

Errores de CORS al solicitar los URIs de medios

El token federado se generó sin un domain que coincida con el origen de tu aplicación. Pasa el origen exacto de tu aplicación (como https://app.example.com) como el parámetro domain al llamar a generateFederatedSessionToken en tu backend.

403 DOMAIN_NOT_ALLOWED, o 401 después de que la página lleva un rato abierta

Un 403 DOMAIN_NOT_ALLOWED significa que el origen de la página no es el domain del token (revisa esquema, host y puerto). Un 401 significa que el token expiró o fue revocado: asegúrate de que tu endpoint devuelva expiresAtMs para que el SDK renueve el token a tiempo.

El reproductor en tiempo real no muestra nada

Verifica la compatibilidad del navegador: WebCodecs H.264 requiere Chrome, Edge o Safari 16.4+. Revisa la consola del navegador en busca de mensajes [RhombusRealtimePlayer].

El modo LAN no autentica

El modo LAN añade el token federado a la URL del WebSocket como parámetros de consulta (igual que WAN), por lo que funciona desde cualquier origen, incluido localhost. Si el modo LAN falla, confirma que el navegador puede alcanzar directamente el host de la cámara/NVR (enrutamiento, firewall y reglas de contenido mixto HTTPS-vs-HTTP). Si el host LAN no es accesible desde el navegador, usa connectionMode="wan" o redirige el tráfico a través de tu backend.

Recursos