diff --git a/src/components/playground/Playground.tsx b/src/components/playground/Playground.tsx index 22a0acf6..e853d9b5 100644 --- a/src/components/playground/Playground.tsx +++ b/src/components/playground/Playground.tsx @@ -26,6 +26,9 @@ import { } from "@livekit/components-react"; import { ConnectionState, + ExternalE2EEKeyProvider, + RoomOptions, + Room, TokenSourceConfigurable, TokenSourceFetchOptions, Track, @@ -67,21 +70,41 @@ export default function Playground({ const [rpcPayload, setRpcPayload] = useState(""); const [hasConnected, setHasConnected] = useState(false); + const [e2eePassphrase, setE2eePassphrase] = useState(undefined); const [tokenFetchOptions, setTokenFetchOptions] = useState(); + + const keyProvider = useMemo(() => new ExternalE2EEKeyProvider(), []); + + const roomOptions = useMemo(() => { + if (!e2eePassphrase) return undefined; + + return { + encryption: { + keyProvider, + worker: new Worker( + new URL("livekit-client/e2ee-worker", import.meta.url), + ), + }, + }; + }, [e2eePassphrase, keyProvider]); + + const room = useMemo(() => { return new Room(roomOptions); }, [roomOptions]); + // initialize token fetch options from initial values, which can come from config useEffect(() => { // set initial options only if they haven't been set yet if (tokenFetchOptions !== undefined || initialAgentOptions === undefined) { return; } + setTokenFetchOptions({ agentName: initialAgentOptions?.agentName ?? "", agentMetadata: initialAgentOptions?.metadata ?? "", }); }, [tokenFetchOptions, initialAgentOptions, initialAgentOptions?.agentName, initialAgentOptions?.metadata]); - const session = useSession(tokenSource, tokenFetchOptions); + const session = useSession(tokenSource, {...tokenFetchOptions, room}); const { connectionState } = session; const agent = useAgent(session); const messages = useSessionMessages(session); @@ -104,6 +127,16 @@ export default function Playground({ } }, [autoConnect, hasConnected, startSession]); + useEffect(() => { + if (connectionState !== ConnectionState.Connected) return; + if (!e2eePassphrase) return; + + (async () => { + await keyProvider.setKey(encodeURIComponent(e2eePassphrase)); + await session.room.setE2EEEnabled(true); + })(); + }, [connectionState, e2eePassphrase, keyProvider, session.room]); + useEffect(() => { if (connectionState === ConnectionState.Connected) { session.room.localParticipant.setCameraEnabled( @@ -302,6 +335,16 @@ export default function Playground({ placeholder="None" editable={connectionState !== ConnectionState.Connected} /> + { + setE2eePassphrase(value === "" ? undefined : value); + }} + placeholder="None" + editable={connectionState !== ConnectionState.Connected} + />