mirror of
https://github.com/vector-im/element-call.git
synced 2024-11-15 00:04:59 +08:00
More hacking on rtcsession
This commit is contained in:
parent
1716bd4418
commit
e39d00154d
23
src/livekit/LivekitFocus.ts
Normal file
23
src/livekit/LivekitFocus.ts
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
Copyright 2023 New Vector Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { Focus } from "matrix-js-sdk/src/matrixrtc/focus";
|
||||
|
||||
export interface LivekitFocus extends Focus {
|
||||
type: "livekit";
|
||||
livekit_service_url: string;
|
||||
livekit_alias: string;
|
||||
}
|
@ -14,10 +14,13 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { GroupCall, IOpenIDToken, MatrixClient } from "matrix-js-sdk";
|
||||
import { IOpenIDToken, MatrixClient } from "matrix-js-sdk";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import { MatrixRTCSession } from "matrix-js-sdk/src/matrixrtc/MatrixRTCSession";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
import { Config } from "../config/Config";
|
||||
import { LivekitFocus } from "./LivekitFocus";
|
||||
import { useActiveFocus } from "../room/useActiveFocus";
|
||||
|
||||
export interface SFUConfig {
|
||||
url: string;
|
||||
@ -30,66 +33,52 @@ export type OpenIDClientParts = Pick<
|
||||
"getOpenIdToken" | "getDeviceId"
|
||||
>;
|
||||
|
||||
export function useOpenIDSFU(
|
||||
client: OpenIDClientParts,
|
||||
rtcSession: MatrixRTCSession
|
||||
) {
|
||||
const [sfuConfig, setSFUConfig] = useState<SFUConfig | undefined>(undefined);
|
||||
|
||||
const activeFocus = useActiveFocus(rtcSession);
|
||||
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
const sfuConfig = activeFocus
|
||||
? await getSFUConfigWithOpenID(client, activeFocus)
|
||||
: undefined;
|
||||
setSFUConfig(sfuConfig);
|
||||
})();
|
||||
}, [client, activeFocus]);
|
||||
|
||||
return sfuConfig;
|
||||
}
|
||||
|
||||
export async function getSFUConfigWithOpenID(
|
||||
client: OpenIDClientParts,
|
||||
groupCall: GroupCall,
|
||||
roomName: string
|
||||
): Promise<SFUConfig> {
|
||||
activeFocus: LivekitFocus
|
||||
): Promise<SFUConfig | undefined> {
|
||||
const openIdToken = await client.getOpenIdToken();
|
||||
logger.debug("Got openID token", openIdToken);
|
||||
|
||||
// if the call has a livekit service URL, try it.
|
||||
if (groupCall.livekitServiceURL) {
|
||||
try {
|
||||
logger.info(
|
||||
`Trying to get JWT from call's configured URL of ${groupCall.livekitServiceURL}...`
|
||||
);
|
||||
const sfuConfig = await getLiveKitJWT(
|
||||
client,
|
||||
groupCall.livekitServiceURL,
|
||||
roomName,
|
||||
openIdToken
|
||||
);
|
||||
logger.info(`Got JWT from call state event URL.`);
|
||||
|
||||
return sfuConfig;
|
||||
} catch (e) {
|
||||
logger.warn(
|
||||
`Failed to get JWT from group call's configured URL of ${groupCall.livekitServiceURL}.`,
|
||||
e
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// otherwise, try our configured one and, if it works, update the call's service URL in the state event
|
||||
// NB. This wuill update it for everyone so we may end up with multiple clients updating this when they
|
||||
// join at similar times, but we don't have a huge number of options here.
|
||||
const urlFromConf = Config.get().livekit!.livekit_service_url;
|
||||
logger.info(`Trying livekit service URL from our config: ${urlFromConf}...`);
|
||||
try {
|
||||
logger.info(
|
||||
`Trying to get JWT from call's active focus URL of ${activeFocus.livekit_service_url}...`
|
||||
);
|
||||
const sfuConfig = await getLiveKitJWT(
|
||||
client,
|
||||
urlFromConf,
|
||||
roomName,
|
||||
activeFocus.livekit_service_url,
|
||||
activeFocus.livekit_alias,
|
||||
openIdToken
|
||||
);
|
||||
|
||||
logger.info(
|
||||
`Got JWT, updating call livekit service URL with: ${urlFromConf}...`
|
||||
);
|
||||
try {
|
||||
await groupCall.updateLivekitServiceURL(urlFromConf);
|
||||
logger.info(`Call livekit service URL updated.`);
|
||||
} catch (e) {
|
||||
logger.warn(
|
||||
`Failed to update call livekit service URL: continuing anyway.`
|
||||
);
|
||||
}
|
||||
logger.info(`Got JWT from call's active focus URL.`);
|
||||
|
||||
return sfuConfig;
|
||||
} catch (e) {
|
||||
logger.error("Failed to get JWT from URL defined in Config.", e);
|
||||
throw e;
|
||||
logger.warn(
|
||||
`Failed to get JWT from RTC session's active focus URL of ${activeFocus.livekit_service_url}.`,
|
||||
e
|
||||
);
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,6 @@ import { useTranslation } from "react-i18next";
|
||||
import { Room } from "livekit-client";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import { MatrixRTCSession } from "matrix-js-sdk/src/matrixrtc/MatrixRTCSession";
|
||||
import { Focus } from "matrix-js-sdk/src/matrixrtc/focus";
|
||||
|
||||
import type { IWidgetApiRequest } from "matrix-widget-api";
|
||||
import { widget, ElementWidgetActions, JoinCallData } from "../widget";
|
||||
@ -32,11 +31,9 @@ import { CallEndedView } from "./CallEndedView";
|
||||
import { PosthogAnalytics } from "../analytics/PosthogAnalytics";
|
||||
import { useProfile } from "../profile/useProfile";
|
||||
import { findDeviceByName } from "../media-utils";
|
||||
//import { OpenIDLoader } from "../livekit/OpenIDLoader";
|
||||
import { ActiveCall } from "./InCallView";
|
||||
import { MuteStates, useMuteStates } from "./MuteStates";
|
||||
import { useMediaDevices, MediaDevices } from "../livekit/MediaDevicesContext";
|
||||
import { LivekitFocus } from "../livekit/LivekitFocus";
|
||||
import { useMatrixRTCSessionMemberships } from "../useMatrixRTCSessionMemberships";
|
||||
import { enterRTCSession, leaveRTCSession } from "../rtcSessionHelpers";
|
||||
import { useMatrixRTCSessionJoinState } from "../useMatrixRTCSessionJoinState";
|
||||
@ -69,21 +66,11 @@ export function GroupCallView({
|
||||
hideHeader,
|
||||
rtcSession,
|
||||
}: Props) {
|
||||
/*const {
|
||||
state,
|
||||
error,
|
||||
enter,
|
||||
leave,
|
||||
participants,
|
||||
unencryptedEventsFromUsers,
|
||||
otelGroupCallMembership,
|
||||
} = useGroupCall(groupCall, client);*/
|
||||
|
||||
const memberships = useMatrixRTCSessionMemberships(rtcSession);
|
||||
const isJoined = useMatrixRTCSessionJoinState(rtcSession);
|
||||
|
||||
const e2eeSharedKey = useManageRoomSharedKey(groupCall.room.roomId);
|
||||
const isRoomE2EE = useIsRoomE2EE(groupCall.room.roomId);
|
||||
const e2eeSharedKey = useManageRoomSharedKey(rtcSession.room.roomId);
|
||||
const isRoomE2EE = useIsRoomE2EE(rtcSession.room.roomId);
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
@ -260,22 +247,9 @@ export function GroupCallView({
|
||||
const onReconnect = useCallback(() => {
|
||||
setLeft(false);
|
||||
setLeaveError(undefined);
|
||||
rtcSession.joinRoomSession();
|
||||
enterRTCSession(rtcSession);
|
||||
}, [rtcSession]);
|
||||
|
||||
const focus: Focus | undefined = rtcSession
|
||||
.getOldestMembership()
|
||||
?.getActiveFoci()?.[0];
|
||||
if (
|
||||
!focus ||
|
||||
focus.type !== "livekit" ||
|
||||
!(focus as LivekitFocus).livekit_alias ||
|
||||
!(focus as LivekitFocus).livekit_service_url
|
||||
) {
|
||||
logger.error("Incompatible focus on call", focus);
|
||||
return <ErrorView error={new Error("Call focus is not compatible!")} />;
|
||||
}
|
||||
|
||||
if (e2eeEnabled && isRoomE2EE && !e2eeSharedKey) {
|
||||
return (
|
||||
<ErrorView
|
||||
@ -294,11 +268,6 @@ export function GroupCallView({
|
||||
|
||||
if (isJoined) {
|
||||
return (
|
||||
/*<OpenIDLoader
|
||||
client={client}
|
||||
groupCall={groupCall}
|
||||
roomName={`${groupCall.room.roomId}-${groupCall.groupCallId}`}
|
||||
>*/
|
||||
<ActiveCall
|
||||
client={client}
|
||||
rtcSession={rtcSession}
|
||||
@ -309,7 +278,6 @@ export function GroupCallView({
|
||||
e2eeConfig={e2eeConfig}
|
||||
//otelGroupCallMembership={otelGroupCallMembership}
|
||||
/>
|
||||
//</OpenIDLoader>
|
||||
);
|
||||
} else if (left) {
|
||||
// The call ended view is shown for two reasons: prompting guests to create
|
||||
@ -351,7 +319,7 @@ export function GroupCallView({
|
||||
<LobbyView
|
||||
matrixInfo={matrixInfo}
|
||||
muteStates={muteStates}
|
||||
onEnter={() => enter()}
|
||||
onEnter={() => enterRTCSession(rtcSession)}
|
||||
isEmbedded={isEmbedded}
|
||||
hideHeader={hideHeader}
|
||||
/>
|
||||
|
68
src/room/useActiveFocus.ts
Normal file
68
src/room/useActiveFocus.ts
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
Copyright 2023 New Vector Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
MatrixRTCSession,
|
||||
MatrixRTCSessionEvent,
|
||||
} from "matrix-js-sdk/src/matrixrtc/MatrixRTCSession";
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
import { deepCompare } from "matrix-js-sdk/src/utils";
|
||||
|
||||
import { LivekitFocus } from "../livekit/LivekitFocus";
|
||||
|
||||
function getActiveFocus(
|
||||
rtcSession: MatrixRTCSession
|
||||
): LivekitFocus | undefined {
|
||||
const oldestMembership = rtcSession.getOldestMembership();
|
||||
return oldestMembership?.getActiveFoci()[0] as LivekitFocus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the currently active (livekit) focus for a MatrixRTC session
|
||||
* This logic is specific to livekit foci where the whole call must use one
|
||||
* and the same focus.
|
||||
*/
|
||||
export function useActiveFocus(
|
||||
rtcSession: MatrixRTCSession
|
||||
): LivekitFocus | undefined {
|
||||
const [activeFocus, setActiveFocus] = useState(() =>
|
||||
getActiveFocus(rtcSession)
|
||||
);
|
||||
|
||||
const onMembershipsChanged = useCallback(() => {
|
||||
const newActiveFocus = getActiveFocus(rtcSession);
|
||||
|
||||
if (!deepCompare(activeFocus, newActiveFocus)) {
|
||||
setActiveFocus(newActiveFocus);
|
||||
}
|
||||
}, [activeFocus, rtcSession]);
|
||||
|
||||
useEffect(() => {
|
||||
rtcSession.on(
|
||||
MatrixRTCSessionEvent.MembershipsChanged,
|
||||
onMembershipsChanged
|
||||
);
|
||||
|
||||
return () => {
|
||||
rtcSession.off(
|
||||
MatrixRTCSessionEvent.MembershipsChanged,
|
||||
onMembershipsChanged
|
||||
);
|
||||
};
|
||||
});
|
||||
|
||||
return activeFocus;
|
||||
}
|
53
src/rtcSessionHelpers.ts
Normal file
53
src/rtcSessionHelpers.ts
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
Copyright 2023 New Vector Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { MatrixRTCSession } from "matrix-js-sdk/src/matrixrtc/MatrixRTCSession";
|
||||
|
||||
import { PosthogAnalytics } from "./analytics/PosthogAnalytics";
|
||||
import { LivekitFocus } from "./livekit/LivekitFocus";
|
||||
import { Config } from "./config/Config";
|
||||
|
||||
function makeFocus(livekitAlias: string): LivekitFocus {
|
||||
const urlFromConf = Config.get().livekit!.livekit_service_url;
|
||||
if (!urlFromConf) {
|
||||
throw new Error("No livekit_service_url is configured!");
|
||||
}
|
||||
|
||||
return {
|
||||
type: "livekit",
|
||||
livekit_service_url: urlFromConf,
|
||||
livekit_alias: livekitAlias,
|
||||
};
|
||||
}
|
||||
|
||||
export function enterRTCSession(rtcSession: MatrixRTCSession) {
|
||||
PosthogAnalytics.instance.eventCallEnded.cacheStartCall(new Date());
|
||||
PosthogAnalytics.instance.eventCallStarted.track(rtcSession.room.roomId);
|
||||
|
||||
// This must be called before we start trying to join the call, as we need to
|
||||
// have started tracking by the time calls start getting created.
|
||||
//groupCallOTelMembership?.onJoinCall();
|
||||
|
||||
// right now we asume everything is a room-scoped call
|
||||
const livekitAlias = rtcSession.room.roomId;
|
||||
|
||||
rtcSession.joinRoomSession([makeFocus(livekitAlias)]);
|
||||
}
|
||||
|
||||
export function leaveRTCSession(rtcSession: MatrixRTCSession) {
|
||||
//groupCallOTelMembership?.onLeaveCall();
|
||||
rtcSession.leaveRoomSession();
|
||||
}
|
@ -14,6 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import {
|
||||
MatrixRTCSession,
|
||||
MatrixRTCSessionEvent,
|
||||
@ -26,6 +27,11 @@ export function useMatrixRTCSessionJoinState(
|
||||
const [isJoined, setJoined] = useState(rtcSession.isJoined());
|
||||
|
||||
const onJoinStateChanged = useCallback(() => {
|
||||
logger.info(
|
||||
`Session in room ${rtcSession.room.roomId} changed to ${
|
||||
rtcSession.isJoined() ? "joined" : "left"
|
||||
}`
|
||||
);
|
||||
setJoined(rtcSession.isJoined());
|
||||
}, [rtcSession]);
|
||||
|
||||
|
@ -14,6 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import { CallMembership } from "matrix-js-sdk/src/matrixrtc/CallMembership";
|
||||
import {
|
||||
MatrixRTCSession,
|
||||
@ -27,6 +28,9 @@ export function useMatrixRTCSessionMemberships(
|
||||
const [memberships, setMemberships] = useState(rtcSession.memberships);
|
||||
|
||||
const onMembershipsChanged = useCallback(() => {
|
||||
logger.info(
|
||||
`Memberships changed for call in room ${rtcSession.room.roomId} (${rtcSession.memberships.length} members)`
|
||||
);
|
||||
setMemberships(rtcSession.memberships);
|
||||
}, [rtcSession]);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user