mirror of https://github.com/msgbyte/tailchat
feat(livekit): add basic room and service endpoint
parent
79a5b76ba4
commit
78407f04d5
Binary file not shown.
After Width: | Height: | Size: 323 B |
@ -0,0 +1,65 @@
|
||||
import { LoadingSpinner } from '@capital/component';
|
||||
import {
|
||||
formatChatMessageLinks,
|
||||
LiveKitRoom,
|
||||
LocalUserChoices,
|
||||
VideoConference,
|
||||
} from '@livekit/components-react';
|
||||
import { RoomOptions, VideoPresets } from 'livekit-client';
|
||||
import React, { useMemo } from 'react';
|
||||
import { useServerUrl } from '../utils/useServerUrl';
|
||||
import { useToken } from '../utils/useToken';
|
||||
|
||||
type ActiveRoomProps = {
|
||||
userChoices: LocalUserChoices;
|
||||
roomName: string;
|
||||
region?: string;
|
||||
onLeave?: () => void;
|
||||
hq?: boolean;
|
||||
};
|
||||
export const ActiveRoom: React.FC<ActiveRoomProps> = React.memo((props) => {
|
||||
const { roomName, userChoices, onLeave, hq } = props;
|
||||
|
||||
const token = useToken(roomName);
|
||||
const liveKitUrl = useServerUrl();
|
||||
|
||||
const roomOptions = useMemo((): RoomOptions => {
|
||||
return {
|
||||
videoCaptureDefaults: {
|
||||
deviceId: userChoices.videoDeviceId ?? undefined,
|
||||
resolution: hq === true ? VideoPresets.h2160 : VideoPresets.h720,
|
||||
},
|
||||
publishDefaults: {
|
||||
videoSimulcastLayers:
|
||||
hq === true
|
||||
? [VideoPresets.h1080, VideoPresets.h720]
|
||||
: [VideoPresets.h540, VideoPresets.h216],
|
||||
},
|
||||
audioCaptureDefaults: {
|
||||
deviceId: userChoices.audioDeviceId ?? undefined,
|
||||
},
|
||||
adaptiveStream: { pixelDensity: 'screen' },
|
||||
dynacast: true,
|
||||
};
|
||||
}, [userChoices, hq]);
|
||||
|
||||
return (
|
||||
<>
|
||||
{token && liveKitUrl ? (
|
||||
<LiveKitRoom
|
||||
token={token}
|
||||
serverUrl={liveKitUrl}
|
||||
options={roomOptions}
|
||||
video={userChoices.videoEnabled}
|
||||
audio={userChoices.audioEnabled}
|
||||
onDisconnected={onLeave}
|
||||
>
|
||||
<VideoConference chatMessageFormatter={formatChatMessageLinks} />
|
||||
</LiveKitRoom>
|
||||
) : (
|
||||
<LoadingSpinner />
|
||||
)}
|
||||
</>
|
||||
);
|
||||
});
|
||||
ActiveRoom.displayName = 'ActiveRoom';
|
@ -0,0 +1,14 @@
|
||||
import { postRequest } from '@capital/common';
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
export function useServerUrl() {
|
||||
const [serverUrl, setServerUrl] = useState<string | undefined>();
|
||||
|
||||
useEffect(() => {
|
||||
postRequest('/plugin:com.msgbyte.livekit/url').then(({ data }) => {
|
||||
setServerUrl(data.url);
|
||||
});
|
||||
}, []);
|
||||
|
||||
return serverUrl;
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
import { postRequest } from '@capital/common';
|
||||
import type { UseTokenOptions } from '@livekit/components-react';
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
export function useToken(roomName: string, options: UseTokenOptions = {}) {
|
||||
const [token, setToken] = useState<string | undefined>(undefined);
|
||||
|
||||
useEffect(() => {
|
||||
const tokenFetcher = async () => {
|
||||
const params = new URLSearchParams({ ...options.userInfo, roomName });
|
||||
const { data } = await postRequest(
|
||||
`/plugin:com.msgbyte.livekit/generateToken?${params.toString()}`
|
||||
);
|
||||
const { accessToken } = data;
|
||||
setToken(accessToken);
|
||||
};
|
||||
|
||||
tokenFetcher();
|
||||
}, [roomName, options]);
|
||||
|
||||
return token;
|
||||
}
|
Loading…
Reference in New Issue