1
0
mirror of https://github.com/matrix-org/matrix-js-sdk.git synced 2025-07-31 15:24:23 +03:00

Add remote user and call id in webrtc call stats (#3413)

* Refactor names in webrtc stats

* Refactor summary stats reporter to gatherer

* Add call and opponent member id to call stats reports

* Update opponent member when we know them

* Add missing return type

* remove async in test

* mark new stats property as optional to avoid braking changes
This commit is contained in:
Enrico Schwendig
2023-06-01 17:07:44 +02:00
committed by GitHub
parent feb424b0a9
commit 9c5c7ddb17
5 changed files with 31 additions and 6 deletions

View File

@ -158,7 +158,7 @@ describe("CallStatsReportGatherer", () => {
collector = new CallStatsReportGatherer(CALL_ID, USER_ID, rtcSpy, emitter);
});
it("in case of stable, parse remote and local description", async () => {
it("in case of stable, parse remote and local description", () => {
// @ts-ignore
const mediaSsrcHandler = {
parse: jest.fn(),

View File

@ -2848,7 +2848,9 @@ export class MatrixCall extends TypedEventEmitter<CallEvent, CallEventHandlerMap
pc.addEventListener("negotiationneeded", this.onNegotiationNeeded);
pc.addEventListener("datachannel", this.onDataChannel);
this.stats?.addStatsReportGatherer(this.callId, "unknown", pc);
const opponentMember: RoomMember | undefined = this.getOpponentMember();
const opponentMemberId = opponentMember ? opponentMember.userId : "unknown";
this.stats?.addStatsReportGatherer(this.callId, opponentMemberId, pc);
return pc;
}
@ -2882,6 +2884,9 @@ export class MatrixCall extends TypedEventEmitter<CallEvent, CallEventHandlerMap
}
this.opponentCaps = msg.capabilities || ({} as CallCapabilities);
this.opponentMember = this.client.getRoom(this.roomId)!.getMember(ev.getSender()!) ?? undefined;
if (this.opponentMember) {
this.stats?.updateOpponentMember(this.callId, this.opponentMember.userId);
}
}
private async addBufferedIceCandidates(): Promise<void> {

View File

@ -37,7 +37,7 @@ export class CallStatsReportGatherer {
public constructor(
public readonly callId: string,
public readonly remoteUserId: string,
private opponentMemberId: string,
private readonly pc: RTCPeerConnection,
private readonly emitter: StatsReportEmitter,
private readonly isFocus = true,
@ -93,7 +93,9 @@ export class CallStatsReportGatherer {
}
private processStatsReport(groupCallId: string, localUserId: string): void {
const byteSentStatsReport: ByteSentStatsReport = new Map<TrackID, ByteSend>();
const byteSentStatsReport: ByteSentStatsReport = new Map<TrackID, ByteSend>() as ByteSentStatsReport;
byteSentStatsReport.callId = this.callId;
byteSentStatsReport.opponentMemberId = this.opponentMemberId;
this.currentStatsReport?.forEach((now) => {
const before = this.previousStatsReport ? this.previousStatsReport.get(now.id) : null;
@ -176,6 +178,8 @@ export class CallStatsReportGatherer {
private processAndEmitConnectionStatsReport(): void {
const report = ConnectionStatsReportBuilder.build(this.trackStats.getTrack2stats());
report.callId = this.callId;
report.opponentMemberId = this.opponentMemberId;
this.connectionStats.bandwidth = report.bandwidth;
this.connectionStats.bitrate = report.bitrate;
@ -201,4 +205,8 @@ export class CallStatsReportGatherer {
}
}
}
public setOpponentMemberId(id: string): void {
this.opponentMemberId = id;
}
}

View File

@ -45,11 +45,15 @@ export class GroupCallStats {
return this.gatherers.has(callId);
}
public addStatsReportGatherer(callId: string, userId: string, peerConnection: RTCPeerConnection): boolean {
public addStatsReportGatherer(
callId: string,
opponentMemberId: string,
peerConnection: RTCPeerConnection,
): boolean {
if (this.hasStatsReportGatherer(callId)) {
return false;
}
this.gatherers.set(callId, new CallStatsReportGatherer(callId, userId, peerConnection, this.reports));
this.gatherers.set(callId, new CallStatsReportGatherer(callId, opponentMemberId, peerConnection, this.reports));
return true;
}
@ -61,6 +65,10 @@ export class GroupCallStats {
return this.hasStatsReportGatherer(callId) ? this.gatherers.get(callId) : undefined;
}
public updateOpponentMember(callId: string, opponentMember: string): void {
this.getStatsReportGatherer(callId)?.setOpponentMemberId(opponentMember);
}
private processStats(): void {
const summary: Promise<CallStatsReportSummary>[] = [];
this.gatherers.forEach((c) => {

View File

@ -28,10 +28,14 @@ export type TrackID = string;
export type ByteSend = number;
export interface ByteSentStatsReport extends Map<TrackID, ByteSend> {
callId?: string;
opponentMemberId?: string;
// is a map: `local trackID` => byte send
}
export interface ConnectionStatsReport {
callId?: string;
opponentMemberId?: string;
bandwidth: ConnectionStatsBandwidth;
bitrate: ConnectionStatsBitrate;
packetLoss: PacketLoss;