Vidtreo
Ejemplos

UI Personalizada

Construye tu propia interfaz de grabación de video con hooks de VIDTREO.

UI Personalizada

Usa el hook useVidtreoRecorder para construir interfaces de grabación completamente personalizadas.

Grabador Personalizado Completo

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,
    countdownDuration: 3000,
    maxRecordingTime: 120000,
    onUploadComplete: (result) => {
      console.log('Video listo:', result.uploadUrl);
    },
  });

  useEffect(() => {
    if (videoRef.current && state.stream) {
      videoRef.current.srcObject = state.stream;
    }
  }, [state.stream]);

  useEffect(() => {
    actions.startPreview();
    return () => actions.cleanup();
  }, []);

  return (
    <div className="custom-recorder">
      {/* Vista previa de video */}
      <div className="video-container">
        <video ref={videoRef} autoPlay muted playsInline />

        {state.recordingState === 'recording' && (
          <div className="recording-indicator">
            <span className="rec-dot" />
            <span className="timer">{state.timer}</span>
          </div>
        )}

        {state.recordingState === 'countdown' && (
          <div className="countdown-overlay">
            <span className="countdown-number">{state.countdown}</span>
          </div>
        )}
      </div>

      {/* Medidor de audio */}
      <div className="audio-meter">
        <div
          className="audio-level"
          style={{
            width: `${audioLevel * 100}%`,
            backgroundColor: audioLevel > 0.8 ? '#ef4444' : '#22c55e'
          }}
        />
      </div>

      {/* Controles */}
      <div className="controls">
        {state.recordingState === 'idle' && (
          <>
            <button onClick={() => actions.startRecording('camera')}>
              Grabar Cámara
            </button>
            <button onClick={() => actions.startRecording('screen')}>
              Grabar Pantalla
            </button>
          </>
        )}

        {state.recordingState === 'recording' && (
          <>
            <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 */}
      {state.recordingState === 'idle' && (
        <div className="device-selection">
          <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 || 'Cámara'}
              </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 || 'Micrófono'}
              </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>
  );
}

Ejemplo Mínimo

function MinimalRecorder() {
  const { state, actions } = useVidtreoRecorder({
    apiKey: import.meta.env.VITE_VIDTREO_API_KEY,
  });

  return (
    <div>
      <video
        ref={(el) => el && state.stream && (el.srcObject = state.stream)}
        autoPlay
        muted
      />
      <button
        onClick={() =>
          state.recordingState === 'idle'
            ? actions.startRecording()
            : actions.stopRecording()
        }
      >
        {state.recordingState === 'idle' ? 'Grabar' : 'Detener'}
      </button>
    </div>
  );
}

Próximos Pasos

En esta página