mirror of
https://github.com/vector-im/element-call.git
synced 2026-10-16 23:45:50 +00:00
make the transport discovery lk edgecase a EC exclusive workaround
Dont add it to the sdk.
This commit is contained in:
@@ -8,8 +8,7 @@ Please see LICENSE in the repository root for full details.
|
||||
import { type Logger } from "matrix-js-sdk/lib/logger";
|
||||
import {
|
||||
type CallMembership,
|
||||
getRemoteLivekitPublishCandidates,
|
||||
type LivekitPublishCandidate,
|
||||
isUnstableLivekitTransport,
|
||||
type Transport,
|
||||
} from "matrix-js-sdk/lib/matrixrtc";
|
||||
import { type CallMembershipIdentityParts } from "matrix-js-sdk/lib/matrixrtc/EncryptionManager";
|
||||
@@ -30,15 +29,15 @@ export interface RemotePublishTransportParams {
|
||||
|
||||
/**
|
||||
* The SFU of another member that its homeserver lets us publish on, as the
|
||||
* transport to advertise, or null where no member's SFU will do. Candidates
|
||||
* are tried oldest membership first, and each one is checked by asking for a
|
||||
* transport to advertise, or null where none does. Candidates are tried
|
||||
* oldest membership first, each SFU once, and each is checked by asking for a
|
||||
* publisher token through our homeserver (MSC4195): a homeserver may restrict
|
||||
* remote publishers, which shows as a token without the publish grant.
|
||||
*/
|
||||
export async function findRemotePublishTransport({
|
||||
export async function findRemotePublishLivekitTransport({
|
||||
client,
|
||||
memberships,
|
||||
ownMembershipIdentity,
|
||||
ownMembershipIdentity: own,
|
||||
roomId,
|
||||
slotId,
|
||||
logger,
|
||||
@@ -46,45 +45,51 @@ export async function findRemotePublishTransport({
|
||||
logger.info(
|
||||
"No local transport available, looking for another member's SFU to publish on",
|
||||
);
|
||||
const candidates = getRemoteLivekitPublishCandidates(
|
||||
memberships,
|
||||
ownMembershipIdentity,
|
||||
);
|
||||
for (const candidate of candidates) {
|
||||
const outcome = await tryCandidate(candidate);
|
||||
if (outcome === "usable") return candidate.transport;
|
||||
if (outcome === "noCsApi") return null;
|
||||
const tried = new Set<string>();
|
||||
const byAge = [...memberships].sort((a, b) => a.createdTs() - b.createdTs());
|
||||
for (const membership of byAge) {
|
||||
if (
|
||||
membership.userId === own.userId &&
|
||||
membership.deviceId === own.deviceId
|
||||
)
|
||||
continue;
|
||||
for (const transport of membership.transports) {
|
||||
// Publishing remotely goes through the client-server API, which a JWT
|
||||
// service cannot stand in for, so only a `url` qualifies
|
||||
if (!isUnstableLivekitTransport(transport) || !("url" in transport))
|
||||
continue;
|
||||
const { url } = transport;
|
||||
const serverName = membership.getTransportServerName(transport);
|
||||
const key = JSON.stringify([url, serverName]);
|
||||
if (tried.has(key)) continue;
|
||||
tried.add(key);
|
||||
try {
|
||||
const { jwt } = await csApi.getSFUConfig({
|
||||
client,
|
||||
membership: own,
|
||||
url,
|
||||
serverName,
|
||||
roomId,
|
||||
slotId,
|
||||
});
|
||||
if (decodeSFUJWTPayload(jwt).video.canPublish) {
|
||||
logger.info(`Publishing on remote SFU ${url} of ${serverName}`);
|
||||
return { type: "livekit", url, server_name: serverName };
|
||||
}
|
||||
logger.info(
|
||||
`${serverName} does not let us publish on ${url}, skipping`,
|
||||
);
|
||||
} catch (e) {
|
||||
if (isCsApiUnavailable(e)) {
|
||||
// Without the endpoint no further candidate can work
|
||||
logger.warn(
|
||||
`Cannot use the MSC4195 get_token endpoint (${e}), so no remote SFU can be used`,
|
||||
);
|
||||
return null;
|
||||
}
|
||||
logger.warn(`Failed to get a token for ${url} of ${serverName}:`, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
/** "noCsApi" ends the search: without the endpoint no candidate can work. */
|
||||
async function tryCandidate({
|
||||
url,
|
||||
serverName,
|
||||
}: LivekitPublishCandidate): Promise<"usable" | "unusable" | "noCsApi"> {
|
||||
try {
|
||||
const { jwt } = await csApi.getSFUConfig({
|
||||
client,
|
||||
membership: ownMembershipIdentity,
|
||||
url,
|
||||
serverName,
|
||||
roomId,
|
||||
slotId,
|
||||
});
|
||||
if (decodeSFUJWTPayload(jwt).video.canPublish) {
|
||||
logger.info(`Publishing on remote SFU ${url} of ${serverName}`);
|
||||
return "usable";
|
||||
}
|
||||
logger.info(`${serverName} does not let us publish on ${url}, skipping`);
|
||||
} catch (e) {
|
||||
if (isCsApiUnavailable(e)) {
|
||||
logger.warn(
|
||||
`Cannot use the MSC4195 get_token endpoint (${e}), so no remote SFU can be used`,
|
||||
);
|
||||
return "noCsApi";
|
||||
}
|
||||
logger.warn(`Failed to get a token for ${url} of ${serverName}:`, e);
|
||||
}
|
||||
return "unusable";
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user