AvanzaCast/packages/studio-panel/docs/BROADCAST_STUDIO_UI.md
Cesar Mendivil 78e83b46dd feat: Implement main Studio component with user authentication and connection handling
feat: Create BroadcastStudio component as the main UI container for broadcasting

feat: Develop ControlPanel component for managing broadcast controls and layouts

feat: Add LiveKitBroadcastWrapper to encapsulate LiveKitRoom and manage broadcasting

feat: Implement StreamView component for rendering video output with overlays and layouts

feat: Create SceneContext for managing scene configurations and layouts

chore: Update index exports for broadcast components
2025-11-07 23:22:35 -07:00

6.3 KiB
Raw Blame History

LiveKit Broadcast Studio UI - Documentación

📋 Descripción General

Sistema de interfaz de usuario para un estudio de producción de video en vivo estilo StreamYard, construido con React, TypeScript y LiveKit Components.

🏗️ Arquitectura

Estructura de Componentes

BroadcastStudio (Contenedor Principal)
├── SceneProvider (Context)
│   ├── StreamView (Visualización - CONSUMIDOR)
│   │   ├── Layouts dinámicos basados en sceneConfig
│   │   ├── Renderizado de participantes (LiveKit)
│   │   └── Overlays (logos, lower thirds)
│   │
│   └── ControlPanel (Controles - MODIFICADOR)
│       ├── LocalControls (Izquierda - Vista local + Presentar)
│       ├── ScrollableLayoutsContainer (Centro - Botones de layouts)
│       └── ActionControls (Derecha - Config y recursos)

Sistema de Estado (SceneContext)

Ubicación: src/context/SceneContext.tsx

El contexto centralizado gestiona toda la configuración de escenas:

interface SceneConfig {
  participantLayout: ParticipantLayoutType  // Tipo de layout activo
  mediaSource: MediaSourceType | null      // Contenido adicional (screen, file, etc)
  overlays: OverlayConfig                  // Logos, lower thirds, etc
}

Regla de oro:

  • ControlPanel: Único componente que MODIFICA sceneConfig
  • StreamView: Único componente que CONSUME sceneConfig para renderizar

🎨 Componentes Principales

1. StreamView

Archivo: src/components/broadcast/StreamView.tsx

Renderiza la salida final de video en formato 16:9.

Características:

  • Aspecto ratio fijo 16:9 (aspect-ratio: 16 / 9)
  • 6 layouts predefinidos:
    • grid_4: Grid 2×2
    • grid_6: Grid 3×2
    • focus_side: Foco principal + sidebar
    • side_by_side: Dos participantes lado a lado
    • presentation: Pantalla compartida + speaker pequeño
    • single_speaker: Un solo participante
  • Sistema de overlays configurable
  • Integración con hooks de LiveKit (useParticipants, useTracks)

2. ControlPanel

Archivo: src/components/broadcast/ControlPanel.tsx

Panel de control interactivo dividido en 3 secciones.

Estructura CSS:

.control-panel-wrapper {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
}

2.1 LocalControls (Izquierda)

  • Vista previa del usuario local
  • Botón "Presentar"
  • flex-shrink: 0 (ancho fijo)

2.2 ScrollableLayoutsContainer (Centro)

  • Scroll horizontal de botones de layouts
  • flex-grow: 1; overflow-x: auto; overflow-y: hidden
  • Botones con flex-shrink: 0 en fila única

2.3 ActionControls (Derecha)

  • Botones de acción (Editor, Config, Añadir)
  • flex-shrink: 0 (ancho fijo)

3. BroadcastStudio

Archivo: src/components/broadcast/BroadcastStudio.tsx

Contenedor principal que alinea todo.

CSS clave:

.main-app-container {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.stream-view-container,
.control-panel-wrapper {
  width: 100%;
  max-width: 1200px; /* Mismo ancho máximo para ambos */
}

4. LiveKitBroadcastWrapper

Archivo: src/components/broadcast/LiveKitBroadcastWrapper.tsx

Wrapper que conecta el BroadcastStudio con LiveKit.

🔧 Uso

Integración Básica

import { LiveKitBroadcastWrapper } from './components/broadcast'

function App() {
  return (
    <LiveKitBroadcastWrapper
      token="your-livekit-token"
      serverUrl="wss://your-server.com"
      userName="Usuario"
      roomName="sala-demo"
      onDisconnect={() => console.log('Desconectado')}
    />
  )
}

Uso Standalone (sin LiveKit)

import { BroadcastStudio } from './components/broadcast'
import { LiveKitRoom } from '@livekit/components-react'

function App() {
  return (
    <LiveKitRoom token={token} serverUrl={serverUrl}>
      <BroadcastStudio />
    </LiveKitRoom>
  )
}

Acceso al Contexto de Escenas

import { useScene } from './context/SceneContext'

function MiComponente() {
  const { sceneConfig, applyPreset, updateOverlays } = useScene()
  
  // Aplicar un preset
  const handleChangeLayout = () => {
    applyPreset('FOCUS_SIDE')
  }
  
  // Actualizar overlays
  const handleToggleLogo = () => {
    updateOverlays({ showLogo: !sceneConfig.overlays.showLogo })
  }
  
  return (...)
}

📦 Presets de Layouts

Definidos en SceneContext.tsx:

PRESET_LAYOUTS = {
  GRID_4: { participantLayout: 'grid_4', ... },
  GRID_6: { participantLayout: 'grid_6', ... },
  FOCUS_SIDE: { participantLayout: 'focus_side', ... },
  SIDE_BY_SIDE: { participantLayout: 'side_by_side', ... },
  PRESENTATION: { participantLayout: 'presentation', ... },
  SINGLE_SPEAKER: { participantLayout: 'single_speaker', ... },
}

🎯 Próximos Pasos

Features Pendientes

  • Integración con LiveKit Egress para grabación/streaming
  • Editor visual de escenas (modal con drag & drop)
  • Gestión de overlays personalizado
  • Soporte para múltiples cámaras por participante
  • Transiciones animadas entre layouts
  • Guardado/carga de escenas personalizadas

Mejoras de UX

  • Tooltips informativos en botones de layout
  • Preview en miniatura de cada layout
  • Keyboard shortcuts para cambio rápido
  • Indicador visual del layout activo más prominente
  • Confirmación antes de cambios críticos

🐛 Debugging

Verificar estado de escenas

// En DevTools Console:
window.__SCENE_DEBUG__ = true

// O agregar en tu componente:
console.log('[SceneDebug]', sceneConfig)

Logs de LiveKit

Los hooks de LiveKit (useParticipants, useTracks) ya incluyen logs internos. Para más detalle, habilitar en LiveKitRoom:

<LiveKitRoom logLevel="debug" ... />

📝 Notas de Implementación

  1. Aspecto Ratio: StreamView usa aspect-ratio: 16/9 nativo de CSS (compatibilidad moderna)
  2. Scroll Horizontal: El scroll en LayoutsContainer es solo horizontal para mejor UX
  3. Flexibilidad: Todos los componentes son modulares y pueden usarse independientemente
  4. Performance: Los layouts se renderizan condicionalmente para evitar re-renders innecesarios
  5. TypeScript: Todo el código está fuertemente tipado para mejor DX

Creado el: 7 de noviembre de 2025
Versión: 1.0.0
Stack: React + TypeScript + LiveKit + Tailwind CSS