Vidtreo
Integraciones

Componente Web

Usa VIDTREO con cualquier framework o HTML vanilla usando el elemento personalizado.

Web Component

El paquete @vidtreo/recorder-wc proporciona un Web Component agnóstico de framework que funciona con Vue, Angular, Svelte o HTML plano.

Instalación

Via npm

npm install @vidtreo/recorder-wc

Via CDN (Sin Compilación)

<script type="module" src="https://cdn.jsdelivr.net/npm/@vidtreo/recorder-wc@latest/dist/vidtreo-recorder.js"></script>

Uso Básico

HTML

<!DOCTYPE html>
<html>
<head>
  <script type="module" src="https://cdn.jsdelivr.net/npm/@vidtreo/recorder-wc@latest/dist/vidtreo-recorder.js"></script>
</head>
<body>
  <vidtreo-recorder
    api-key="tu-api-key"
    lang="es"
  ></vidtreo-recorder>

  <script>
    const recorder = document.querySelector('vidtreo-recorder');

    recorder.addEventListener('upload-complete', (event) => {
      console.log('URL del Video:', event.detail.uploadUrl);
      console.log('ID de Grabación:', event.detail.recordingId);
    });

    recorder.addEventListener('error', (event) => {
      console.error('Error:', event.detail);
    });
  </script>
</body>
</html>

Vue.js

<template>
  <vidtreo-recorder
    :api-key="apiKey"
    lang="es"
    @upload-complete="handleUploadComplete"
    @error="handleError"
  />
</template>

<script setup>
import '@vidtreo/recorder-wc';

const apiKey = import.meta.env.VITE_VIDTREO_API_KEY;

function handleUploadComplete(event) {
  console.log('URL del Video:', event.detail.uploadUrl);
}

function handleError(event) {
  console.error('Error:', event.detail);
}
</script>

Angular

// app.module.ts
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import '@vidtreo/recorder-wc';

@NgModule({
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
  // ...
})
export class AppModule {}
<!-- recorder.component.html -->
<vidtreo-recorder
  [attr.api-key]="apiKey"
  lang="es"
  (upload-complete)="onUploadComplete($event)"
  (error)="onError($event)"
></vidtreo-recorder>

Svelte

<script>
  import '@vidtreo/recorder-wc';

  const apiKey = import.meta.env.VITE_VIDTREO_API_KEY;

  function handleUploadComplete(event) {
    console.log('URL del Video:', event.detail.uploadUrl);
  }

  function handleError(event) {
    console.error('Error:', event.detail);
  }
</script>

<vidtreo-recorder
  api-key={apiKey}
  lang="es"
  on:upload-complete={handleUploadComplete}
  on:error={handleError}
/>

Atributos

Todos los atributos usan kebab-case (convención HTML):

AtributoTipoPor DefectoDescripción
api-keystringrequeridoTu API key de VIDTREO
backend-urlstringhttps://core.vidtreo.comEndpoint de la API
countdown-durationnumber3000Cuenta regresiva (ms)
max-recording-timenumberundefinedDuración máxima (ms)
user-metadatastringundefinedJSON string de metadatos
enable-source-switchingbooleantrueAlternar cámara/pantalla
enable-mutebooleantrueBotón de silencio
enable-pausebooleantruePausar/reanudar
enable-device-changebooleantrueSelección de dispositivos
mobile-modestring"overlay"Modo móvil: "overlay", "embed", "native"
langstring"en"Idioma de la UI
textsstringundefinedJSON string de textos personalizados

Establecer Atributos Dinámicamente

const recorder = document.querySelector('vidtreo-recorder');

// Atributos simples
recorder.setAttribute('lang', 'es');
recorder.setAttribute('max-recording-time', '120000');

// Atributos JSON (metadatos y textos)
recorder.setAttribute('user-metadata', JSON.stringify({
  userId: 'user-123',
  sessionId: 'session-456'
}));

recorder.setAttribute('texts', JSON.stringify({
  record: 'Iniciar Captura',
  stop: 'Finalizar Captura'
}));

Eventos

Escucha eventos usando addEventListener o sintaxis específica del framework:

EventoDetalleDescripción
recording-start{}Grabación iniciada
recording-stop{}Grabación detenida
upload-progress{ progress: number }Progreso de subida (0-1)
upload-complete{ uploadUrl, recordingId }Subida finalizada
upload-error{ error: Error }Falló la subida
error{ error: Error }Cualquier error

Ejemplos de Eventos

const recorder = document.querySelector('vidtreo-recorder');

recorder.addEventListener('recording-start', () => {
  console.log('Grabación iniciada');
});

recorder.addEventListener('recording-stop', () => {
  console.log('Grabación detenida');
});

recorder.addEventListener('upload-progress', (e) => {
  const percent = Math.round(e.detail.progress * 100);
  console.log(`Progreso de subida: ${percent}%`);
});

recorder.addEventListener('upload-complete', (e) => {
  console.log('URL del Video:', e.detail.uploadUrl);
  console.log('ID de Grabación:', e.detail.recordingId);
});

recorder.addEventListener('error', (e) => {
  console.error('Error:', e.detail.error);
});

Métodos

Controla el grabador programáticamente:

const recorder = document.querySelector('vidtreo-recorder');

// Iniciar vista previa de cámara
await recorder.startCamera();

// Controles de grabación
await recorder.startRecording();
await recorder.stopRecording();
recorder.pauseRecording();
recorder.resumeRecording();

// Controles de fuente
await recorder.toggleSource();  // Cambiar cámara/pantalla
recorder.toggleMute();

// Controles de dispositivos
await recorder.handleCameraChange('device-id');
await recorder.handleMicChange('device-id');

// Panel de configuración
recorder.toggleSettings();

// Reproducción de video (después de grabar)
recorder.playVideo();
recorder.downloadVideo();

// Procesar video (transcodificación)
await recorder.processVideo();

Estilos

El Web Component se renderiza en el light DOM (sin Shadow DOM), por lo que su estructura puede estilizarse con CSS normal. Estiliza el contenedor:

vidtreo-recorder {
  /* Dimensiones del contenedor */
  width: 100%;
  max-width: 640px;
  height: 480px;

  /* Estilos del contenedor */
  display: block;
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}

Propiedades CSS Personalizadas (Próximamente)

vidtreo-recorder {
  --vidtreo-primary-color: #3b82f6;
  --vidtreo-background: #1f2937;
  --vidtreo-text-color: #ffffff;
  --vidtreo-border-radius: 8px;
}

Internacionalización

Idiomas Incorporados

<!-- Inglés (por defecto) -->
<vidtreo-recorder api-key="..." lang="en"></vidtreo-recorder>

<!-- Español -->
<vidtreo-recorder api-key="..." lang="es"></vidtreo-recorder>

<!-- Portugués -->
<vidtreo-recorder api-key="..." lang="pt"></vidtreo-recorder>

Textos Personalizados

<vidtreo-recorder
  api-key="..."
  lang="es"
  texts='{"record": "Iniciar Captura", "stop": "Finalizar Captura", "uploading": "Enviando..."}'
></vidtreo-recorder>

Claves de Texto Disponibles

ClavePor Defecto (Español)
titleGrabar Video
subtitleHaz clic en grabar para comenzar
initializingCameraInicializando cámara...
grantPermissionsPor favor concede permisos de cámara
retryCameraReintentar
switchingDeviceCambiando dispositivo...
recordingStartsInLa grabación comienza en
switchingSourceCambiando fuente...
recREC
settingsConfiguración
recordGrabar
stopDetener
pausePausar
resumeReanudar
muteSilenciar
unmuteActivar Audio
switchSourceCambiar Fuente
cameraCámara
microphoneMicrófono
processVideoProcesar Video
processingProcesando...
uploadingSubiendo...
switchingCameraCambiando cámara...
switchingMicrophoneCambiando micrófono...
failedToStartCameraError al iniciar cámara

Ejemplo Completo

<!DOCTYPE html>
<html lang="es">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Grabador de Video</title>
  <script type="module" src="https://cdn.jsdelivr.net/npm/@vidtreo/recorder-wc@latest/dist/vidtreo-recorder.js"></script>
  <style>
    body {
      font-family: system-ui, sans-serif;
      max-width: 800px;
      margin: 0 auto;
      padding: 2rem;
    }

    vidtreo-recorder {
      width: 100%;
      max-width: 640px;
      height: 480px;
      display: block;
      margin: 0 auto;
      border-radius: 12px;
      overflow: hidden;
    }

    .result {
      margin-top: 2rem;
      text-align: center;
    }

    .result video {
      max-width: 100%;
      border-radius: 8px;
    }

    .progress {
      margin-top: 1rem;
      text-align: center;
    }

    .hidden {
      display: none;
    }
  </style>
</head>
<body>
  <h1>Graba tu Video</h1>

  <vidtreo-recorder
    id="recorder"
    api-key="tu-api-key"
    enable-source-switching="true"
    enable-mute="true"
    enable-pause="true"
    enable-device-change="true"
    max-recording-time="120000"
    countdown-duration="3000"
    lang="es"
  ></vidtreo-recorder>

  <div id="progress" class="progress hidden">
    <p>Subiendo: <span id="percent">0</span>%</p>
  </div>

  <div id="result" class="result hidden">
    <h2>¡Grabación Completa!</h2>
    <video id="video" controls></video>
    <p><a id="link" href="#" target="_blank">Abrir en nueva pestaña</a></p>
  </div>

  <script>
    const recorder = document.getElementById('recorder');
    const progress = document.getElementById('progress');
    const percent = document.getElementById('percent');
    const result = document.getElementById('result');
    const video = document.getElementById('video');
    const link = document.getElementById('link');

    recorder.addEventListener('recording-start', () => {
      result.classList.add('hidden');
    });

    recorder.addEventListener('upload-progress', (e) => {
      progress.classList.remove('hidden');
      percent.textContent = Math.round(e.detail.progress * 100);
    });

    recorder.addEventListener('upload-complete', (e) => {
      progress.classList.add('hidden');
      result.classList.remove('hidden');
      video.src = e.detail.uploadUrl;
      link.href = e.detail.uploadUrl;
    });

    recorder.addEventListener('error', (e) => {
      progress.classList.add('hidden');
      alert('Error: ' + e.detail.error.message);
    });
  </script>
</body>
</html>

Soporte TypeScript

Para proyectos TypeScript, añade declaraciones de tipos:

declare global {
  namespace JSX {
    interface IntrinsicElements {
      'vidtreo-recorder': React.DetailedHTMLProps<
        React.HTMLAttributes<HTMLElement> & {
          'api-key'?: string;
          'backend-url'?: string;
          'countdown-duration'?: string;
          'max-recording-time'?: string;
          'user-metadata'?: string;
          'enable-source-switching'?: string;
          'enable-mute'?: string;
          'enable-pause'?: string;
          'enable-device-change'?: string;
          'lang'?: string;
          'texts'?: string;
        },
        HTMLElement
      >;
    }
  }
}

Próximos Pasos

En esta página