From 8a53ea11e1b3d4a2b71398e94e9f1935811ca249 Mon Sep 17 00:00:00 2001 From: Jonas Schell Date: Wed, 11 Sep 2024 18:58:15 +0200 Subject: [PATCH] wip --- frontend/app/connection-details/route.ts | 54 ++++++++++++++---------- frontend/app/page.tsx | 49 ++++++++++----------- frontend/package.json | 1 + frontend/pnpm-lock.yaml | 53 +++++++++++++++++++++++ 4 files changed, 111 insertions(+), 46 deletions(-) diff --git a/frontend/app/connection-details/route.ts b/frontend/app/connection-details/route.ts index 48d73e1c..87ae9dbf 100644 --- a/frontend/app/connection-details/route.ts +++ b/frontend/app/connection-details/route.ts @@ -1,7 +1,9 @@ -import { randomString } from '@/lib/client-utils'; -import { ConnectionDetails } from '@/lib/types'; -import { AccessToken, AccessTokenOptions, VideoGrant } from 'livekit-server-sdk'; -import { NextRequest, NextResponse } from 'next/server'; +import { + AccessToken, + AccessTokenOptions, + VideoGrant, +} from "livekit-server-sdk"; +import { NextRequest, NextResponse } from "next/server"; const API_KEY = process.env.LIVEKIT_API_KEY; const API_SECRET = process.env.LIVEKIT_API_SECRET; @@ -10,34 +12,39 @@ const LIVEKIT_URL = process.env.LIVEKIT_URL; export async function GET(request: NextRequest) { try { // Parse query parameters - const roomName = request.nextUrl.searchParams.get('roomName'); - const participantName = request.nextUrl.searchParams.get('participantName'); - const metadata = request.nextUrl.searchParams.get('metadata') ?? ''; - const region = request.nextUrl.searchParams.get('region'); + const roomName = request.nextUrl.searchParams.get("roomName"); + const participantName = request.nextUrl.searchParams.get("participantName"); + const metadata = request.nextUrl.searchParams.get("metadata") ?? ""; + const region = request.nextUrl.searchParams.get("region"); const livekitServerUrl = region ? getLiveKitURL(region) : LIVEKIT_URL; if (livekitServerUrl === undefined) { - throw new Error('Invalid region'); + throw new Error("Invalid region"); } - if (typeof roomName !== 'string') { - return new NextResponse('Missing required query parameter: roomName', { status: 400 }); - } - if (participantName === null) { - return new NextResponse('Missing required query parameter: participantName', { status: 400 }); - } + // if (typeof roomName !== "string") { + // return new NextResponse("Missing required query parameter: roomName", { + // status: 400, + // }); + // } + // if (participantName === null) { + // return new NextResponse( + // "Missing required query parameter: participantName", + // { status: 400 } + // ); + // } // Generate participant token const participantToken = await createParticipantToken( { - identity: `${participantName}__${randomString(4)}`, - name: participantName, + identity: `${participantName}__${Math.round(Math.random() * 10000)}`, + name: "participantName", metadata, }, - roomName, + "roomName" ); // Return connection details - const data: ConnectionDetails = { + const data = { serverUrl: livekitServerUrl, roomName: roomName, participantToken: participantToken, @@ -51,9 +58,12 @@ export async function GET(request: NextRequest) { } } -function createParticipantToken(userInfo: AccessTokenOptions, roomName: string) { +function createParticipantToken( + userInfo: AccessTokenOptions, + roomName: string +) { const at = new AccessToken(API_KEY, API_SECRET, userInfo); - at.ttl = '5m'; + at.ttl = "5m"; const grant: VideoGrant = { room: roomName, roomJoin: true, @@ -69,7 +79,7 @@ function createParticipantToken(userInfo: AccessTokenOptions, roomName: string) * Get the LiveKit server URL for the given region. */ function getLiveKitURL(region: string | null): string { - let targetKey = 'LIVEKIT_URL'; + let targetKey = "LIVEKIT_URL"; if (region) { targetKey = `LIVEKIT_URL_${region}`.toUpperCase(); } diff --git a/frontend/app/page.tsx b/frontend/app/page.tsx index b13f9fce..fc22242c 100644 --- a/frontend/app/page.tsx +++ b/frontend/app/page.tsx @@ -25,14 +25,18 @@ function SimpleVoiceAssistant() { export default function Page() { const [shouldConnect, setShouldConnect] = useState(false); + const [details, setDetails] = useState(undefined); const handlePreJoinSubmit = useCallback(async () => { const url = new URL( - process.env.NEXT_PUBLIC_CONN_DETAILS_ENDPOINT, + process.env.NEXT_PUBLIC_CONN_DETAILS_ENDPOINT!, window.location.origin ); const connectionDetailsResp = await fetch(url.toString()); const connectionDetailsData = await connectionDetailsResp.json(); + console.log({ connectionDetailsData }); + + setDetails(connectionDetailsData); }, []); const onDeviceFailure = (e?: MediaDeviceFailure) => { @@ -44,30 +48,27 @@ export default function Page() { return (
- setShouldConnect(false)} - className="" - > -
- {shouldConnect ? ( + {details ? ( + setShouldConnect(false)} + className="" + > +
- ) : ( - - )} -
- - -
+
+ + +
+ ) : ( + + )}
); } diff --git a/frontend/package.json b/frontend/package.json index 8692dadc..4ada4ae5 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -12,6 +12,7 @@ "@livekit/components-react": "^2.5.1", "@livekit/components-styles": "^1.1.1", "livekit-client": "^2.5.1", + "livekit-server-sdk": "^2.6.1", "next": "14.2.9", "react": "^18", "react-dom": "^18" diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index 2fff0901..bd703bcf 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -17,6 +17,9 @@ importers: livekit-client: specifier: ^2.5.1 version: 2.5.1 + livekit-server-sdk: + specifier: ^2.6.1 + version: 2.6.1 next: specifier: 14.2.9 version: 14.2.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -451,6 +454,14 @@ packages: resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} engines: {node: '>= 6'} + camelcase-keys@9.1.3: + resolution: {integrity: sha512-Rircqi9ch8AnZscQcsA1C47NFdaO3wukpmIRzYcDOrmvgt78hM/sj5pZhZNec2NM12uk5vTwRHZ4anGcrC4ZTg==} + engines: {node: '>=16'} + + camelcase@8.0.0: + resolution: {integrity: sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==} + engines: {node: '>=16'} + caniuse-lite@1.0.30001660: resolution: {integrity: sha512-GacvNTTuATm26qC74pt+ad1fW15mlQ/zuTzzY1ZoIzECTP8HURDfF43kNxPgf7H1jmelCBQTTbBNxdSXOA7Bqg==} @@ -1020,6 +1031,9 @@ packages: resolution: {integrity: sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==} hasBin: true + jose@5.8.0: + resolution: {integrity: sha512-E7CqYpL/t7MMnfGnK/eg416OsFCVUrU/Y3Vwe7QjKhu/BkS1Ms455+2xsqZQVN57/U2MHMBvEb5SrmAZWAIntA==} + js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -1072,6 +1086,10 @@ packages: livekit-client@2.5.1: resolution: {integrity: sha512-D7BzGoO3nc7/H2pEP9hseTjpzfgUoQ1AdeUNdlM7XNEywvorY1UR6RhOWH9UvycM/D5tIIRx7OvhxzpVfHE3TA==} + livekit-server-sdk@2.6.1: + resolution: {integrity: sha512-j/8TOlahIyWnycNkuSzTv6q+win4JTbDGNH48iMsZDMnJBks9hhC9UwAO4ES42sAorIAxGkrH58hxt4KdTkZaQ==} + engines: {node: '>=19'} + locate-path@6.0.0: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} @@ -1097,6 +1115,10 @@ packages: lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + map-obj@5.0.0: + resolution: {integrity: sha512-2L3MIgJynYrZ3TYMriLDLWocz15okFakV6J12HXvMXDHui2x/zgChzg1u9mFFGbbGWE+GsLpQByt4POb9Or+uA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} @@ -1322,6 +1344,10 @@ packages: queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + quick-lru@6.1.2: + resolution: {integrity: sha512-AAFUA5O1d83pIHEhJwWCq/RQcRukCkn/NSm2QsTEMle5f2hP0ChI2+3Xb051PZCkLryI/Ir1MVKviT2FIloaTQ==} + engines: {node: '>=12'} + react-dom@18.3.1: resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} peerDependencies: @@ -1569,6 +1595,10 @@ packages: resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} engines: {node: '>=10'} + type-fest@4.26.1: + resolution: {integrity: sha512-yOGpmOAL7CkKe/91I5O3gPICmJNLJ1G4zFYVAsRHg7M64biSnPtRj0WNQt++bRkjYOqjWXrhnUw1utzmVErAdg==} + engines: {node: '>=16'} + typed-array-buffer@1.0.2: resolution: {integrity: sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==} engines: {node: '>= 0.4'} @@ -2081,6 +2111,15 @@ snapshots: camelcase-css@2.0.1: {} + camelcase-keys@9.1.3: + dependencies: + camelcase: 8.0.0 + map-obj: 5.0.0 + quick-lru: 6.1.2 + type-fest: 4.26.1 + + camelcase@8.0.0: {} + caniuse-lite@1.0.30001660: {} chalk@4.1.2: @@ -2839,6 +2878,8 @@ snapshots: jiti@1.21.6: {} + jose@5.8.0: {} + js-tokens@4.0.0: {} js-yaml@4.1.0: @@ -2894,6 +2935,12 @@ snapshots: typed-emitter: 2.1.0 webrtc-adapter: 9.0.1 + livekit-server-sdk@2.6.1: + dependencies: + '@livekit/protocol': 1.20.1 + camelcase-keys: 9.1.3 + jose: 5.8.0 + locate-path@6.0.0: dependencies: p-locate: 5.0.0 @@ -2912,6 +2959,8 @@ snapshots: lru-cache@10.4.3: {} + map-obj@5.0.0: {} + merge2@1.4.1: {} micromatch@4.0.8: @@ -3126,6 +3175,8 @@ snapshots: queue-microtask@1.2.3: {} + quick-lru@6.1.2: {} + react-dom@18.3.1(react@18.3.1): dependencies: loose-envify: 1.4.0 @@ -3416,6 +3467,8 @@ snapshots: type-fest@0.20.2: {} + type-fest@4.26.1: {} + typed-array-buffer@1.0.2: dependencies: call-bind: 1.0.7