'use client'; import { LiveKitRoom, VideoConference, formatChatMessageLinks, useToken, LocalUserChoices, } from '@livekit/components-react'; import { DeviceUnsupportedError, ExternalE2EEKeyProvider, LogLevel, Room, RoomConnectOptions, RoomOptions, VideoCodec, VideoPresets, } from 'livekit-client'; import type { NextPage } from 'next'; import dynamic from 'next/dynamic'; import Head from 'next/head'; import { useRouter } from 'next/router'; import * as React from 'react'; import { DebugMode } from '../../lib/Debug'; import { decodePassphrase, useServerUrl } from '../../lib/client-utils'; const PreJoinNoSSR = dynamic( async () => { return (await import('@livekit/components-react')).PreJoin; }, { ssr: false }, ); const Home: NextPage = () => { const router = useRouter(); const { name: roomName } = router.query; const [preJoinChoices, setPreJoinChoices] = React.useState( undefined, ); function handlePreJoinSubmit(values: LocalUserChoices) { setPreJoinChoices(values); } return ( <> LiveKit Meet
{roomName && !Array.isArray(roomName) && preJoinChoices ? ( { router.push('/'); }} > ) : (
console.log('error while setting up prejoin', err)} defaults={{ username: '', videoEnabled: true, audioEnabled: true, }} onSubmit={handlePreJoinSubmit} >
)}
); }; export default Home; type ActiveRoomProps = { userChoices: LocalUserChoices; roomName: string; region?: string; onLeave?: () => void; }; const ActiveRoom = ({ roomName, userChoices, onLeave }: ActiveRoomProps) => { const token = useToken(process.env.NEXT_PUBLIC_LK_TOKEN_ENDPOINT, roomName, { userInfo: { identity: userChoices.username, name: userChoices.username, }, }); const router = useRouter(); const { region, hq, codec } = router.query; const e2eePassphrase = typeof window !== 'undefined' && decodePassphrase(location.hash.substring(1)); const liveKitUrl = useServerUrl(region as string | undefined); const worker = typeof window !== 'undefined' && e2eePassphrase && new Worker(new URL('livekit-client/e2ee-worker', import.meta.url)); const e2eeEnabled = !!(e2eePassphrase && worker); const keyProvider = new ExternalE2EEKeyProvider(); const roomOptions = React.useMemo((): RoomOptions => { let videoCodec: VideoCodec | undefined = ( Array.isArray(codec) ? codec[0] : codec ?? 'av1' ) as VideoCodec; if (e2eeEnabled && (videoCodec === 'av1' || videoCodec === 'vp9')) { videoCodec = undefined; } console.log('video codec', videoCodec); return { videoCaptureDefaults: { deviceId: userChoices.videoDeviceId ?? undefined, resolution: hq === 'true' ? VideoPresets.h2160 : VideoPresets.h720, }, publishDefaults: { dtx: false, videoSimulcastLayers: hq === 'true' ? [VideoPresets.h1080, VideoPresets.h720] : [VideoPresets.h540, VideoPresets.h216], red: !e2eeEnabled, videoCodec, }, audioCaptureDefaults: { deviceId: userChoices.audioDeviceId ?? undefined, }, adaptiveStream: { pixelDensity: 'screen' }, dynacast: true, e2ee: e2eeEnabled ? { keyProvider, worker, } : undefined, }; }, [userChoices, hq, codec]); const room = React.useMemo(() => new Room(roomOptions), []); if (e2eeEnabled) { keyProvider.setKey(decodePassphrase(e2eePassphrase)); room.setE2EEEnabled(true).catch((e) => { if (e instanceof DeviceUnsupportedError) { alert( `You're trying to join an encrypted meeting, but your browser does not support it. Please update it to the latest version and try again.`, ); console.error(e); } }); } const connectOptions = React.useMemo((): RoomConnectOptions => { return { autoSubscribe: true, }; }, []); return ( <> {liveKitUrl && ( )} ); };