10 KiB
🛠️ Integración de LiveKit en Next.js con Componentes y Estilo Similar a StreamYard
Para lograr una interfaz similar a la captura de StreamYard en tu proyecto Next.js con Vite (aunque Next.js ya tiene su propio bundler, si usas Vite para otras partes o pruebas, los componentes de LiveKit para React son la clave), la mejor estrategia es utilizar la librería oficial de LiveKit React Components y luego aplicar estilos para simular la disposición.
1. ⚙️ Configuración e Instalación
Aunque Next.js no usa Vite para el bundling principal, la integración de las librerías sigue los mismos pasos que cualquier aplicación React:
-
Instala el SDK y los Componentes de React:
npm install livekit-client @livekit/components-react @livekit/components-styles livekit-server-sdk # O usa yarn/pnpm: # yarn add livekit-client @livekit/components-react @livekit/components-styles livekit-server-sdklivekit-client: El SDK principal para la conectividad WebRTC.@livekit/components-react: Componentes de UI preconstruidos (la base para la interfaz).@livekit/components-styles: Estilos base para los componentes.livekit-server-sdk: Necesario para generar los tokens de acceso en tu API de Next.js.
-
Generación de Tokens (Backend): Crea una API Route en Next.js (por ejemplo, en
/app/api/token/route.tspara Next.js 13+) que uselivekit-server-sdkpara generar un token de acceso (JWT). Este token es necesario para que el cliente se conecte a la sala.Nota: Necesitarás tu
LIVEKIT_API_KEY,LIVEKIT_API_SECRETyLIVEKIT_URLconfigurados en tu archivo.env.local.
2. 🏗️ Estructura de Componentes de LiveKit
La interfaz de StreamYard que muestras se puede replicar usando una combinación de componentes de LiveKit y estilos CSS/Tailwind para el diseño de la cuadrícula.
-
Contenedor Principal de la Sala: Envuelve tu aplicación de video en el componente
<LiveKitRoom>.import '@livekit/components-styles'; import { LiveKitRoom, VideoConference } from '@livekit/components-react'; export default function MiSala({ token, serverUrl }) { return ( <LiveKitRoom token={token} serverUrl={serverUrl} connect={true} data-lk-theme="default" // Aplica el tema base > {/* Aquí van tus componentes personalizados */} <VideoConference /> </LiveKitRoom> ); } -
Paneles y Diseño (Simulación de la Interfaz):
La clave para simular la interfaz es usar CSS Grid o Flexbox en tu página de Next.js para colocar los componentes en las áreas que se ven en la captura:
| Área en StreamYard (Captura) | Componente de LiveKit o Custom | Descripción | | :--- | :--- | :--- | | Escenas/Mis Escenas (Izquierda) | Custom React Component | Un componente personalizado de Next.js para gestionar escenas, fuera de LiveKitRoom, pero que interactúa con el estado de la sala (por ejemplo, publicando/despublicando pistas o cambiando el layout). | | Vídeo Central (720p) | GridLayout / FocusLayout | Usa componentes de Layout de LiveKit, como
<GridLayout>o<FocusLayout>para renderizar la vista principal de los participantes. | | Controles (Micrófono, Cámara, etc.) | ControlBar / TrackToggle | El componente<ControlBar>de LiveKit es ideal para la barra de control inferior, ya que incluye botones listos para Mute/Cámara/Pantalla Compartida. | | Participantes (Cesar Mendivil) | ParticipantTile | Puedes usar<ParticipantLoop>para iterar sobre los participantes y renderizar un<ParticipantTile>para cada uno en la vista inferior o principal. | | Comentarios (Derecha) | Chat | El componente<Chat>de LiveKit proporciona una funcionalidad de chat lista para usar que se ajusta a la sección de "Comentarios". |
3. ✨ Estilizado y Componentes Personalizados
- Estilos: Importa los estilos base de LiveKit (
import '@livekit/components-styles';) y utiliza CSS Modules o Tailwind CSS (muy común en Next.js) para crear el diseño de cuadrícula principal y los estilos específicos (bordes, fondos, etc.) que se asemejan a StreamYard. Utiliza slots o envoltorios personalizados alrededor de los componentes de LiveKit si necesitas un estilo muy específico que no se puede lograr con la personalización de LiveKit. - Vite: Si estás usando Vite en paralelo para el frontend, la instalación y el uso de los componentes de React son idénticos.
Aquí tienes un video que muestra cómo hacer una aplicación de videollamadas con Next.js y LiveKit. Video Call Application with Next js and LiveKit | 2024 es un tutorial que te guiará a través de la creación de una aplicación de videollamadas con Next.js y LiveKit.
http://googleusercontent.com/youtube_content/0
🔑 Generación de Tokens con livekit-server-sdk
Para generar un token de acceso con livekit-server-sdk en tu backend (como en una API Route de Next.js), necesitas seguir tres pasos clave: configurar el SDK, definir la identidad del usuario y generar el token con los permisos (roles) adecuados.
Aquí te muestro un ejemplo completo en TypeScript/JavaScript:
1. 🛠️ Instalación y Configuración
Asegúrate de tener el SDK instalado:
npm install livekit-server-sdk
Y que tus credenciales estén configuradas (usualmente en variables de entorno):
LIVEKIT_API_KEYLIVEKIT_API_SECRETLIVEKIT_URL(la URL de tu servidor LiveKit, e.g.,wss://misuperapp.livekit.cloud)
2. 📝 Ejemplo de Código para Generar un Token
Utiliza la clase AccessToken para crear un nuevo token, incluyendo los permisos para la sala.
import { AccessToken, RoomServiceClient } from 'livekit-server-sdk';
import type { VideoGrant } from 'livekit-server-sdk';
// ----------------------------------------------------
// 1. Obtén las credenciales de tus variables de entorno
// ----------------------------------------------------
const apiKey = process.env.LIVEKIT_API_KEY;
const apiSecret = process.env.LIVEKIT_API_SECRET;
// const livekitUrl = process.env.LIVEKIT_URL; // Solo es necesaria si usas RoomServiceClient
if (!apiKey || !apiSecret) {
throw new Error('LIVEKIT_API_KEY y LIVEKIT_API_SECRET deben estar configuradas.');
}
/**
* Genera un token de acceso para un usuario específico en una sala.
* @param roomName El nombre de la sala a la que se conectará el usuario.
* @param identity La identidad única del usuario (e.g., ID de usuario o nombre de usuario).
* @param canPublish Permiso para publicar video/audio/pantalla (típico de un participante).
* @param canSubscribe Permiso para ver/escuchar a otros participantes (siempre debe ser true).
* @param roomJoin Permiso para unirse a la sala.
* @returns El token JWT generado (string).
*/
export function generateLiveKitToken(
roomName: string,
identity: string,
canPublish: boolean,
isModerator: boolean = false,
): string {
// ----------------------------------------------------
// 2. Crea una instancia de AccessToken
// ----------------------------------------------------
const at = new AccessToken(apiKey!, apiSecret!, {
identity: identity,
// (Opcional) Nombre del usuario que se mostrará en la UI
name: identity,
// (Opcional) Define un tiempo de expiración
ttl: '10m',
});
// ----------------------------------------------------
// 3. Define los permisos (VideoGrant)
// ----------------------------------------------------
const grant: VideoGrant = {
roomJoin: true, // Permitir unirse a la sala
room: roomName, // El nombre de la sala específica
// Permisos de publicación/suscripción
canPublish: canPublish, // Permite publicar audio/video/pantalla
canSubscribe: true, // Permite recibir pistas de otros
// (Opcional) Permisos avanzados para moderadores
canUpdate: isModerator, // Permite actualizar la sala (mutear a otros, etc.)
roomAdmin: isModerator, // Permisos de administrador de sala
canPublishSources: ['camera', 'microphone', 'screen'], // Fuentes permitidas
};
at.addGrant(grant);
// ----------------------------------------------------
// 4. To string: genera el token JWT
// ----------------------------------------------------
const token = at.toJwt();
console.log(`Token generado para ${identity} en sala ${roomName}:`, token);
return token;
}
3. 🌐 Uso Típico en Next.js (API Route)
En una API Route de Next.js (/api/livekit/token):
import { NextRequest, NextResponse } from 'next/server';
import { generateLiveKitToken } from './utils'; // Asume que el código anterior está en 'utils'
export async function POST(req: NextRequest) {
try {
const { roomName, identity, isPublisher } = await req.json();
if (!roomName || !identity) {
return NextResponse.json({ error: 'Faltan parámetros: roomName e identity' }, { status: 400 });
}
// Un publicador tiene 'canPublish: true', un espectador tendría 'canPublish: false'
const token = generateLiveKitToken(roomName, identity, isPublisher);
return NextResponse.json({ token }, { status: 200 });
} catch (error) {
console.error('Error generando token:', error);
return NextResponse.json({ error: 'Error interno del servidor' }, { status: 500 });
}
}
Variables de entorno útiles
Además de las variables necesarias para la generación de tokens (LIVEKIT_API_KEY, LIVEKIT_API_SECRET, LIVEKIT_URL), el paquete del Broadcast Panel expone una variable específica para controlar un "preflight" que provoca el prompt de permisos de cámara/micrófono antes de intentar conectar al estudio.
VITE_STUDIO_PREFLIGHT(opcional): controla si se ejecuta un preflight que llama anavigator.mediaDevices.getUserMediapara forzar el prompt de permisos antes de la negociación WebRTC.- Valores válidos:
1/true(habilitado por defecto),0/false(deshabilitado). - Uso típico: en desarrollo puedes dejarlo habilitado para asegurar que el navegador solicite permisos al entrar al estudio; en entornos de pruebas automáticas o cuando no quieres el prompt automático, pon
VITE_STUDIO_PREFLIGHT=0.
- Valores válidos:
Hemos añadido un ejemplo de archivo de entorno en:
packages/broadcast-panel/.env.example
que incluye VITE_STUDIO_PREFLIGHT=1 y otras variables de ejemplo que el paquete puede leer (p. ej. VITE_BACKEND_API_URL, VITE_BACKEND_TOKENS_URL, VITE_BROADCASTPANEL_URL, VITE_LIVEKIT_WS_URL).