45 lines
1.9 KiB
TypeScript
45 lines
1.9 KiB
TypeScript
import { AccessToken } from 'livekit-server-sdk';
|
|
import { saveSession } from './store';
|
|
|
|
// API Route (POST) que crea una sesión y devuelve token + studioUrl + id
|
|
// Env required: LIVEKIT_API_KEY, LIVEKIT_API_SECRET, optionally STUDIO_URL or STUDIO_BASE_URL
|
|
|
|
export async function POST(req: Request) {
|
|
try {
|
|
const body = await req.json();
|
|
const room = body.room || 'e2e-room';
|
|
const username = body.username || 'visual-runner';
|
|
const ttl = body.ttl || 300; // segundos
|
|
|
|
const apiKey = process.env.LIVEKIT_API_KEY;
|
|
const apiSecret = process.env.LIVEKIT_API_SECRET;
|
|
if (!apiKey || !apiSecret) {
|
|
return new Response(JSON.stringify({ error: 'LIVEKIT_API_KEY and LIVEKIT_API_SECRET required' }), { status: 500, headers: { 'content-type': 'application/json' } });
|
|
}
|
|
|
|
const at = new AccessToken(apiKey, apiSecret, { identity: username, name: username, ttl: `${ttl}s` });
|
|
at.addGrant({
|
|
roomJoin: true,
|
|
room: room,
|
|
canPublish: true,
|
|
canSubscribe: true,
|
|
canPublishSources: ['camera', 'microphone', 'screen'],
|
|
} as any);
|
|
|
|
const token = at.toJwt();
|
|
const id = `sess_${Date.now()}_${Math.random().toString(36).slice(2,8)}`;
|
|
|
|
// Construir studioUrl usando la estructura rooms/[roomName] por defecto
|
|
const studioBase = (process.env.STUDIO_BASE_URL || process.env.STUDIO_URL || process.env.BROADCAST_URL || '').trim();
|
|
const studioUrl = studioBase ? `${studioBase.replace(/\/$/, '')}/rooms/${encodeURIComponent(room)}` : '';
|
|
|
|
// Guardar sesión en store en memoria
|
|
saveSession(id, { token, room, username, studioUrl });
|
|
|
|
return new Response(JSON.stringify({ id, token, studioUrl }), { status: 200, headers: { 'content-type': 'application/json' } });
|
|
} catch (err) {
|
|
console.error('Error in /api/session', err);
|
|
return new Response(JSON.stringify({ error: 'internal' }), { status: 500, headers: { 'content-type': 'application/json' } });
|
|
}
|
|
}
|