Show the whole transport in debug UI and logs

A transport may soon carry a LiveKit SFU `url` instead of, or as well as,
a `livekit_service_url`, so a service URL alone no longer identifies it.
Pass the whole transport to the tiles' debug stats and print it as JSON in
log lines instead of picking out the service URL.

Element Call's media view models carry the member's raw transport from the SDK's TransportMetadata to the tiles.
This commit is contained in:
Robin
2026-10-14 10:23:29 +02:00
committed by Timo
parent 1700e9fe20
commit f97dd2adab
8 changed files with 22 additions and 21 deletions
+2 -2
View File
@@ -16,12 +16,12 @@ import classNames from "classnames";
import { Modal } from "./Modal";
import styles from "./RTCConnectionStats.module.css";
import mediaViewStyles from "../src/tile/MediaView.module.css";
import { type UnstableLivekitTransport } from "matrix-js-sdk/lib/matrixrtc";
import { type Transport } from "matrix-js-sdk/lib/matrixrtc";
interface Props {
audio?: RTCInboundRtpStreamStats | RTCOutboundRtpStreamStats;
video?: RTCInboundRtpStreamStats | RTCOutboundRtpStreamStats;
transport?: UnstableLivekitTransport;
transport?: Transport;
rtcBackendIdentity?: string;
}
+2 -2
View File
@@ -674,8 +674,8 @@ export function createCallViewModel$(
rtcBackendIdentity: member.rtcBackendIdentity,
member,
encryptionSystem: options.encryptionSystem,
focusUrl$: scope.behavior(
member.transport$.pipe(map((transport) => transport?.id)),
transport$: scope.behavior(
member.transport$.pipe(map((transport) => transport?.raw)),
),
mediaDevices,
pretendToBeDisconnected$: reconnecting$,
+5 -4
View File
@@ -18,6 +18,7 @@ import {
trackBySource$,
type VideoMediaTrack,
} from "@element-hq/matrixrtc-sdk";
import { type Transport } from "matrix-js-sdk/lib/matrixrtc";
import {
combineLatest,
distinctUntilChanged,
@@ -56,10 +57,10 @@ export interface BaseMemberMediaViewModel extends BaseMediaViewModel {
*/
video$: Behavior<VideoMediaTrack | undefined>;
/**
* The URL of the transport on which this member should be publishing.
* Exposed for debugging.
* The transport on which this member should be publishing, as it appears
* in the membership. Exposed for debugging.
*/
transport$: Behavior<UnstableLivekitTransport | undefined>;
transport$: Behavior<Transport | undefined>;
/**
* Whether there should be a warning that this media is unencrypted.
*/
@@ -74,7 +75,7 @@ export interface MemberMediaInputs extends BaseMediaViewModel {
member: MediaMember;
audioSource: "microphone" | "screenShareAudio";
videoSource: "camera" | "screenShare";
focusUrl$: Behavior<string | undefined>;
transport$: Behavior<Transport | undefined>;
encryptionSystem: EncryptionSystem;
}
+2 -2
View File
@@ -43,11 +43,11 @@ export function createRemoteUserMedia(
const waitingForMedia$ = scope.behavior(
combineLatest(
[inputs.focusUrl$, inputs.member.tracks$],
[inputs.transport$, inputs.member.tracks$],
// Without a transport the user is not attempting to publish anywhere
// and so we shouldn't expect media. (They might be a subscribe-only bot
// for example.)
(focusUrl, tracks) => focusUrl !== undefined && tracks === null,
(transport, tracks) => transport !== undefined && tracks === null,
),
);
waitingForMedia$.pipe(scope.bind()).subscribe((waiting) => {
+2 -2
View File
@@ -51,7 +51,7 @@ import { type RemoteUserMediaViewModel } from "../state/media/RemoteUserMediaVie
import { type UserMediaViewModel } from "../state/media/UserMediaViewModel";
import { type RingingMediaViewModel } from "../state/media/RingingMediaViewModel";
import { RingingStatus } from "./RingingStatus";
import { type UnstableLivekitTransport } from "matrix-js-sdk/lib/matrixrtc";
import { type Transport } from "matrix-js-sdk/lib/matrixrtc";
interface TileProps {
ref?: Ref<HTMLDivElement>;
@@ -104,7 +104,7 @@ interface UserMediaTileProps extends TileProps {
playbackMuted: boolean;
waitingForMedia?: boolean;
primaryButton?: ReactNode;
transport: UnstableLivekitTransport | undefined;
transport: Transport | undefined;
}
/**
+3 -3
View File
@@ -34,7 +34,7 @@ import { ReactionIndicator } from "../reactions/ReactionIndicator";
import { RTCConnectionStats } from "../RTCConnectionStats";
import videoPlaceholder from "../graphics/video-placeholder.gif";
import { autoVideoFit } from "../utils/videoFit";
import { type UnstableLivekitTransport } from "matrix-js-sdk/lib/matrixrtc";
import { type Transport } from "matrix-js-sdk/lib/matrixrtc";
interface Props extends ComponentProps<typeof animated.div> {
className?: string;
@@ -69,9 +69,9 @@ interface Props extends ComponentProps<typeof animated.div> {
videoStreamStats?: RTCInboundRtpStreamStats | RTCOutboundRtpStreamStats;
rtcBackendIdentity?: string;
/**
* The LiveKit transport, mainly for debugging purposes.
* The member's transport, mainly for debugging purposes.
*/
transport?: UnstableLivekitTransport;
transport?: Transport;
/**
* Called whenever the aspect ratio of the video content becomes known or
* otherwise changes.
+2 -2
View File
@@ -54,7 +54,7 @@ import { platform } from "../Platform";
import { type RingingMediaViewModel } from "../state/media/RingingMediaViewModel";
import { RingingStatus } from "./RingingStatus";
import { useRootElement } from "../RootElementContext";
import { type UnstableLivekitTransport } from "matrix-js-sdk/lib/matrixrtc";
import { type Transport } from "matrix-js-sdk/lib/matrixrtc";
interface SpotlightItemBaseProps {
ref?: Ref<HTMLDivElement>;
@@ -75,7 +75,7 @@ interface SpotlightItemBaseProps {
interface SpotlightMemberMediaItemBaseProps extends SpotlightItemBaseProps {
video: VideoMediaTrack | undefined;
unencryptedWarning: boolean;
transport: UnstableLivekitTransport | undefined;
transport: Transport | undefined;
}
interface SpotlightUserMediaItemBaseProps extends SpotlightMemberMediaItemBaseProps {
+4 -4
View File
@@ -372,7 +372,7 @@ export function mockLocalMedia(
tracks$: constant(tracks),
}),
encryptionSystem: { kind: E2eeType.PER_PARTICIPANT },
focusUrl$: constant("https://rtc-example.org"),
transport$: constant(exampleTransport),
mediaDevices,
displayName$: constant(member.rawDisplayName ?? "nodisplayname"),
mxcAvatarUrl$: constant(member.getMxcAvatarUrl()),
@@ -386,7 +386,7 @@ export function mockRemoteMedia(
roomMember: Partial<RoomMember>,
/** The tracks, or a behavior of them for a test that has them arrive. */
tracks: MockTracks | Behavior<MockTracks>,
{ focusUrl }: { focusUrl?: string } = { focusUrl: "https://rtc-example.org" },
{ transport }: { transport?: Transport } = { transport: exampleTransport },
): RemoteUserMediaViewModel {
const member = mockMatrixRoomMember(rtcMember, roomMember);
return createRemoteUserMedia(testScope(), {
@@ -400,7 +400,7 @@ export function mockRemoteMedia(
tracks === null || Array.isArray(tracks) ? constant(tracks) : tracks,
}),
encryptionSystem: { kind: E2eeType.PER_PARTICIPANT },
focusUrl$: constant(focusUrl),
transport$: constant(transport),
pretendToBeDisconnected$: constant(false),
displayName$: constant(member.rawDisplayName ?? "nodisplayname"),
mxcAvatarUrl$: constant(member.getMxcAvatarUrl()),
@@ -424,7 +424,7 @@ export function mockRemoteScreenShare(
tracks$: constant(tracks),
}),
encryptionSystem: { kind: E2eeType.PER_PARTICIPANT },
focusUrl$: constant("https://rtc-example.org"),
transport$: constant(exampleTransport),
pretendToBeDisconnected$: constant(false),
displayName$: constant(member.rawDisplayName ?? "nodisplayname"),
mxcAvatarUrl$: constant(member.getMxcAvatarUrl()),