Build EC room use method (#1108)

* Build custom useRoom
This commit is contained in:
Enrico Schwendig 2023-06-14 15:03:38 +02:00 committed by GitHub
parent 20a4e0bd09
commit 20c9c09258
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 151 additions and 12 deletions

View file

@ -16,7 +16,6 @@ limitations under the License.
import { ResizeObserver } from "@juggle/resize-observer";
import {
useLiveKitRoom,
useLocalParticipant,
useParticipants,
useToken,
@ -79,6 +78,7 @@ import { InviteModal } from "./InviteModal";
import { useRageshakeRequestModal } from "../settings/submit-rageshake";
import { RageshakeRequestModal } from "./RageshakeRequestModal";
import { VideoTile } from "../video-grid/VideoTile";
import { useRoom } from "./useRoom";
const canScreenshare = "getDisplayMedia" in (navigator.mediaDevices ?? {});
// There is currently a bug in Safari our our code with cloning and sending MediaStreams
@ -86,6 +86,16 @@ const canScreenshare = "getDisplayMedia" in (navigator.mediaDevices ?? {});
// For now we can disable screensharing in Safari.
const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
const onConnectedCallback = (): void => {
console.log("connected to LiveKit room");
};
const onDisconnectedCallback = (): void => {
console.log("disconnected from LiveKit room");
};
const onErrorCallback = (err: Error): void => {
console.error("error connecting to LiveKit room", err);
};
interface LocalUserChoices {
videoMuted: boolean;
audioMuted: boolean;
@ -150,22 +160,16 @@ export function InCallView({
options
);
// Uses a hook to connect to the LiveKit room (on unmount the room will be left) and publish local media tracks (default).
useLiveKitRoom({
useRoom({
token,
serverUrl: Config.get().livekit.server_url,
room: livekitRoom,
audio: !userChoices.audioMuted,
video: !userChoices.videoMuted,
onConnected: () => {
console.log("connected to LiveKit room");
},
onDisconnected: () => {
console.log("disconnected from LiveKit room");
},
onError: (err) => {
console.error("error connecting to LiveKit room", err);
},
simulateParticipants: 10,
onConnected: onConnectedCallback,
onDisconnected: onDisconnectedCallback,
onError: onErrorCallback,
});
const screenSharingTracks = useTracks(

135
src/room/useRoom.ts Normal file
View file

@ -0,0 +1,135 @@
import * as React from "react";
import {
ConnectionState,
MediaDeviceFailure,
Room,
RoomEvent,
} from "livekit-client";
import { LiveKitRoomProps } from "@livekit/components-react/src/components/LiveKitRoom";
import { logger } from "matrix-js-sdk/src/logger";
const defaultRoomProps: Partial<LiveKitRoomProps> = {
connect: true,
audio: false,
video: false,
};
export function useRoom(props: LiveKitRoomProps) {
const {
token,
serverUrl,
options,
room: passedRoom,
connectOptions,
connect,
audio,
video,
screen,
onConnected,
onDisconnected,
onError,
onMediaDeviceFailure,
} = { ...defaultRoomProps, ...props };
if (options && passedRoom) {
logger.warn(
"when using a manually created room, the options object will be ignored. set the desired options directly when creating the room instead."
);
}
const [room, setRoom] = React.useState<Room | undefined>();
React.useEffect(() => {
setRoom(passedRoom ?? new Room(options));
}, [options, passedRoom]);
React.useEffect(() => {
if (!room) return;
const onSignalConnected = () => {
const localP = room.localParticipant;
try {
logger.debug("trying to publish local tracks");
localP.setMicrophoneEnabled(
!!audio,
typeof audio !== "boolean" ? audio : undefined
);
localP.setCameraEnabled(
!!video,
typeof video !== "boolean" ? video : undefined
);
localP.setScreenShareEnabled(
!!screen,
typeof screen !== "boolean" ? screen : undefined
);
} catch (e) {
logger.warn(e);
onError?.(e as Error);
}
};
const onMediaDeviceError = (e: Error) => {
const mediaDeviceFailure = MediaDeviceFailure.getFailure(e);
onMediaDeviceFailure?.(mediaDeviceFailure);
};
room.on(RoomEvent.SignalConnected, onSignalConnected);
room.on(RoomEvent.MediaDevicesError, onMediaDeviceError);
return () => {
room.off(RoomEvent.SignalConnected, onSignalConnected);
room.off(RoomEvent.MediaDevicesError, onMediaDeviceError);
};
}, [room, audio, video, screen, onError, onMediaDeviceFailure]);
React.useEffect(() => {
if (!room) return;
if (!token) {
logger.debug("no token yet");
return;
}
if (!serverUrl) {
logger.warn("no livekit url provided");
onError?.(Error("no livekit url provided"));
return;
}
if (connect) {
logger.debug("connecting");
room.connect(serverUrl, token, connectOptions).catch((e) => {
logger.warn(e);
onError?.(e as Error);
});
} else {
logger.debug("disconnecting because connect is false");
room.disconnect();
}
}, [connect, token, connectOptions, room, onError, serverUrl]);
React.useEffect(() => {
if (!room) return;
const connectionStateChangeListener = (state: ConnectionState) => {
switch (state) {
case ConnectionState.Disconnected:
if (onDisconnected) onDisconnected();
break;
case ConnectionState.Connected:
if (onConnected) onConnected();
break;
default:
break;
}
};
room.on(RoomEvent.ConnectionStateChanged, connectionStateChangeListener);
return () => {
room.off(RoomEvent.ConnectionStateChanged, connectionStateChangeListener);
};
}, [token, onConnected, onDisconnected, room]);
React.useEffect(() => {
if (!room) return;
return () => {
logger.info("disconnecting on onmount");
room.disconnect();
};
}, [room]);
return { room };
}