Saltar al contenido principal

Documentation Index

Fetch the complete documentation index at: https://api-docs.rhombus.community/llms.txt

Use this file to discover all available pages before exploring further.

Esta página fue traducida automáticamente. Si encuentra errores o tiene sugerencias, contáctenos.

Descripción general

Las cámaras Rhombus ofrecen múltiples maneras de acceder al contenido de video:
  • Transmisión en vivo para monitoreo en tiempo real
  • Miniaturas para vistas previas rápidas y paneles
  • Clips de video grabado para reproducción histórica
  • Capturas instantáneas para momentos específicos

Obtención de miniaturas de cámara

Todas las cámaras Rhombus suben automáticamente miniaturas que ofrecen instantáneas actuales de lo que ve la cámara. Estas miniaturas son ideales para vistas previas en paneles, interfaces de monitoreo y verificaciones rápidas de estado.

Endpoint de miniaturas

Recupera las miniaturas de la cámara mediante una solicitud GET a:
https://media.rhombussystems.com/media/{cameraUuid}/{mediaRegion}/snapshot.jpeg
Todos los endpoints de media.rhombussystems.com usan la misma autenticación que la API principal, así que asegúrate de incluir los encabezados de autenticación.
Para obtener el cameraUuid y el mediaRegion de una cámara, usa el endpoint /camera/getMinimalCameraState para obtener una lista de todas las cámaras. En la respuesta, encontrarás los campos uuid y mediaRegion.

Implementación básica

# First get camera details
curl -X GET \
  "https://api2.rhombussystems.com/camera/getMinimalCameraState" \
  -H "x-auth-scheme: api-token" \
  -H "x-auth-apikey: YOUR_API_KEY" \
  -H "Content-Type: application/json"

# Then get thumbnail using camera UUID and media region
curl -X GET \
  "https://media.rhombussystems.com/media/{CAMERA_UUID}/{MEDIA_REGION}/snapshot.jpeg" \
  -H "x-auth-scheme: api-token" \
  -H "x-auth-apikey: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  --output thumbnail.jpg

Obtener fotogramas en momentos específicos

Para obtener una imagen JPEG en un momento determinado, usa el endpoint /video/getExactFrameUri para generar un URI de fotograma. Ejecuta una solicitud GET al URI de fotograma devuelto con los mismos encabezados de autenticación para obtener el fotograma solicitado directamente desde la cámara.
async function getFrameAtTime(cameraUuid, timestamp, apiKey) {
  // Get frame URI
  const frameUriResponse = await fetch('https://api2.rhombussystems.com/video/getExactFrameUri', {
    method: 'POST',
    headers: {
      'x-auth-scheme': 'api-token',
      'x-auth-apikey': apiKey,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      cameraUuid: cameraUuid,
      timestamp: timestamp,
      crop: false // Set to true if you want a cropped image
    })
  });
  
  const frameData = await frameUriResponse.json();
  
  // Get the actual frame
  const frameResponse = await fetch(frameData.frameUri, {
    headers: {
      'x-auth-scheme': 'api-token',
      'x-auth-apikey': apiKey
    }
  });
  
  return frameResponse.blob();
}

Transmisión de video en vivo

Rhombus ofrece múltiples maneras de incrustar y transmitir contenido de video en vivo en tus aplicaciones.

Incrustar transmisiones compartidas como iframes (Recomendado)

La forma más común y recomendada es usar iframes para incrustar el reproductor de video Rhombus directamente en tu sitio. Esto trae el beneficio adicional de que los eventos de cámara y la analítica se cargan automáticamente en el reproductor. Necesitarás crear transmisiones compartidas para cada cámara que quieras incrustar. Esto se puede hacer en la consola, o desde la API usando el endpoint /api/camera/createSharedLiveVideoStream.
async function createSharedStream(cameraUuid, apiKey) {
  const response = await fetch('https://api2.rhombussystems.com/api/camera/createSharedLiveVideoStream', {
    method: 'POST',
    headers: {
      'x-auth-scheme': 'api-token',
      'x-auth-apikey': apiKey,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      cameraUuid: cameraUuid,
      // Additional configuration options
    })
  });
  
  const streamData = await response.json();
  return streamData.url; // This is your shared stream URL
}
La respuesta incluye una URL que puedes agregar a un iframe e incrustar en tu aplicación:
<iframe 
  allow="fullscreen" 
  frameborder="0" 
  height="100%" 
  width="100%" 
  src="SHARED_STREAM_URL_GOES_HERE">
</iframe>

Ejemplo de componente React

Aquí tienes un componente React para incrustar transmisiones compartidas:
import React, { useState, useEffect } from 'react';

const RhombusSharedStream = ({ 
  cameraUuid, 
  apiKey, 
  width = "100%", 
  height = "400px",
  options = {} 
}) => {
  const [streamUrl, setStreamUrl] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    createSharedStream();
  }, [cameraUuid]);

  const createSharedStream = async () => {
    try {
      setLoading(true);
      const response = await fetch('https://api2.rhombussystems.com/api/camera/createSharedLiveVideoStream', {
        method: 'POST',
        headers: {
          'x-auth-scheme': 'api-token',
          'x-auth-apikey': apiKey,
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({
          cameraUuid: cameraUuid
        })
      });

      if (!response.ok) {
        throw new Error('Failed to create shared stream');
      }

      const streamData = await response.json();
      
      // Add URL parameters if specified
      const url = new URL(streamData.url);
      Object.entries(options).forEach(([key, value]) => {
        url.searchParams.set(key, value);
      });
      
      setStreamUrl(url.toString());
      setError(null);
    } catch (err) {
      setError(err.message);
    } finally {
      setLoading(false);
    }
  };

  if (loading) return <div>Loading stream...</div>;
  if (error) return <div>Error: {error}</div>;

  return (
    <iframe
      src={streamUrl}
      width={width}
      height={height}
      frameBorder="0"
      allow="fullscreen"
      title={`Camera ${cameraUuid} Stream`}
    />
  );
};

export default RhombusSharedStream;

Parámetros de URL para control mejorado

Puedes personalizar el reproductor incrustado mediante parámetros de URL. Todos los parámetros pueden establecerse en true o false:
ParámetroDescripción
disableautoplayActiva o desactiva la reproducción automática al cargar
hideeventsActiva o desactiva la línea de tiempo y los eventos relacionados
realtimeActiva o desactiva la transmisión en tiempo real por defecto
showheaderActiva o desactiva los botones de zoom y transmisión arriba
showfooterActiva o desactiva el nombre de la cámara y la marca de tiempo abajo
lowResFuerza baja resolución en la transmisión de video
performanceModeFuerza el modo de rendimiento permitiendo el uso de GPU
tMarca de tiempo (milisegundos epoch) donde debe iniciar el video

Uso de parámetros

Sigue esta estructura: https://{{url}}/?{{variable}}=true&{{variable}}=false Ejemplo:
https://console.rhombussystems.com/share/live/ehrF58ABSj2VT8QzXh7GVA?disableautoplay=true&hideevents=true&realtime=true

Uso en React con parámetros

// Usage with custom parameters
<RhombusSharedStream 
  cameraUuid="your-camera-uuid"
  apiKey="your-api-key"
  options={{
    disableautoplay: 'true',
    hideevents: 'true',
    realtime: 'true',
    showheader: 'false',
    lowRes: 'false'
  }}
/>

Acceso a transmisiones MPEG-DASH sin procesar

Con autenticación de API, también puedes acceder a la transmisión MPEG-DASH sin procesar para usarla con cualquier reproductor estándar. Para mantener seguro el token de API y resolver problemas de CORS, recomendamos usar un servidor intermediario que actúe como proxy.
// Server-side proxy example (Node.js/Express)
app.get('/stream-proxy/:cameraUuid', async (req, res) => {
  const { cameraUuid } = req.params;
  const apiKey = process.env.RHOMBUS_API_KEY; // Keep API key server-side
  
  try {
    // Get DASH stream URL from Rhombus API
    const streamResponse = await fetch(`https://api2.rhombussystems.com/api/camera/getDashStream`, {
      method: 'POST',
      headers: {
        'x-auth-scheme': 'api-token',
        'x-auth-apikey': apiKey,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ cameraUuid })
    });
    
    const streamData = await streamResponse.json();
    
    // Proxy the stream to client
    res.json({ streamUrl: streamData.dashUrl });
  } catch (error) {
    res.status(500).json({ error: 'Failed to get stream' });
  }
});
Uso del lado del cliente con dash.js:
import dashjs from 'dashjs';

async function setupDashStream(cameraUuid, videoElementId) {
  // Get stream URL from your proxy
  const response = await fetch(`/stream-proxy/${cameraUuid}`);
  const { streamUrl } = await response.json();
  
  const videoElement = document.getElementById(videoElementId);
  const player = dashjs.MediaPlayer().create();
  
  player.initialize(videoElement, streamUrl, true);
  
  return player;
}

Reproducción de video grabado

Accede a clips de video grabado para análisis y revisión históricos.

Descargar clips VOD como MP4

Puedes descargar grabaciones de Video on Demand (VOD) directamente desde una cámara especificando la hora de inicio y la duración.
async function downloadVODClip(cameraUuid, startTime, durationSeconds, apiKey) {
  const response = await fetch('https://api2.rhombussystems.com/api/video/downloadClip', {
    method: 'POST',
    headers: {
      'x-auth-scheme': 'api-token',
      'x-auth-apikey': apiKey,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      cameraUuid: cameraUuid,
      startTime: startTime, // Unix timestamp in milliseconds
      duration: durationSeconds * 1000, // Duration in milliseconds
      format: 'mp4'
    })
  });
  
  if (!response.ok) {
    throw new Error(`Failed to download clip: ${response.statusText}`);
  }
  
  // Return the blob for download
  return response.blob();
}

// Usage example
async function downloadAndSaveClip() {
  const startTime = new Date('2024-01-01T12:00:00Z').getTime();
  const duration = 300; // 5 minutes
  
  try {
    const clipBlob = await downloadVODClip('camera-uuid', startTime, duration, 'your-api-key');
    
    // Create download link
    const url = URL.createObjectURL(clipBlob);
    const a = document.createElement('a');
    a.href = url;
    a.download = `camera-clip-${startTime}.mp4`;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    URL.revokeObjectURL(url);
  } catch (error) {
    console.error('Error downloading clip:', error);
  }
}

Ejemplo en Python para descarga de VOD

import requests
from datetime import datetime
import time

def download_vod_clip(camera_uuid, start_time, duration_seconds, api_key, output_filename):
    """
    Download a VOD clip from Rhombus camera
    
    Args:
        camera_uuid (str): Camera UUID
        start_time (datetime): Start time for the clip
        duration_seconds (int): Duration in seconds
        api_key (str): Rhombus API key
        output_filename (str): Output filename for the MP4
    """
    url = "https://api2.rhombussystems.com/api/video/downloadClip"
    
    # Convert datetime to Unix timestamp in milliseconds
    start_timestamp = int(start_time.timestamp() * 1000)
    duration_ms = duration_seconds * 1000
    
    payload = {
        'cameraUuid': camera_uuid,
        'startTime': start_timestamp,
        'duration': duration_ms,
        'format': 'mp4'
    }
    
    headers = {
        'x-auth-scheme': 'api-token',
        'x-auth-apikey': api_key,
        'Content-Type': 'application/json'
    }
    
    response = requests.post(url, json=payload, headers=headers)
    response.raise_for_status()
    
    # Save the clip
    with open(output_filename, 'wb') as f:
        f.write(response.content)
    
    print(f"Clip saved as {output_filename}")

# Usage
start_time = datetime(2024, 1, 1, 12, 0, 0)  # January 1, 2024 at 12:00 PM
download_vod_clip('camera-uuid', start_time, 300, 'your-api-key', 'camera_clip.mp4')

Descargar clips de alerta

Puedes descargar clips correspondientes a alertas específicas. Esto es particularmente útil al usar webhooks que se activan cada vez que se crea una alerta en el sistema.
async function downloadAlertClip(alertData, apiKey) {
  // alertData comes from webhook payload or API response
  const { cameraUuid, startTime, endTime, alertId } = alertData;
  
  const response = await fetch('https://api2.rhombussystems.com/api/video/downloadAlertClip', {
    method: 'POST',
    headers: {
      'x-auth-scheme': 'api-token',
      'x-auth-apikey': apiKey,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      cameraUuid: cameraUuid,
      alertId: alertId,
      startTime: startTime,
      endTime: endTime,
      format: 'mp4'
    })
  });
  
  if (!response.ok) {
    throw new Error(`Failed to download alert clip: ${response.statusText}`);
  }
  
  return response.blob();
}

// Webhook handler example (Express.js)
app.post('/webhook/alert', async (req, res) => {
  const alertData = req.body;
  
  try {
    // Download the clip associated with this alert
    const clipBlob = await downloadAlertClip(alertData, process.env.RHOMBUS_API_KEY);
    
    // Process or save the clip as needed
    console.log(`Downloaded clip for alert ${alertData.alertId}`);
    
    res.status(200).send('OK');
  } catch (error) {
    console.error('Error processing alert webhook:', error);
    res.status(500).send('Error');
  }
});

Obtener detalles de alertas para descarga de clips

Si estás usando la API para obtener detalles de alertas (por ejemplo, /api/event/getPolicyAlertsV2), puedes usar los campos de la respuesta para construir la solicitud de medios:
async function getAlertsAndDownloadClips(apiKey) {
  // Get recent alerts
  const alertsResponse = await fetch('https://api2.rhombussystems.com/api/event/getPolicyAlertsV2', {
    method: 'POST',
    headers: {
      'x-auth-scheme': 'api-token',
      'x-auth-apikey': apiKey,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      // Add your alert query parameters
      limit: 10,
      // startTime, endTime, etc.
    })
  });
  
  const alerts = await alertsResponse.json();
  
  // Download clips for each alert
  for (const alert of alerts) {
    try {
      const clipBlob = await downloadAlertClip({
        cameraUuid: alert.cameraUuid,
        alertId: alert.alertId,
        startTime: alert.startTime,
        endTime: alert.endTime
      }, apiKey);
      
      // Save or process the clip
      console.log(`Downloaded clip for alert ${alert.alertId}`);
    } catch (error) {
      console.error(`Failed to download clip for alert ${alert.alertId}:`, error);
    }
  }
}

Ejemplos de implementación completa

Componente React multipropósito

Aquí tienes un componente React integral que admite miniaturas, transmisiones compartidas y descargas de video:
import React, { useEffect, useState, useCallback } from 'react';

const RhombusCameraViewer = ({ 
  cameraUuid, 
  apiKey, 
  viewType = 'thumbnail', // 'thumbnail', 'stream', 'download'
  autoRefresh = true,
  refreshInterval = 5000,
  streamOptions = {},
  width = "100%",
  height = "400px"
}) => {
  const [thumbnailUrl, setThumbnailUrl] = useState(null);
  const [streamUrl, setStreamUrl] = useState(null);
  const [cameraDetails, setCameraDetails] = useState(null);
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState(null);
  
  // Get camera details (UUID and media region)
  const getCameraDetails = useCallback(async () => {
    try {
      const response = await fetch('https://api2.rhombussystems.com/camera/getMinimalCameraState', {
        headers: {
          'x-auth-scheme': 'api-token',
          'x-auth-apikey': apiKey,
          'Content-Type': 'application/json'
        }
      });
      
      if (!response.ok) throw new Error('Failed to get camera details');
      
      const cameras = await response.json();
      const camera = cameras.find(c => c.uuid === cameraUuid);
      
      if (!camera) throw new Error('Camera not found');
      
      setCameraDetails(camera);
      return camera;
    } catch (err) {
      setError(err.message);
      throw err;
    }
  }, [cameraUuid, apiKey]);
  
  // Load thumbnail
  const loadThumbnail = useCallback(async () => {
    if (!cameraDetails) return;
    
    try {
      setIsLoading(true);
      const response = await fetch(
        `https://media.rhombussystems.com/media/${cameraDetails.uuid}/${cameraDetails.mediaRegion}/snapshot.jpeg`,
        {
          headers: { 'x-auth-scheme': 'api-token', 'x-auth-apikey': apiKey }
        }
      );
      
      if (!response.ok) throw new Error('Failed to load thumbnail');
      
      const blob = await response.blob();
      const url = URL.createObjectURL(blob);
      
      // Clean up previous URL
      if (thumbnailUrl) URL.revokeObjectURL(thumbnailUrl);
      
      setThumbnailUrl(url);
      setError(null);
    } catch (err) {
      setError(err.message);
    } finally {
      setIsLoading(false);
    }
  }, [cameraDetails, apiKey, thumbnailUrl]);
  
  // Create shared stream
  const createSharedStream = useCallback(async () => {
    try {
      setIsLoading(true);
      const response = await fetch('https://api2.rhombussystems.com/api/camera/createSharedLiveVideoStream', {
        method: 'POST',
        headers: {
          'x-auth-scheme': 'api-token',
          'x-auth-apikey': apiKey,
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({
          cameraUuid: cameraUuid
        })
      });

      if (!response.ok) throw new Error('Failed to create shared stream');

      const streamData = await response.json();
      
      // Add URL parameters if specified
      const url = new URL(streamData.url);
      Object.entries(streamOptions).forEach(([key, value]) => {
        url.searchParams.set(key, value);
      });
      
      setStreamUrl(url.toString());
      setError(null);
    } catch (err) {
      setError(err.message);
    } finally {
      setIsLoading(false);
    }
  }, [cameraUuid, apiKey, streamOptions]);
  
  // Download VOD clip
  const downloadClip = async (startTime, duration) => {
    try {
      const response = await fetch('https://api2.rhombussystems.com/api/video/downloadClip', {
        method: 'POST',
        headers: {
          'x-auth-scheme': 'api-token',
          'x-auth-apikey': apiKey,
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({
          cameraUuid: cameraUuid,
          startTime: startTime,
          duration: duration * 1000,
          format: 'mp4'
        })
      });
      
      if (!response.ok) throw new Error('Failed to download clip');
      
      const blob = await response.blob();
      const url = URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = `camera-${cameraUuid}-${startTime}.mp4`;
      document.body.appendChild(a);
      a.click();
      document.body.removeChild(a);
      URL.revokeObjectURL(url);
    } catch (err) {
      setError(err.message);
    }
  };
  
  useEffect(() => {
    getCameraDetails().then(() => {
      if (viewType === 'thumbnail') {
        loadThumbnail();
        if (autoRefresh) {
          const interval = setInterval(loadThumbnail, refreshInterval);
          return () => clearInterval(interval);
        }
      } else if (viewType === 'stream') {
        createSharedStream();
      }
    });
  }, [viewType, autoRefresh, refreshInterval, getCameraDetails, loadThumbnail, createSharedStream]);
  
  if (error) {
    return (
      <div className="camera-error" style={{ padding: '20px', border: '1px solid #ff6b6b', borderRadius: '4px' }}>
        <p>Error: {error}</p>
        <button onClick={() => window.location.reload()}>Retry</button>
      </div>
    );
  }
  
  if (isLoading) {
    return <div className="loading" style={{ padding: '20px', textAlign: 'center' }}>Loading camera...</div>;
  }
  
  return (
    <div className="camera-viewer" style={{ width, height }}>
      {viewType === 'thumbnail' && thumbnailUrl && (
        <img 
          src={thumbnailUrl} 
          alt={`Camera ${cameraUuid}`}
          style={{ width: '100%', height: '100%', objectFit: 'cover' }}
        />
      )}
      
      {viewType === 'stream' && streamUrl && (
        <iframe
          src={streamUrl}
          width="100%"
          height="100%"
          frameBorder="0"
          allow="fullscreen"
          title={`Camera ${cameraUuid} Stream`}
        />
      )}
      
      {viewType === 'download' && (
        <div style={{ padding: '20px' }}>
          <h3>Download Video Clips</h3>
          <button 
            onClick={() => {
              const startTime = new Date().getTime() - (5 * 60 * 1000); // 5 minutes ago
              downloadClip(startTime, 300); // 5 minute duration
            }}
            style={{ padding: '10px 20px', margin: '5px' }}
          >
            Download Last 5 Minutes
          </button>
          <button 
            onClick={() => {
              const startTime = new Date().getTime() - (60 * 60 * 1000); // 1 hour ago
              downloadClip(startTime, 3600); // 1 hour duration
            }}
            style={{ padding: '10px 20px', margin: '5px' }}
          >
            Download Last Hour
          </button>
        </div>
      )}
    </div>
  );
};

export default RhombusCameraViewer;

Ejemplos de uso

// Thumbnail view with auto-refresh
<RhombusCameraViewer 
  cameraUuid="your-camera-uuid"
  apiKey="your-api-key"
  viewType="thumbnail"
  autoRefresh={true}
  refreshInterval={3000}
  width="640px"
  height="480px"
/>

// Live stream with custom options
<RhombusCameraViewer 
  cameraUuid="your-camera-uuid"
  apiKey="your-api-key"
  viewType="stream"
  streamOptions={{
    disableautoplay: 'false',
    hideevents: 'false',
    realtime: 'true',
    showheader: 'true',
    showfooter: 'true'
  }}
  width="100%"
  height="600px"
/>

// Download interface
<RhombusCameraViewer 
  cameraUuid="your-camera-uuid"
  apiKey="your-api-key"
  viewType="download"
/>

Mejores prácticas

Optimización del rendimiento

  • Caché de miniaturas: Implementa caché del lado del cliente para miniaturas para reducir las llamadas a la API
  • Carga diferida: Carga el contenido de video solo cuando sea necesario o cuando esté en el viewport
  • Selección de calidad: Elige los ajustes de calidad apropiados según el caso de uso y el ancho de banda
  • Pool de conexiones: Reutiliza las conexiones para múltiples solicitudes a la API

Consideraciones de seguridad

  • Gestión de API keys: Almacena las API keys de forma segura y nunca las expongas en código del lado del cliente
  • Solo HTTPS: Usa siempre HTTPS para todas las comunicaciones de la API
  • Rotación de tokens: Implementa rotación regular de la API key
  • Control de acceso: Limita el acceso a las cámaras según los permisos de usuario

Manejo de errores

class RhombusVideoError extends Error {
  constructor(message, code, cameraUuid) {
    super(message);
    this.name = 'RhombusVideoError';
    this.code = code;
    this.cameraUuid = cameraUuid;
  }
}

async function robustThumbnailFetch(cameraUuid, apiKey, retries = 3) {
  for (let attempt = 1; attempt <= retries; attempt++) {
    try {
      const response = await fetch(`https://media.rhombus.com/thumbnail/${cameraUuid}`, {
        headers: { 'x-auth-scheme': 'api-token', 'x-auth-apikey': apiKey },
        timeout: 10000 // 10 second timeout
      });
      
      if (!response.ok) {
        throw new RhombusVideoError(
          `HTTP ${response.status}: ${response.statusText}`,
          response.status,
          cameraUuid
        );
      }
      
      return response.blob();
    } catch (error) {
      if (attempt === retries) {
        throw error;
      }
      
      // Exponential backoff
      await new Promise(resolve => setTimeout(resolve, Math.pow(2, attempt) * 1000));
    }
  }
}

Accesibilidad

Asegúrate de que tus implementaciones de video sean accesibles para todos los usuarios:
<video 
  controls
  aria-label={`Live feed from camera ${cameraName}`}
  poster={thumbnailUrl}
>
  <track kind="captions" src="captions.vtt" srcLang="en" label="English" />
  Your browser does not support the video tag.
</video>

Solución de problemas

Problemas comunes

La miniatura no carga
  • Verifica que el UUID de la cámara sea correcto
  • Revisa los permisos de la API key
  • Asegúrate de que la cámara esté en línea y accesible
Fallos de conexión de transmisión
  • Verifica la conectividad de red
  • Confirma el soporte de WebRTC/HLS en el navegador
  • Revisa la configuración del firewall y proxy
Calidad de video deficiente
  • Ajusta los parámetros de calidad
  • Verifica el ancho de banda disponible
  • Considera usar transmisión de tasa de bits adaptativa

Modo de depuración

Habilita el registro de depuración para solucionar problemas:
const DEBUG = process.env.NODE_ENV === 'development';

function debugLog(message, data = null) {
  if (DEBUG) {
    console.log(`[Rhombus Video] ${message}`, data);
  }
}

// Usage in your functions
debugLog('Fetching thumbnail', { cameraUuid, timestamp: new Date() });

Próximos pasos

Reproductor de video

Crea un reproductor de video personalizado con reproducción HLS y controles de línea de tiempo.

Respaldo de grabaciones

Descarga y archiva grabaciones de cámara en almacenamiento local.
Last modified on April 30, 2026