Integraciones
Integración con React
Guía completa para integrar VIDTREO en aplicaciones React con componentes y hooks.
Integración con React
El paquete @vidtreo/recorder-react proporciona un componente React listo para usar y un hook potente para implementaciones personalizadas.
Instalación
npm install @vidtreo/recorder-reactInicio Rápido
La forma más simple de añadir grabación de video es con el componente VidtreoRecorder:
import { VidtreoRecorder } from '@vidtreo/recorder-react';
function App() {
return (
<VidtreoRecorder
apiKey={import.meta.env.VITE_VIDTREO_API_KEY}
onUploadComplete={(result) => {
console.log('Video listo:', result.uploadUrl);
}}
/>
);
}Props del Componente
Requeridos
| Prop | Tipo | Descripción |
|---|---|---|
apiKey | string | Tu API key de VIDTREO |
Opcionales
| Prop | Tipo | Por Defecto | Descripción |
|---|---|---|---|
backendUrl | string | https://core.vidtreo.com | URL del endpoint de la API |
enableSourceSwitching | boolean | true | Permite cambio cámara/pantalla |
enableMute | boolean | true | Muestra botón de silencio |
enablePause | boolean | true | Muestra botón pausar/reanudar |
enableDeviceChange | boolean | true | Permite selección de dispositivos |
maxRecordingTime | number | undefined | Duración máxima en milisegundos |
countdownDuration | number | 3000 | Cuenta regresiva previa en ms |
userMetadata | object | undefined | Metadatos personalizados del video |
lang | string | "en" | Idioma de la UI (en, es, pt) |
texts | object | undefined | Textos personalizados |
demo | boolean | false | Modo demo (sin subida) |
Callbacks
| Callback | Parámetros | Descripción |
|---|---|---|
onRecordingStart | () | Se dispara al iniciar grabación |
onRecordingStop | () | Se dispara al terminar grabación |
onUploadProgress | (progress: number) | Progreso de subida (0-1) |
onUploadComplete | (result) | Subida completada exitosamente |
onUploadError | (error: Error) | Fallo en la subida |
onError | (error: Error) | Cualquier error ocurrido |
Ejemplo Completo
import { VidtreoRecorder } from '@vidtreo/recorder-react';
import { useState } from 'react';
function VideoRecorderPage() {
const [videoUrl, setVideoUrl] = useState<string | null>(null);
const [uploadProgress, setUploadProgress] = useState(0);
const [isRecording, setIsRecording] = useState(false);
return (
<div className="container">
<h1>Graba un Mensaje de Video</h1>
<VidtreoRecorder
apiKey={import.meta.env.VITE_VIDTREO_API_KEY}
enableSourceSwitching={true}
enableMute={true}
enablePause={true}
enableDeviceChange={true}
maxRecordingTime={120000} // 2 minutos
countdownDuration={3000}
lang="es"
userMetadata={{
userId: 'user-123',
sessionId: 'session-456',
}}
onRecordingStart={() => {
setIsRecording(true);
setVideoUrl(null);
}}
onRecordingStop={() => {
setIsRecording(false);
}}
onUploadProgress={(progress) => {
setUploadProgress(progress);
}}
onUploadComplete={(result) => {
setVideoUrl(result.uploadUrl);
setUploadProgress(0);
}}
onError={(error) => {
console.error('Error:', error);
}}
/>
{uploadProgress > 0 && uploadProgress < 1 && (
<div className="progress-bar">
<div style={{ width: `${uploadProgress * 100}%` }} />
<span>{Math.round(uploadProgress * 100)}%</span>
</div>
)}
{videoUrl && (
<div className="result">
<h2>¡Grabación Completa!</h2>
<video src={videoUrl} controls />
</div>
)}
</div>
);
}Usando el Hook
Para control total sobre la UI, usa el hook useVidtreoRecorder:
import { useVidtreoRecorder } from '@vidtreo/recorder-react';
import { useRef, useEffect } from 'react';
function CustomRecorder() {
const videoRef = useRef<HTMLVideoElement>(null);
const { state, actions, audioLevel } = useVidtreoRecorder({
apiKey: import.meta.env.VITE_VIDTREO_API_KEY,
onUploadComplete: (result) => {
console.log('URL del Video:', result.uploadUrl);
},
});
// Conectar stream al elemento video
useEffect(() => {
if (videoRef.current && state.stream) {
videoRef.current.srcObject = state.stream;
}
}, [state.stream]);
// Inicializar al montar
useEffect(() => {
actions.startPreview();
}, []);
return (
<div className="custom-recorder">
<video ref={videoRef} autoPlay muted playsInline />
{/* Indicador de nivel de audio */}
<div className="audio-meter" style={{ width: `${audioLevel * 100}%` }} />
{/* Controles de grabación */}
<div className="controls">
{state.recordingState === 'idle' && (
<button onClick={() => actions.startRecording()}>
Iniciar Grabación
</button>
)}
{state.recordingState === 'countdown' && (
<div className="countdown">{state.countdown}</div>
)}
{state.recordingState === 'recording' && (
<>
<span className="timer">{state.timer}</span>
<button onClick={() => actions.toggleMute()}>
{state.isMuted ? 'Activar Audio' : 'Silenciar'}
</button>
<button onClick={() =>
state.isPaused ? actions.resumeRecording() : actions.pauseRecording()
}>
{state.isPaused ? 'Reanudar' : 'Pausar'}
</button>
<button onClick={() => actions.stopRecording()}>
Detener
</button>
</>
)}
</div>
{/* Selección de dispositivos */}
<div className="devices">
<select
value={state.devices.selectedCamera || ''}
onChange={(e) => actions.changeCamera(e.target.value)}
>
{state.devices.cameras.map((camera) => (
<option key={camera.deviceId} value={camera.deviceId}>
{camera.label}
</option>
))}
</select>
<select
value={state.devices.selectedMic || ''}
onChange={(e) => actions.changeMic(e.target.value)}
>
{state.devices.microphones.map((mic) => (
<option key={mic.deviceId} value={mic.deviceId}>
{mic.label}
</option>
))}
</select>
</div>
{/* Progreso de subida */}
{state.uploadProgress !== null && (
<div className="upload-progress">
Subiendo: {Math.round(state.uploadProgress * 100)}%
</div>
)}
{state.error && (
<div className="error">{state.error}</div>
)}
</div>
);
}Valores de Retorno del Hook
Objeto State
interface State {
recordingState: 'idle' | 'countdown' | 'recording';
stream: MediaStream | null;
isMuted: boolean;
isPaused: boolean;
error: string | null;
countdown: number | null;
timer: string; // formato "00:00"
uploadProgress: number | null; // 0-1
transitionMessage: string | null;
isInitialized: boolean;
recordedBlob: Blob | null;
devices: {
cameras: MediaDeviceInfo[];
microphones: MediaDeviceInfo[];
selectedCamera: string | null;
selectedMic: string | null;
};
}Objeto Actions
interface Actions {
startRecording(sourceType?: 'camera' | 'screen'): Promise<void>;
stopRecording(): Promise<RecordingStopResult>;
pauseRecording(): void;
resumeRecording(): void;
toggleMute(): void;
switchSource(sourceType: 'camera' | 'screen'): Promise<void>;
changeCamera(deviceId: string): Promise<void>;
changeMic(deviceId: string): Promise<void>;
startPreview(sourceType?: 'camera' | 'screen'): Promise<void>;
downloadVideo(): void;
cleanup(): void;
}Internacionalización
Idiomas Incorporados
// Inglés (por defecto)
<VidtreoRecorder apiKey="..." lang="en" />
// Español
<VidtreoRecorder apiKey="..." lang="es" />
// Portugués
<VidtreoRecorder apiKey="..." lang="pt" />Textos Personalizados
Sobrescribe cualquier texto de la UI:
<VidtreoRecorder
apiKey="..."
lang="es"
texts={{
record: 'Iniciar Captura',
stop: 'Finalizar Captura',
pause: 'Esperar',
resume: 'Continuar',
mute: 'Silencio',
unmute: 'Con Sonido',
switchSource: 'Cambiar Fuente',
uploading: 'Enviando...',
}}
/>Claves de Texto Disponibles
| Clave | Por Defecto (Español) |
|---|---|
initializingCamera | Inicializando cámara... |
grantPermissions | Por favor concede permisos de cámara |
switchingDevice | Cambiando dispositivo... |
recordingStartsIn | La grabación comienza en |
switchingSource | Cambiando fuente... |
rec | REC |
settings | Configuración |
record | Grabar |
stop | Detener |
pause | Pausar |
resume | Reanudar |
mute | Silenciar |
unmute | Activar Audio |
switchSource | Cambiar Fuente |
camera | Cámara |
microphone | Micrófono |
uploading | Subiendo... |
Soporte TypeScript
Todos los tipos están exportados:
import type {
VidtreoRecorderProps,
UseVidtreoRecorderConfig,
UseVidtreoRecorderReturn,
VidtreoRecorderState,
VidtreoRecorderActions,
PartialTranslations,
TranslationKeys,
} from '@vidtreo/recorder-react';Compatibilidad con Next.js
Para Next.js con App Router, asegura el renderizado del lado del cliente:
'use client';
import { VidtreoRecorder } from '@vidtreo/recorder-react';
export default function RecorderPage() {
return (
<VidtreoRecorder
apiKey={process.env.NEXT_PUBLIC_VIDTREO_API_KEY!}
onUploadComplete={(result) => {
console.log('Video:', result.uploadUrl);
}}
/>
);
}El grabador VIDTREO requiere APIs del navegador y debe renderizarse en el lado del cliente.
Próximos Pasos
- Opciones de Configuración — Todas las configuraciones disponibles
- Referencia de Callbacks — Maneja todos los eventos
- Ejemplo de UI Personalizada — Construye tu propia interfaz