> ## Índice de la documentación
> Consulta el índice completo de la documentación en: https://developer.rhombus.com/llms.txt
> Úsalo para descubrir todas las páginas disponibles antes de seguir explorando.

# Mostrar cámaras en tu aplicación

> Muestra miniaturas y video en vivo de las cámaras de Rhombus en tu propia app web o móvil: lista las cámaras en tu servidor, genera tokens federados de corta duración para cada usuario, carga instantáneas y reproduce video en vivo con el SDK de React o un reproductor HLS.

> **Note**: Esta página se tradujo automáticamente. Si encuentras errores o tienes sugerencias, [escríbenos](mailto:support@rhombus.com).

Esta guía agrega un muro de cámaras a tu aplicación: una cuadrícula de miniaturas actuales y video en vivo cuando un usuario abre una cámara. Tu clave de API nunca sale de tu servidor; el navegador o la app reciben [tokens federados](https://developer.rhombus.com/es/authentication/federated-tokens) de corta duración, limitados a las cámaras que elijas.

```mermaid
sequenceDiagram
    participant U as Tu app (navegador o móvil)
    participant B as Tu backend
    participant R as Rhombus
    U->>B: Lista mis cámaras (tu propia autenticación)
    B->>R: getMinimalCameraStateList (clave de API)
    B-->>U: Cámaras que este usuario puede ver
    U->>B: Token para la cámara X
    B->>R: generateFederatedSessionToken (deviceUUid = X)
    B-->>U: Token de corta duración
    U->>R: Instantánea y video en vivo con el token
```

## 1. Lista las cámaras en tu servidor

Llama a [`getMinimalCameraStateList`](https://developer.rhombus.com/api-reference/camera-webservice/get-minimal-camera-state-list) con tu clave de API. Conserva `uuid`, `name`, `locationUuid`, `mediaRegion` y `connectionStatus` de cada cámara y luego **filtra la lista con tus propias reglas** antes de devolverla: tus usuarios no son usuarios de Rhombus, así que solo tu backend sabe qué cámaras puede ver cada uno.

Usa una clave cuyo rol cubra solo las ubicaciones que atiende tu app, con acceso a dispositivos solo en vivo o de solo lectura; cada token que generes lo hereda ([Permisos](https://developer.rhombus.com/es/authentication/permissions#privilegio-mínimo)).

## 2. Genera un token por usuario y cámara

Cuando un usuario abre una cámara, tu backend comprueba que puede verla y genera un token limitado a esa cámara con [`generateFederatedSessionToken`](https://developer.rhombus.com/api-reference/org-webservice/generate-federated-session-token):

```javascript Node.js (Express)
// El origen exacto de tu app web. Omite domain en las apps nativas (ver abajo).
const APP_ORIGIN = "https://app.example.com";

app.post("/api/cameras/:uuid/token", requireUser, async (req, res) => {
  if (!userCanSeeCamera(req.user, req.params.uuid)) return res.sendStatus(403);
  const r = await fetch("https://api2.rhombussystems.com/api/org/generateFederatedSessionToken", {
    method: "POST",
    headers: {
      "x-auth-scheme": "api-token",
      "x-auth-apikey": process.env.RHOMBUS_API_KEY,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ durationSec: 900, deviceUUid: req.params.uuid, domain: APP_ORIGIN }),
  });
  if (!r.ok) return res.sendStatus(502);
  const { federatedSessionToken, expiresAtMs } = await r.json();
  // Guarda el token para revocarlo cuando el usuario cierre sesión (paso 5)
  (req.session.rhombusTokens ??= []).push(federatedSessionToken);
  res.json({ token: federatedSessionToken, expiresAtMs });
});
```

Mantén los tokens cortos (minutos, no días; nunca más de 24 horas), limitados con `deviceUUid`, y renuévalos antes del `expiresAtMs` de la respuesta de generación.

En una app web, establece `domain` con el origen exacto de tu app, un origen absoluto como `https://app.example.com`. Rhombus acepta entonces el token solo en solicitudes cuyo `Origin` (o, cuando no lo hay, `Referer`) es ese origen, y responde a cualquier otra con 403 `DOMAIN_NOT_ALLOWED`, así que un token copiado de tu página no funciona en otro sitio. Las solicitudes de imágenes no llevan `Origin`, así que dependen del `Referer`: no uses `Referrer-Policy: no-referrer` en las páginas que muestran imágenes de cámaras. Omite `domain` en las apps móviles nativas, que no envían ninguno de los dos encabezados. [El campo domain](https://developer.rhombus.com/es/authentication/federated-tokens#el-campo-domain) tiene los detalles.

## 3. Muestra miniaturas

La instantánea más reciente de una cámara es una URL de imagen normal, así que una etiqueta `<img>` puede cargarla con el token en la cadena de consulta:

```html
<img
  alt="Loading dock"
  src="https://media.rhombussystems.com/media/CAMERA_UUID/MEDIA_REGION/snapshot.jpeg?x-auth-scheme=federated-token&x-auth-ft=TOKEN"
/>
```

`MEDIA_REGION` es el `mediaRegion` de la cámara del paso 1. Actualiza las miniaturas como mucho cada pocos segundos, y solo las de las cámaras visibles en pantalla. Una cuadrícula de muchas cámaras puede generar un token por cámara, o un solo token sin `deviceUUid` que cubra todas las cámaras que el rol de la clave puede ver; el token por cámara limita lo que expone un token filtrado.

## 4. Reproduce video en vivo

Elige el reproductor que encaje con tu app:

| App                  | Reproductor                                                                                                      | Guía                                                                                                    |
| -------------------- | ---------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
| App web con React    | El SDK de React de Rhombus: pásale una función que pida un token a tu backend, y renueva los tokens por sí mismo | [SDK de React](https://developer.rhombus.com/es/implementations/react-sdk)                              |
| Otra app web         | hls.js, o el reproductor nativo de Safari, sobre `wanLiveM3u8Uri` con el token agregado                          | [Medios y transmisiones: HLS](https://developer.rhombus.com/es/authentication/media#hls)                |
| iOS o Android nativo | AVPlayer o ExoPlayer sobre la misma URL HLS                                                                      | [Medios y transmisiones](https://developer.rhombus.com/es/authentication/media#video-en-vivo-y-grabado) |

Tu backend obtiene las URLs de transmisión con [`getMediaUris`](https://developer.rhombus.com/api-reference/camera-webservice/get-camera-media-uris) para la cámara y se las pasa a la app junto con el token. El video grabado usa las mismas URLs con una hora de inicio y una duración; consulta [Streaming de video](https://developer.rhombus.com/es/implementations/streaming-video).

## 5. Revoca los tokens cuando el usuario cierre sesión

Un token deja de funcionar en su `expiresAtMs`, o antes si lo revocas o eliminas la clave de API que lo generó. Cuando un usuario cierre sesión en tu app, revoca los tokens que generaste para su sesión con `POST /api/org/revokeFederatedSessionToken`. Surte efecto en 60 segundos o menos, un socket de video en vivo abierto que use el token se cierra con el código `1008`, y la llamada devuelve 200 tanto si el token seguía existiendo como si no:

```javascript Node.js (Express)
app.post("/logout", requireUser, async (req, res) => {
  for (const token of req.session.rhombusTokens ?? []) {
    await fetch("https://api2.rhombussystems.com/api/org/revokeFederatedSessionToken", {
      method: "POST",
      headers: {
        "x-auth-scheme": "api-token",
        "x-auth-apikey": process.env.RHOMBUS_API_KEY,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({ federatedSessionToken: token }),
    });
  }
  req.session.destroy(() => res.sendStatus(204));
});
```

La app también puede revocar su propio token con la misma llamada, autenticándose con ese token (`x-auth-scheme=federated-token&x-auth-ft=<token>`).

## Antes de lanzar

- La clave de API se queda en tu servidor; nada en el dispositivo de un usuario puede generar tokens.
- Tu backend comprueba, en cada solicitud de token, que el usuario puede ver esa cámara.
- Los tokens están limitados a una cámara, duran minutos y están vinculados al origen de tu app web con `domain`.
- Al cerrar sesión se revocan los tokens generados para esa sesión.
- Las URLs con tokens se mantienen fuera de los registros, la analítica y los informes de errores.
- Tu app pide un token nuevo antes de `expiresAtMs`, y maneja un 401 pidiendo uno nuevo y recargando la imagen o la transmisión.
