Change env var names, add support for region query (#10)
This commit is contained in:
parent
e234a76293
commit
f4a301c116
8 changed files with 75 additions and 30 deletions
|
@ -5,7 +5,8 @@
|
||||||
LIVEKIT_API_KEY=devkey
|
LIVEKIT_API_KEY=devkey
|
||||||
LIVEKIT_API_SECRET=secret
|
LIVEKIT_API_SECRET=secret
|
||||||
|
|
||||||
|
# URL pointing to the LiveKit server.
|
||||||
|
LIVEKIT_URL=wss://my-livekit-project.livekit.cloud
|
||||||
|
|
||||||
## PUBLIC
|
## PUBLIC
|
||||||
NEXT_PUBLIC_LK_TOKEN_ENDPOINT=/api/token
|
NEXT_PUBLIC_LK_TOKEN_ENDPOINT=/api/token
|
||||||
NEXT_PUBLIC_LK_SERVER_URL=wss://my-livekit-project.livekit.cloud
|
|
|
@ -1,9 +1,9 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { useRoomContext } from '@livekit/components-react';
|
import { useRoomContext } from '@livekit/components-react';
|
||||||
import { setLogLevel } from 'livekit-client';
|
import { setLogLevel, LogLevel } from 'livekit-client';
|
||||||
|
|
||||||
export const useDebugMode = () => {
|
export const useDebugMode = ({ logLevel }: { logLevel?: LogLevel }) => {
|
||||||
setLogLevel('debug');
|
setLogLevel(logLevel ?? 'debug');
|
||||||
const room = useRoomContext();
|
const room = useRoomContext();
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
|
@ -16,7 +16,7 @@ export const useDebugMode = () => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const DebugMode = () => {
|
export const DebugMode = ({ logLevel }: { logLevel?: LogLevel }) => {
|
||||||
useDebugMode();
|
useDebugMode({ logLevel });
|
||||||
return <></>;
|
return <></>;
|
||||||
};
|
};
|
||||||
|
|
21
lib/client-utils.ts
Normal file
21
lib/client-utils.ts
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
import { useEffect, useState } from 'react';
|
||||||
|
|
||||||
|
export function useServerUrl(region?: string) {
|
||||||
|
const [serverUrl, setServerUrl] = useState<string | undefined>();
|
||||||
|
useEffect(() => {
|
||||||
|
let endpoint = `/api/url`;
|
||||||
|
if (region) {
|
||||||
|
endpoint += `?region=${region}`;
|
||||||
|
}
|
||||||
|
fetch(endpoint).then(async (res) => {
|
||||||
|
if (res.ok) {
|
||||||
|
const body = await res.json();
|
||||||
|
console.log(body);
|
||||||
|
setServerUrl(body.url);
|
||||||
|
} else {
|
||||||
|
throw Error('Error fetching server url, check server logs');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return serverUrl;
|
||||||
|
}
|
|
@ -5,10 +5,10 @@ export function getRoomClient(): RoomServiceClient {
|
||||||
return new RoomServiceClient(getLiveKitURL());
|
return new RoomServiceClient(getLiveKitURL());
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getLiveKitURL(region?: string): string {
|
export function getLiveKitURL(region?: string | string[]): string {
|
||||||
let targetKey = 'NEXT_PUBLIC_LK_SERVER_URL';
|
let targetKey = 'LIVEKIT_URL';
|
||||||
if (region) {
|
if (region && !Array.isArray(region)) {
|
||||||
targetKey = `NEXT_PUBLIC_LK_SERVER_URL${region}`.toUpperCase();
|
targetKey = `LIVEKIT_URL_${region}`.toUpperCase();
|
||||||
}
|
}
|
||||||
const url = process.env[targetKey];
|
const url = process.env[targetKey];
|
||||||
if (!url) {
|
if (!url) {
|
|
@ -12,6 +12,5 @@ export interface SessionProps {
|
||||||
|
|
||||||
export interface TokenResult {
|
export interface TokenResult {
|
||||||
identity: string;
|
identity: string;
|
||||||
url: string;
|
|
||||||
accessToken: string;
|
accessToken: string;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@ import { NextApiRequest, NextApiResponse } from 'next';
|
||||||
|
|
||||||
import { AccessToken } from 'livekit-server-sdk';
|
import { AccessToken } from 'livekit-server-sdk';
|
||||||
import type { AccessTokenOptions, VideoGrant } from 'livekit-server-sdk';
|
import type { AccessTokenOptions, VideoGrant } from 'livekit-server-sdk';
|
||||||
import { getLiveKitURL } from '../../lib/clients';
|
|
||||||
import { TokenResult } from '../../lib/types';
|
import { TokenResult } from '../../lib/types';
|
||||||
|
|
||||||
const apiKey = process.env.LIVEKIT_API_KEY;
|
const apiKey = process.env.LIVEKIT_API_KEY;
|
||||||
|
@ -19,7 +18,7 @@ const roomPattern = /\w{4}\-\w{4}/;
|
||||||
|
|
||||||
export default async function handleToken(req: NextApiRequest, res: NextApiResponse) {
|
export default async function handleToken(req: NextApiRequest, res: NextApiResponse) {
|
||||||
try {
|
try {
|
||||||
const { roomName, identity, name, metadata, region } = req.query;
|
const { roomName, identity, name, metadata } = req.query;
|
||||||
|
|
||||||
if (typeof identity !== 'string' || typeof roomName !== 'string') {
|
if (typeof identity !== 'string' || typeof roomName !== 'string') {
|
||||||
res.status(403).end();
|
res.status(403).end();
|
||||||
|
@ -32,9 +31,6 @@ export default async function handleToken(req: NextApiRequest, res: NextApiRespo
|
||||||
if (Array.isArray(metadata)) {
|
if (Array.isArray(metadata)) {
|
||||||
throw Error('provide max one metadata string');
|
throw Error('provide max one metadata string');
|
||||||
}
|
}
|
||||||
if (Array.isArray(region)) {
|
|
||||||
throw Error('provide max one region string');
|
|
||||||
}
|
|
||||||
|
|
||||||
// enforce room name to be xxxx-xxxx
|
// enforce room name to be xxxx-xxxx
|
||||||
// this is simple & naive way to prevent user from guessing room names
|
// this is simple & naive way to prevent user from guessing room names
|
||||||
|
@ -61,7 +57,6 @@ export default async function handleToken(req: NextApiRequest, res: NextApiRespo
|
||||||
const result: TokenResult = {
|
const result: TokenResult = {
|
||||||
identity,
|
identity,
|
||||||
accessToken: token,
|
accessToken: token,
|
||||||
url: getLiveKitURL(region),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
res.status(200).json(result);
|
res.status(200).json(result);
|
||||||
|
|
17
pages/api/url.ts
Normal file
17
pages/api/url.ts
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
import { NextApiRequest, NextApiResponse } from 'next';
|
||||||
|
import { getLiveKitURL } from '../../lib/server-utils';
|
||||||
|
|
||||||
|
export default async function handleServerUrl(req: NextApiRequest, res: NextApiResponse) {
|
||||||
|
try {
|
||||||
|
const { region } = req.query;
|
||||||
|
|
||||||
|
if (Array.isArray(region)) {
|
||||||
|
throw Error('provide max one region string');
|
||||||
|
}
|
||||||
|
const url = getLiveKitURL(region);
|
||||||
|
res.status(200).json({ url });
|
||||||
|
} catch (e) {
|
||||||
|
res.statusMessage = (e as Error).message;
|
||||||
|
res.status(500).end();
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,13 +5,15 @@ import {
|
||||||
useToken,
|
useToken,
|
||||||
VideoConference,
|
VideoConference,
|
||||||
} from '@livekit/components-react';
|
} from '@livekit/components-react';
|
||||||
import { RoomOptions } from 'livekit-client';
|
import { LogLevel, RoomOptions } from 'livekit-client';
|
||||||
|
|
||||||
import type { NextPage } from 'next';
|
import type { NextPage } from 'next';
|
||||||
import Head from 'next/head';
|
import Head from 'next/head';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
import { useMemo, useState } from 'react';
|
import { useMemo, useState } from 'react';
|
||||||
|
import { getLiveKitURL } from '../../lib/server-utils';
|
||||||
import { DebugMode } from '../../lib/Debug';
|
import { DebugMode } from '../../lib/Debug';
|
||||||
|
import { useServerUrl } from '../../lib/client-utils';
|
||||||
|
|
||||||
const Home: NextPage = () => {
|
const Home: NextPage = () => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
@ -58,6 +60,7 @@ export default Home;
|
||||||
type ActiveRoomProps = {
|
type ActiveRoomProps = {
|
||||||
userChoices: LocalUserChoices;
|
userChoices: LocalUserChoices;
|
||||||
roomName: string;
|
roomName: string;
|
||||||
|
region?: string;
|
||||||
onLeave?: () => void;
|
onLeave?: () => void;
|
||||||
};
|
};
|
||||||
const ActiveRoom = ({ roomName, userChoices, onLeave }: ActiveRoomProps) => {
|
const ActiveRoom = ({ roomName, userChoices, onLeave }: ActiveRoomProps) => {
|
||||||
|
@ -70,6 +73,11 @@ const ActiveRoom = ({ roomName, userChoices, onLeave }: ActiveRoomProps) => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const router = useRouter();
|
||||||
|
const { region } = router.query;
|
||||||
|
|
||||||
|
const liveKitUrl = useServerUrl(region as string | undefined);
|
||||||
|
|
||||||
const roomOptions = useMemo((): RoomOptions => {
|
const roomOptions = useMemo((): RoomOptions => {
|
||||||
return {
|
return {
|
||||||
videoCaptureDefaults: {
|
videoCaptureDefaults: {
|
||||||
|
@ -84,16 +92,20 @@ const ActiveRoom = ({ roomName, userChoices, onLeave }: ActiveRoomProps) => {
|
||||||
}, [userChoices]);
|
}, [userChoices]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<LiveKitRoom
|
<>
|
||||||
token={token}
|
{liveKitUrl && (
|
||||||
serverUrl={process.env.NEXT_PUBLIC_LK_SERVER_URL}
|
<LiveKitRoom
|
||||||
options={roomOptions}
|
token={token}
|
||||||
video={userChoices.videoEnabled}
|
serverUrl={liveKitUrl}
|
||||||
audio={userChoices.audioEnabled}
|
options={roomOptions}
|
||||||
onDisconnected={onLeave}
|
video={userChoices.videoEnabled}
|
||||||
>
|
audio={userChoices.audioEnabled}
|
||||||
<VideoConference />
|
onDisconnected={onLeave}
|
||||||
<DebugMode />
|
>
|
||||||
</LiveKitRoom>
|
<VideoConference />
|
||||||
|
<DebugMode logLevel={LogLevel.info} />
|
||||||
|
</LiveKitRoom>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue