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
235 lines
6.3 KiB
Markdown
235 lines
6.3 KiB
Markdown
# 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:
|
||
|
||
```typescript
|
||
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:**
|
||
```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:**
|
||
```css
|
||
.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
|
||
|
||
```tsx
|
||
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)
|
||
|
||
```tsx
|
||
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
|
||
|
||
```tsx
|
||
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`:
|
||
|
||
```typescript
|
||
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
|
||
```tsx
|
||
// 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:
|
||
```tsx
|
||
<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
|