Turn multi-SFU media transport into a developer option

This commit is contained in:
Robin
2025-10-03 14:43:22 -04:00
parent 68aae4a8e3
commit 86fb026be8
12 changed files with 461 additions and 290 deletions

View File

@@ -17,7 +17,7 @@ import { AutoDiscovery } from "matrix-js-sdk/lib/autodiscovery";
import { PosthogAnalytics } from "./analytics/PosthogAnalytics";
import { Config } from "./config/Config";
import { ElementWidgetActions, widget, type WidgetHelpers } from "./widget";
import { MatrixRTCFocusMissingError } from "./utils/errors";
import { MatrixRTCTransportMissingError } from "./utils/errors";
import { getUrlParams } from "./UrlParams";
import { getSFUConfigWithOpenID } from "./livekit/openIDSFU.ts";
@@ -28,35 +28,31 @@ export function getLivekitAlias(rtcSession: MatrixRTCSession): string {
return rtcSession.room.roomId;
}
async function makeFocusInternal(
async function makeTransportInternal(
rtcSession: MatrixRTCSession,
): Promise<LivekitTransport> {
logger.log("Searching for a preferred focus");
logger.log("Searching for a preferred transport");
const livekitAlias = getLivekitAlias(rtcSession);
const urlFromStorage = localStorage.getItem("robin-matrixrtc-auth");
// TODO-MULTI-SFU: Either remove this dev tool or make it more official
const urlFromStorage =
localStorage.getItem("robin-matrixrtc-auth") ??
localStorage.getItem("timo-focus-url");
if (urlFromStorage !== null) {
const focusFromStorage: LivekitTransport = {
const transportFromStorage: LivekitTransport = {
type: "livekit",
livekit_service_url: urlFromStorage,
livekit_alias: livekitAlias,
};
logger.log("Using LiveKit focus from local storage: ", focusFromStorage);
return focusFromStorage;
logger.log(
"Using LiveKit transport from local storage: ",
transportFromStorage,
);
return transportFromStorage;
}
// Prioritize the .well-known/matrix/client, if available, over the configured SFU
const domain = rtcSession.room.client.getDomain();
if (localStorage.getItem("timo-focus-url")) {
const timoFocusUrl = localStorage.getItem("timo-focus-url")!;
const focusFromUrl: LivekitTransport = {
type: "livekit",
livekit_service_url: timoFocusUrl,
livekit_alias: livekitAlias,
};
logger.log("Using LiveKit focus from localStorage: ", timoFocusUrl);
return focusFromUrl;
}
if (domain) {
// we use AutoDiscovery instead of relying on the MatrixClient having already
// been fully configured and started
@@ -64,46 +60,46 @@ async function makeFocusInternal(
FOCI_WK_KEY
];
if (Array.isArray(wellKnownFoci)) {
const focus: LivekitTransportConfig | undefined = wellKnownFoci.find(
const transport: LivekitTransportConfig | undefined = wellKnownFoci.find(
(f) => f && isLivekitTransportConfig(f),
);
if (focus !== undefined) {
logger.log("Using LiveKit focus from .well-known: ", focus);
return { ...focus, livekit_alias: livekitAlias };
if (transport !== undefined) {
logger.log("Using LiveKit transport from .well-known: ", transport);
return { ...transport, livekit_alias: livekitAlias };
}
}
}
const urlFromConf = Config.get().livekit?.livekit_service_url;
if (urlFromConf) {
const focusFromConf: LivekitTransport = {
const transportFromConf: LivekitTransport = {
type: "livekit",
livekit_service_url: urlFromConf,
livekit_alias: livekitAlias,
};
logger.log("Using LiveKit focus from config: ", focusFromConf);
return focusFromConf;
logger.log("Using LiveKit transport from config: ", transportFromConf);
return transportFromConf;
}
throw new MatrixRTCFocusMissingError(domain ?? "");
throw new MatrixRTCTransportMissingError(domain ?? "");
}
export async function makeFocus(
export async function makeTransport(
rtcSession: MatrixRTCSession,
): Promise<LivekitTransport> {
const focus = await makeFocusInternal(rtcSession);
const transport = await makeTransportInternal(rtcSession);
// this will call the jwt/sfu/get endpoint to pre create the livekit room.
await getSFUConfigWithOpenID(
rtcSession.room.client,
focus.livekit_service_url,
focus.livekit_alias,
transport.livekit_service_url,
transport.livekit_alias,
);
return focus;
return transport;
}
export async function enterRTCSession(
rtcSession: MatrixRTCSession,
focus: LivekitTransport,
transport: LivekitTransport,
encryptMedia: boolean,
useNewMembershipManager = true,
useExperimentalToDeviceTransport = false,
@@ -120,10 +116,10 @@ export async function enterRTCSession(
const useDeviceSessionMemberEvents =
features?.feature_use_device_session_member_events;
const { sendNotificationType: notificationType, callIntent } = getUrlParams();
// Multi-sfu does not need a focus preferred list. just the focus that is actually used.
// Multi-sfu does not need a preferred foci list. just the focus that is actually used.
rtcSession.joinRoomSession(
useMultiSfu ? [focus] : [],
useMultiSfu ? focus : undefined,
useMultiSfu ? [] : [transport],
useMultiSfu ? transport : undefined,
{
notificationType,
callIntent,