Herramientas y SDK
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
- Instalación
- Inicio rápido
- Reproductor con búfer (DASH)
- Calidad de la transmisión
- Reproductor en tiempo real (WebSocket)
- Modos de conexión
- Calidad de la transmisión
- Consideraciones del modo LAN
- Configuración del backend
- Endpoint del token
- Modo de anulación (proxy de todas las solicitudes)
- Referencia de props
- Props compartidas
- Props de RhombusBufferedPlayer
- Props de RhombusRealtimePlayer
- Solución de problemas
- Recursos
Esta página se tradujo automáticamente. Si encuentras errores o tienes sugerencias, escríbenos.
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)
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
npm install @rhombussystems/reactyarn add @rhombussystems/reactpnpm add @rhombussystems/reactDependencias de pares (peer dependencies): react y react-dom >= 18. La biblioteca dashjs se incluye automáticamente para la reproducción DASH.
Inicio rápido
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:
- Solicita un token de sesión federado a tu backend (
POST /api/federated-token) - Obtiene los URIs de medios desde la API de Rhombus
- Inicializa la reproducción con Dash.js
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.
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:
| Valor | Descripció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.
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.
import { RhombusRealtimePlayer } from "@rhombussystems/react";
export function RealtimeCamera() {
return (
<RhombusRealtimePlayer
cameraUuid="YOUR_CAMERA_UUID"
connectionMode="wan"
/>
);
}Modos de conexión
| Modo | Descripció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
| Valor | Descripción |
|---|---|
"HD" | Resolución completa (predeterminado) |
"SD" | Menor resolución mediante la ruta /wsl: cambiar esta prop reconecta el WebSocket |
Compatibilidad de navegadores: WebCodecs con decodificación H.264 es compatible con Chrome, Edge y Safari 16.4+. La compatibilidad con Firefox es limitada.
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.
El SDK 1.0 y posteriores autentican el modo LAN con parámetros de consulta en la URL, igual que WAN. La cookie RFT y la prop applyLanAuthCookie de las versiones previas a la 1.0 no forman parte del SDK; si una guía más antigua las usa, actualiza el SDK y elimínalas.
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):
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());
});from fastapi import FastAPI, Request
import httpx, os
app = FastAPI()
# The exact origin your pages are served from, such as https://app.example.com
APP_ORIGIN = os.environ["APP_ORIGIN"]
@app.post("/api/federated-token")
async def federated_token(request: Request):
body = await request.json()
# At most 24 hours; 1 hour if the request doesn't say
duration_sec = min(int(body.get("durationSec") or 3600), 86400)
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": duration_sec, "domain": APP_ORIGIN},
)
response.raise_for_status()
# Return the whole response: the SDK reads expiresAtMs and renews the token before it expires
return response.json()// app/api/federated-token/route.ts
import { NextResponse } from "next/server";
// The exact origin your pages are served from, such as https://app.example.com
const APP_ORIGIN = process.env.APP_ORIGIN!;
export async function POST(request: Request) {
const body = await request.json();
// At most 24 hours; 1 hour if the request doesn't say
const durationSec = Math.min(Number(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 NextResponse.json({ error: "Could not mint a token" }, { status: 502 });
// Return the whole response: the SDK reads expiresAtMs and renews the token before it expires
return NextResponse.json(await response.json());
}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:
<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
| Prop | Tipo | Predeterminado | Descripción |
|---|---|---|---|
cameraUuid | string | requerido | UUID de la cámara a transmitir |
apiOverrideBaseUrl | string | — | Enruta tanto las solicitudes de token como las de medios a través de tu servidor |
rhombusApiBaseUrl | string | https://api2.rhombussystems.com/ | URL base de la API de Rhombus (cuando no se usa la anulación) |
paths.federatedToken | string | /api/ | Ruta a tu endpoint de token |
paths.mediaUris | string | /camera/ o /api/ | Ruta para la resolución de URIs de medios |
federatedSessionToken | string | — | Omite la obtención del token; usa este token directamente |
tokenDurationSec | number | 86400 | Duración del token, en segundos, que el SDK solicita a tu endpoint de token; 86400 como máximo |
headers | object | — | Encabezados adicionales fusionados en la solicitud del token |
getRequestHeaders | () | — | Encabezados dinámicos para cada solicitud |
onError | (error: | — | Callback de error |
Props de RhombusBufferedPlayer
| Prop | Tipo | Predeterminado | Descripción |
|---|---|---|---|
bufferedStreamQuality | "HIGH" | "MEDIUM" | "LOW" | "HIGH" | Nivel de reescalado del lado del servidor |
applyBufferedStreamQuality | boolean | true | Establece false para deshabilitar el parámetro de calidad |
Props de RhombusRealtimePlayer
| Prop | Tipo | Predeterminado | Descripción |
|---|---|---|---|
connectionMode | "wan" | "lan" | requerido | URIs 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
Detalles del paquete e historial de versiones
Código fuente, ejemplos y problemas
Implementación de transmisión de bajo nivel sin el SDK
Implementación de un reproductor Dash.js personalizado