diff options
author | RaindropsSys <raindrops@equestria.dev> | 2023-11-17 23:25:29 +0100 |
---|---|---|
committer | RaindropsSys <raindrops@equestria.dev> | 2023-11-17 23:25:29 +0100 |
commit | 953ddd82e48dd206cef5ac94456549aed13b3ad5 (patch) | |
tree | 8f003106ee2e7f422e5a22d2ee04d0db302e66c0 /includes/external/matrix/node_modules/matrix-js-sdk/src/webrtc/stats | |
parent | 62a9199846b0c07c03218703b33e8385764f42d9 (diff) | |
download | pluralconnect-953ddd82e48dd206cef5ac94456549aed13b3ad5.tar.gz pluralconnect-953ddd82e48dd206cef5ac94456549aed13b3ad5.tar.bz2 pluralconnect-953ddd82e48dd206cef5ac94456549aed13b3ad5.zip |
Updated 30 files and deleted 2976 files (automated)
Diffstat (limited to 'includes/external/matrix/node_modules/matrix-js-sdk/src/webrtc/stats')
15 files changed, 0 insertions, 1057 deletions
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/src/webrtc/stats/connectionStats.ts b/includes/external/matrix/node_modules/matrix-js-sdk/src/webrtc/stats/connectionStats.ts deleted file mode 100644 index dbde6e5..0000000 --- a/includes/external/matrix/node_modules/matrix-js-sdk/src/webrtc/stats/connectionStats.ts +++ /dev/null @@ -1,47 +0,0 @@ -/* -Copyright 2023 The Matrix.org Foundation C.I.C. - -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 { TransportStats } from "./transportStats"; -import { Bitrate } from "./media/mediaTrackStats"; - -export interface ConnectionStatsBandwidth { - /** - * bytes per second - */ - download: number; - /** - * bytes per second - */ - upload: number; -} - -export interface ConnectionStatsBitrate extends Bitrate { - audio?: Bitrate; - video?: Bitrate; -} - -export interface PacketLoos { - total: number; - download: number; - upload: number; -} - -export class ConnectionStats { - public bandwidth: ConnectionStatsBitrate = {} as ConnectionStatsBitrate; - public bitrate: ConnectionStatsBitrate = {} as ConnectionStatsBitrate; - public packetLoss: PacketLoos = {} as PacketLoos; - public transport: TransportStats[] = []; -} diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/src/webrtc/stats/connectionStatsReporter.ts b/includes/external/matrix/node_modules/matrix-js-sdk/src/webrtc/stats/connectionStatsReporter.ts deleted file mode 100644 index c43b9b4..0000000 --- a/includes/external/matrix/node_modules/matrix-js-sdk/src/webrtc/stats/connectionStatsReporter.ts +++ /dev/null @@ -1,28 +0,0 @@ -/* -Copyright 2023 The Matrix.org Foundation C.I.C. - -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 { Bitrate } from "./media/mediaTrackStats"; - -export class ConnectionStatsReporter { - public static buildBandwidthReport(now: RTCIceCandidatePairStats): Bitrate { - const availableIncomingBitrate = now.availableIncomingBitrate; - const availableOutgoingBitrate = now.availableOutgoingBitrate; - - return { - download: availableIncomingBitrate ? Math.round(availableIncomingBitrate / 1000) : 0, - upload: availableOutgoingBitrate ? Math.round(availableOutgoingBitrate / 1000) : 0, - }; - } -} diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/src/webrtc/stats/groupCallStats.ts b/includes/external/matrix/node_modules/matrix-js-sdk/src/webrtc/stats/groupCallStats.ts deleted file mode 100644 index 6d8c566..0000000 --- a/includes/external/matrix/node_modules/matrix-js-sdk/src/webrtc/stats/groupCallStats.ts +++ /dev/null @@ -1,64 +0,0 @@ -/* -Copyright 2023 The Matrix.org Foundation C.I.C. - -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 { StatsReportGatherer } from "./statsReportGatherer"; -import { StatsReportEmitter } from "./statsReportEmitter"; - -export class GroupCallStats { - private timer: undefined | ReturnType<typeof setTimeout>; - private readonly gatherers: Map<string, StatsReportGatherer> = new Map<string, StatsReportGatherer>(); - public readonly reports = new StatsReportEmitter(); - - public constructor(private groupCallId: string, private userId: string, private interval: number = 10000) {} - - public start(): void { - if (this.timer === undefined) { - this.timer = setInterval(() => { - this.processStats(); - }, this.interval); - } - } - - public stop(): void { - if (this.timer !== undefined) { - clearInterval(this.timer); - this.gatherers.forEach((c) => c.stopProcessingStats()); - } - } - - public hasStatsReportGatherer(callId: string): boolean { - return this.gatherers.has(callId); - } - - public addStatsReportGatherer(callId: string, userId: string, peerConnection: RTCPeerConnection): boolean { - if (this.hasStatsReportGatherer(callId)) { - return false; - } - this.gatherers.set(callId, new StatsReportGatherer(callId, userId, peerConnection, this.reports)); - return true; - } - - public removeStatsReportGatherer(callId: string): boolean { - return this.gatherers.delete(callId); - } - - public getStatsReportGatherer(callId: string): StatsReportGatherer | undefined { - return this.hasStatsReportGatherer(callId) ? this.gatherers.get(callId) : undefined; - } - - private processStats(): void { - this.gatherers.forEach((c) => c.processStats(this.groupCallId, this.userId)); - } -} diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/src/webrtc/stats/media/mediaSsrcHandler.ts b/includes/external/matrix/node_modules/matrix-js-sdk/src/webrtc/stats/media/mediaSsrcHandler.ts deleted file mode 100644 index e606051..0000000 --- a/includes/external/matrix/node_modules/matrix-js-sdk/src/webrtc/stats/media/mediaSsrcHandler.ts +++ /dev/null @@ -1,57 +0,0 @@ -/* -Copyright 2023 The Matrix.org Foundation C.I.C. - -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 { parse as parseSdp } from "sdp-transform"; - -export type Mid = string; -export type Ssrc = string; -export type MapType = "local" | "remote"; - -export class MediaSsrcHandler { - private readonly ssrcToMid = { local: new Map<Mid, Ssrc[]>(), remote: new Map<Mid, Ssrc[]>() }; - - public findMidBySsrc(ssrc: Ssrc, type: "local" | "remote"): Mid | undefined { - let mid: Mid | undefined; - this.ssrcToMid[type].forEach((ssrcs, m) => { - if (ssrcs.find((s) => s == ssrc)) { - mid = m; - return; - } - }); - return mid; - } - - public parse(description: string, type: MapType): void { - const sdp = parseSdp(description); - const ssrcToMid = new Map<Mid, Ssrc[]>(); - sdp.media.forEach((m) => { - if ((!!m.mid && m.type === "video") || m.type === "audio") { - const ssrcs: Ssrc[] = []; - m.ssrcs?.forEach((ssrc) => { - if (ssrc.attribute === "cname") { - ssrcs.push(`${ssrc.id}`); - } - }); - ssrcToMid.set(`${m.mid}`, ssrcs); - } - }); - this.ssrcToMid[type] = ssrcToMid; - } - - public getSsrcToMidMap(type: MapType): Map<Mid, Ssrc[]> { - return this.ssrcToMid[type]; - } -} diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/src/webrtc/stats/media/mediaTrackHandler.ts b/includes/external/matrix/node_modules/matrix-js-sdk/src/webrtc/stats/media/mediaTrackHandler.ts deleted file mode 100644 index 32580b1..0000000 --- a/includes/external/matrix/node_modules/matrix-js-sdk/src/webrtc/stats/media/mediaTrackHandler.ts +++ /dev/null @@ -1,71 +0,0 @@ -/* -Copyright 2023 The Matrix.org Foundation C.I.C. - -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. -*/ - -export type TrackId = string; - -export class MediaTrackHandler { - public constructor(private readonly pc: RTCPeerConnection) {} - - public getLocalTracks(kind: "audio" | "video"): MediaStreamTrack[] { - const isNotNullAndKind = (track: MediaStreamTrack | null): boolean => { - return track !== null && track.kind === kind; - }; - // @ts-ignore The linter don't get it - return this.pc - .getTransceivers() - .filter((t) => t.currentDirection === "sendonly" || t.currentDirection === "sendrecv") - .filter((t) => t.sender !== null) - .map((t) => t.sender) - .map((s) => s.track) - .filter(isNotNullAndKind); - } - - public getTackById(trackId: string): MediaStreamTrack | undefined { - return this.pc - .getTransceivers() - .map((t) => { - if (t?.sender.track !== null && t.sender.track.id === trackId) { - return t.sender.track; - } - if (t?.receiver.track !== null && t.receiver.track.id === trackId) { - return t.receiver.track; - } - return undefined; - }) - .find((t) => t !== undefined); - } - - public getLocalTrackIdByMid(mid: string): string | undefined { - const transceiver = this.pc.getTransceivers().find((t) => t.mid === mid); - if (transceiver !== undefined && !!transceiver.sender && !!transceiver.sender.track) { - return transceiver.sender.track.id; - } - return undefined; - } - - public getRemoteTrackIdByMid(mid: string): string | undefined { - const transceiver = this.pc.getTransceivers().find((t) => t.mid === mid); - if (transceiver !== undefined && !!transceiver.receiver && !!transceiver.receiver.track) { - return transceiver.receiver.track.id; - } - return undefined; - } - - public getActiveSimulcastStreams(): number { - //@TODO implement this right.. Check how many layer configured - return 3; - } -} diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/src/webrtc/stats/media/mediaTrackStats.ts b/includes/external/matrix/node_modules/matrix-js-sdk/src/webrtc/stats/media/mediaTrackStats.ts deleted file mode 100644 index 69ee9bd..0000000 --- a/includes/external/matrix/node_modules/matrix-js-sdk/src/webrtc/stats/media/mediaTrackStats.ts +++ /dev/null @@ -1,104 +0,0 @@ -/* -Copyright 2023 The Matrix.org Foundation C.I.C. - -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 { TrackId } from "./mediaTrackHandler"; - -export interface PacketLoss { - packetsTotal: number; - packetsLost: number; - isDownloadStream: boolean; -} - -export interface Bitrate { - /** - * bytes per second - */ - download: number; - /** - * bytes per second - */ - upload: number; -} - -export interface Resolution { - width: number; - height: number; -} - -export type TrackStatsType = "local" | "remote"; - -export class MediaTrackStats { - private loss: PacketLoss = { packetsTotal: 0, packetsLost: 0, isDownloadStream: false }; - private bitrate: Bitrate = { download: 0, upload: 0 }; - private resolution: Resolution = { width: -1, height: -1 }; - private framerate = 0; - private codec = ""; - - public constructor( - public readonly trackId: TrackId, - public readonly type: TrackStatsType, - public readonly kind: "audio" | "video", - ) {} - - public getType(): TrackStatsType { - return this.type; - } - - public setLoss(loos: PacketLoss): void { - this.loss = loos; - } - - public getLoss(): PacketLoss { - return this.loss; - } - - public setResolution(resolution: Resolution): void { - this.resolution = resolution; - } - - public getResolution(): Resolution { - return this.resolution; - } - - public setFramerate(framerate: number): void { - this.framerate = framerate; - } - - public getFramerate(): number { - return this.framerate; - } - - public setBitrate(bitrate: Bitrate): void { - this.bitrate = bitrate; - } - - public getBitrate(): Bitrate { - return this.bitrate; - } - - public setCodec(codecShortType: string): boolean { - this.codec = codecShortType; - return true; - } - - public getCodec(): string { - return this.codec; - } - - public resetBitrate(): void { - this.bitrate = { download: 0, upload: 0 }; - } -} diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/src/webrtc/stats/media/mediaTrackStatsHandler.ts b/includes/external/matrix/node_modules/matrix-js-sdk/src/webrtc/stats/media/mediaTrackStatsHandler.ts deleted file mode 100644 index 6fb119c..0000000 --- a/includes/external/matrix/node_modules/matrix-js-sdk/src/webrtc/stats/media/mediaTrackStatsHandler.ts +++ /dev/null @@ -1,86 +0,0 @@ -/* -Copyright 2023 The Matrix.org Foundation C.I.C. - -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 { TrackID } from "../statsReport"; -import { MediaTrackStats } from "./mediaTrackStats"; -import { MediaTrackHandler } from "./mediaTrackHandler"; -import { MediaSsrcHandler } from "./mediaSsrcHandler"; - -export class MediaTrackStatsHandler { - private readonly track2stats = new Map<TrackID, MediaTrackStats>(); - - public constructor( - public readonly mediaSsrcHandler: MediaSsrcHandler, - public readonly mediaTrackHandler: MediaTrackHandler, - ) {} - - /** - * Find tracks by rtc stats - * Argument report is any because the stats api is not consistent: - * For example `trackIdentifier`, `mid` not existing in every implementations - * https://www.w3.org/TR/webrtc-stats/#dom-rtcinboundrtpstreamstats - * https://developer.mozilla.org/en-US/docs/Web/API/RTCInboundRtpStreamStats - */ - public findTrack2Stats(report: any, type: "remote" | "local"): MediaTrackStats | undefined { - let trackID; - if (report.trackIdentifier) { - trackID = report.trackIdentifier; - } else if (report.mid) { - trackID = - type === "remote" - ? this.mediaTrackHandler.getRemoteTrackIdByMid(report.mid) - : this.mediaTrackHandler.getLocalTrackIdByMid(report.mid); - } else if (report.ssrc) { - const mid = this.mediaSsrcHandler.findMidBySsrc(report.ssrc, type); - if (!mid) { - return undefined; - } - trackID = - type === "remote" - ? this.mediaTrackHandler.getRemoteTrackIdByMid(report.mid) - : this.mediaTrackHandler.getLocalTrackIdByMid(report.mid); - } - - if (!trackID) { - return undefined; - } - - let trackStats = this.track2stats.get(trackID); - - if (!trackStats) { - const track = this.mediaTrackHandler.getTackById(trackID); - if (track !== undefined) { - const kind: "audio" | "video" = track.kind === "audio" ? track.kind : "video"; - trackStats = new MediaTrackStats(trackID, type, kind); - this.track2stats.set(trackID, trackStats); - } else { - return undefined; - } - } - return trackStats; - } - - public findLocalVideoTrackStats(report: any): MediaTrackStats | undefined { - const localVideoTracks = this.mediaTrackHandler.getLocalTracks("video"); - if (localVideoTracks.length === 0) { - return undefined; - } - return this.findTrack2Stats(report, "local"); - } - - public getTrack2stats(): Map<TrackID, MediaTrackStats> { - return this.track2stats; - } -} diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/src/webrtc/stats/statsReport.ts b/includes/external/matrix/node_modules/matrix-js-sdk/src/webrtc/stats/statsReport.ts deleted file mode 100644 index 56d6c4b..0000000 --- a/includes/external/matrix/node_modules/matrix-js-sdk/src/webrtc/stats/statsReport.ts +++ /dev/null @@ -1,56 +0,0 @@ -/* -Copyright 2023 The Matrix.org Foundation C.I.C. - -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 { ConnectionStatsBandwidth, ConnectionStatsBitrate, PacketLoos } from "./connectionStats"; -import { TransportStats } from "./transportStats"; -import { Resolution } from "./media/mediaTrackStats"; - -export enum StatsReport { - CONNECTION_STATS = "StatsReport.connection_stats", - BYTE_SENT_STATS = "StatsReport.byte_sent_stats", -} - -export type TrackID = string; -export type ByteSend = number; - -export interface ByteSentStatsReport extends Map<TrackID, ByteSend> { - // is a map: `local trackID` => byte send -} - -export interface ConnectionStatsReport { - bandwidth: ConnectionStatsBandwidth; - bitrate: ConnectionStatsBitrate; - packetLoss: PacketLoos; - resolution: ResolutionMap; - framerate: FramerateMap; - codec: CodecMap; - transport: TransportStats[]; -} - -export interface ResolutionMap { - local: Map<TrackID, Resolution>; - remote: Map<TrackID, Resolution>; -} - -export interface FramerateMap { - local: Map<TrackID, number>; - remote: Map<TrackID, number>; -} - -export interface CodecMap { - local: Map<TrackID, string>; - remote: Map<TrackID, string>; -} diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/src/webrtc/stats/statsReportBuilder.ts b/includes/external/matrix/node_modules/matrix-js-sdk/src/webrtc/stats/statsReportBuilder.ts deleted file mode 100644 index c1af471..0000000 --- a/includes/external/matrix/node_modules/matrix-js-sdk/src/webrtc/stats/statsReportBuilder.ts +++ /dev/null @@ -1,110 +0,0 @@ -/* -Copyright 2023 The Matrix.org Foundation C.I.C. - -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 { CodecMap, ConnectionStatsReport, FramerateMap, ResolutionMap, TrackID } from "./statsReport"; -import { MediaTrackStats, Resolution } from "./media/mediaTrackStats"; - -export class StatsReportBuilder { - public static build(stats: Map<TrackID, MediaTrackStats>): ConnectionStatsReport { - const report = {} as ConnectionStatsReport; - - // process stats - const totalPackets = { - download: 0, - upload: 0, - }; - const lostPackets = { - download: 0, - upload: 0, - }; - let bitrateDownload = 0; - let bitrateUpload = 0; - const resolutions: ResolutionMap = { - local: new Map<TrackID, Resolution>(), - remote: new Map<TrackID, Resolution>(), - }; - const framerates: FramerateMap = { local: new Map<TrackID, number>(), remote: new Map<TrackID, number>() }; - const codecs: CodecMap = { local: new Map<TrackID, string>(), remote: new Map<TrackID, string>() }; - - let audioBitrateDownload = 0; - let audioBitrateUpload = 0; - let videoBitrateDownload = 0; - let videoBitrateUpload = 0; - - for (const [trackId, trackStats] of stats) { - // process packet loss stats - const loss = trackStats.getLoss(); - const type = loss.isDownloadStream ? "download" : "upload"; - - totalPackets[type] += loss.packetsTotal; - lostPackets[type] += loss.packetsLost; - - // process bitrate stats - bitrateDownload += trackStats.getBitrate().download; - bitrateUpload += trackStats.getBitrate().upload; - - // collect resolutions and framerates - if (trackStats.kind === "audio") { - audioBitrateDownload += trackStats.getBitrate().download; - audioBitrateUpload += trackStats.getBitrate().upload; - } else { - videoBitrateDownload += trackStats.getBitrate().download; - videoBitrateUpload += trackStats.getBitrate().upload; - } - - resolutions[trackStats.getType()].set(trackId, trackStats.getResolution()); - framerates[trackStats.getType()].set(trackId, trackStats.getFramerate()); - codecs[trackStats.getType()].set(trackId, trackStats.getCodec()); - - trackStats.resetBitrate(); - } - - report.bitrate = { - upload: bitrateUpload, - download: bitrateDownload, - }; - - report.bitrate.audio = { - upload: audioBitrateUpload, - download: audioBitrateDownload, - }; - - report.bitrate.video = { - upload: videoBitrateUpload, - download: videoBitrateDownload, - }; - - report.packetLoss = { - total: StatsReportBuilder.calculatePacketLoss( - lostPackets.download + lostPackets.upload, - totalPackets.download + totalPackets.upload, - ), - download: StatsReportBuilder.calculatePacketLoss(lostPackets.download, totalPackets.download), - upload: StatsReportBuilder.calculatePacketLoss(lostPackets.upload, totalPackets.upload), - }; - report.framerate = framerates; - report.resolution = resolutions; - report.codec = codecs; - return report; - } - - private static calculatePacketLoss(lostPackets: number, totalPackets: number): number { - if (!totalPackets || totalPackets <= 0 || !lostPackets || lostPackets <= 0) { - return 0; - } - - return Math.round((lostPackets / totalPackets) * 100); - } -} diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/src/webrtc/stats/statsReportEmitter.ts b/includes/external/matrix/node_modules/matrix-js-sdk/src/webrtc/stats/statsReportEmitter.ts deleted file mode 100644 index cf01470..0000000 --- a/includes/external/matrix/node_modules/matrix-js-sdk/src/webrtc/stats/statsReportEmitter.ts +++ /dev/null @@ -1,33 +0,0 @@ -/* -Copyright 2023 The Matrix.org Foundation C.I.C. - -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 { TypedEventEmitter } from "../../models/typed-event-emitter"; -import { ByteSentStatsReport, ConnectionStatsReport, StatsReport } from "./statsReport"; - -export type StatsReportHandlerMap = { - [StatsReport.BYTE_SENT_STATS]: (report: ByteSentStatsReport) => void; - [StatsReport.CONNECTION_STATS]: (report: ConnectionStatsReport) => void; -}; - -export class StatsReportEmitter extends TypedEventEmitter<StatsReport, StatsReportHandlerMap> { - public emitByteSendReport(byteSentStats: ByteSentStatsReport): void { - this.emit(StatsReport.BYTE_SENT_STATS, byteSentStats); - } - - public emitConnectionStatsReport(report: ConnectionStatsReport): void { - this.emit(StatsReport.CONNECTION_STATS, report); - } -} diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/src/webrtc/stats/statsReportGatherer.ts b/includes/external/matrix/node_modules/matrix-js-sdk/src/webrtc/stats/statsReportGatherer.ts deleted file mode 100644 index 769ba6e..0000000 --- a/includes/external/matrix/node_modules/matrix-js-sdk/src/webrtc/stats/statsReportGatherer.ts +++ /dev/null @@ -1,183 +0,0 @@ -/* -Copyright 2023 The Matrix.org Foundation C.I.C. - -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 { ConnectionStats } from "./connectionStats"; -import { StatsReportEmitter } from "./statsReportEmitter"; -import { ByteSend, ByteSentStatsReport, TrackID } from "./statsReport"; -import { ConnectionStatsReporter } from "./connectionStatsReporter"; -import { TransportStatsReporter } from "./transportStatsReporter"; -import { MediaSsrcHandler } from "./media/mediaSsrcHandler"; -import { MediaTrackHandler } from "./media/mediaTrackHandler"; -import { MediaTrackStatsHandler } from "./media/mediaTrackStatsHandler"; -import { TrackStatsReporter } from "./trackStatsReporter"; -import { StatsReportBuilder } from "./statsReportBuilder"; -import { StatsValueFormatter } from "./statsValueFormatter"; - -export class StatsReportGatherer { - private isActive = true; - private previousStatsReport: RTCStatsReport | undefined; - private currentStatsReport: RTCStatsReport | undefined; - private readonly connectionStats = new ConnectionStats(); - - private readonly trackStats: MediaTrackStatsHandler; - - // private readonly ssrcToMid = { local: new Map<Mid, Ssrc[]>(), remote: new Map<Mid, Ssrc[]>() }; - - public constructor( - public readonly callId: string, - public readonly remoteUserId: string, - private readonly pc: RTCPeerConnection, - private readonly emitter: StatsReportEmitter, - private readonly isFocus = true, - ) { - pc.addEventListener("signalingstatechange", this.onSignalStateChange.bind(this)); - this.trackStats = new MediaTrackStatsHandler(new MediaSsrcHandler(), new MediaTrackHandler(pc)); - } - - public async processStats(groupCallId: string, localUserId: string): Promise<boolean> { - if (this.isActive) { - const statsPromise = this.pc.getStats(); - if (typeof statsPromise?.then === "function") { - return statsPromise - .then((report) => { - // @ts-ignore - this.currentStatsReport = typeof report?.result === "function" ? report.result() : report; - try { - this.processStatsReport(groupCallId, localUserId); - } catch (error) { - this.isActive = false; - return false; - } - - this.previousStatsReport = this.currentStatsReport; - return true; - }) - .catch((error) => { - this.handleError(error); - return false; - }); - } - this.isActive = false; - } - return Promise.resolve(false); - } - - private processStatsReport(groupCallId: string, localUserId: string): void { - const byteSentStats: ByteSentStatsReport = new Map<TrackID, ByteSend>(); - - this.currentStatsReport?.forEach((now) => { - const before = this.previousStatsReport ? this.previousStatsReport.get(now.id) : null; - // RTCIceCandidatePairStats - https://w3c.github.io/webrtc-stats/#candidatepair-dict* - if (now.type === "candidate-pair" && now.nominated && now.state === "succeeded") { - this.connectionStats.bandwidth = ConnectionStatsReporter.buildBandwidthReport(now); - this.connectionStats.transport = TransportStatsReporter.buildReport( - this.currentStatsReport, - now, - this.connectionStats.transport, - this.isFocus, - ); - - // RTCReceivedRtpStreamStats - // https://w3c.github.io/webrtc-stats/#receivedrtpstats-dict* - // RTCSentRtpStreamStats - // https://w3c.github.io/webrtc-stats/#sentrtpstats-dict* - } else if (now.type === "inbound-rtp" || now.type === "outbound-rtp") { - const trackStats = this.trackStats.findTrack2Stats( - now, - now.type === "inbound-rtp" ? "remote" : "local", - ); - if (!trackStats) { - return; - } - - if (before) { - TrackStatsReporter.buildPacketsLost(trackStats, now, before); - } - - // Get the resolution and framerate for only remote video sources here. For the local video sources, - // 'track' stats will be used since they have the updated resolution based on the simulcast streams - // currently being sent. Promise based getStats reports three 'outbound-rtp' streams and there will be - // more calculations needed to determine what is the highest resolution stream sent by the client if the - // 'outbound-rtp' stats are used. - if (now.type === "inbound-rtp") { - TrackStatsReporter.buildFramerateResolution(trackStats, now); - if (before) { - TrackStatsReporter.buildBitrateReceived(trackStats, now, before); - } - } else if (before) { - byteSentStats.set(trackStats.trackId, StatsValueFormatter.getNonNegativeValue(now.bytesSent)); - TrackStatsReporter.buildBitrateSend(trackStats, now, before); - } - TrackStatsReporter.buildCodec(this.currentStatsReport, trackStats, now); - } else if (now.type === "track" && now.kind === "video" && !now.remoteSource) { - const trackStats = this.trackStats.findLocalVideoTrackStats(now); - if (!trackStats) { - return; - } - TrackStatsReporter.buildFramerateResolution(trackStats, now); - TrackStatsReporter.calculateSimulcastFramerate( - trackStats, - now, - before, - this.trackStats.mediaTrackHandler.getActiveSimulcastStreams(), - ); - } - }); - - this.emitter.emitByteSendReport(byteSentStats); - this.processAndEmitReport(); - } - - public setActive(isActive: boolean): void { - this.isActive = isActive; - } - - public getActive(): boolean { - return this.isActive; - } - - private handleError(_: any): void { - this.isActive = false; - } - - private processAndEmitReport(): void { - const report = StatsReportBuilder.build(this.trackStats.getTrack2stats()); - - this.connectionStats.bandwidth = report.bandwidth; - this.connectionStats.bitrate = report.bitrate; - this.connectionStats.packetLoss = report.packetLoss; - - this.emitter.emitConnectionStatsReport({ - ...report, - transport: this.connectionStats.transport, - }); - - this.connectionStats.transport = []; - } - - public stopProcessingStats(): void {} - - private onSignalStateChange(): void { - if (this.pc.signalingState === "stable") { - if (this.pc.currentRemoteDescription) { - this.trackStats.mediaSsrcHandler.parse(this.pc.currentRemoteDescription.sdp, "remote"); - } - if (this.pc.currentLocalDescription) { - this.trackStats.mediaSsrcHandler.parse(this.pc.currentLocalDescription.sdp, "local"); - } - } - } -} diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/src/webrtc/stats/statsValueFormatter.ts b/includes/external/matrix/node_modules/matrix-js-sdk/src/webrtc/stats/statsValueFormatter.ts deleted file mode 100644 index c658fa6..0000000 --- a/includes/external/matrix/node_modules/matrix-js-sdk/src/webrtc/stats/statsValueFormatter.ts +++ /dev/null @@ -1,27 +0,0 @@ -/* -Copyright 2023 The Matrix.org Foundation C.I.C. -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. -*/ -export class StatsValueFormatter { - public static getNonNegativeValue(imput: any): number { - let value = imput; - - if (typeof value !== "number") { - value = Number(value); - } - - if (isNaN(value)) { - return 0; - } - - return Math.max(0, value); - } -} diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/src/webrtc/stats/trackStatsReporter.ts b/includes/external/matrix/node_modules/matrix-js-sdk/src/webrtc/stats/trackStatsReporter.ts deleted file mode 100644 index 1f6fcd6..0000000 --- a/includes/external/matrix/node_modules/matrix-js-sdk/src/webrtc/stats/trackStatsReporter.ts +++ /dev/null @@ -1,117 +0,0 @@ -import { MediaTrackStats } from "./media/mediaTrackStats"; -import { StatsValueFormatter } from "./statsValueFormatter"; - -export class TrackStatsReporter { - public static buildFramerateResolution(trackStats: MediaTrackStats, now: any): void { - const resolution = { - height: now.frameHeight, - width: now.frameWidth, - }; - const frameRate = now.framesPerSecond; - - if (resolution.height && resolution.width) { - trackStats.setResolution(resolution); - } - trackStats.setFramerate(Math.round(frameRate || 0)); - } - - public static calculateSimulcastFramerate(trackStats: MediaTrackStats, now: any, before: any, layer: number): void { - let frameRate = trackStats.getFramerate(); - if (!frameRate) { - if (before) { - const timeMs = now.timestamp - before.timestamp; - - if (timeMs > 0 && now.framesSent) { - const numberOfFramesSinceBefore = now.framesSent - before.framesSent; - - frameRate = (numberOfFramesSinceBefore / timeMs) * 1000; - } - } - - if (!frameRate) { - return; - } - } - - // Reset frame rate to 0 when video is suspended as a result of endpoint falling out of last-n. - frameRate = layer ? Math.round(frameRate / layer) : 0; - trackStats.setFramerate(frameRate); - } - - public static buildCodec(report: RTCStatsReport | undefined, trackStats: MediaTrackStats, now: any): void { - const codec = report?.get(now.codecId); - - if (codec) { - /** - * The mime type has the following form: video/VP8 or audio/ISAC, - * so we what to keep just the type after the '/', audio and video - * keys will be added on the processing side. - */ - const codecShortType = codec.mimeType.split("/")[1]; - - codecShortType && trackStats.setCodec(codecShortType); - } - } - - public static buildBitrateReceived(trackStats: MediaTrackStats, now: any, before: any): void { - trackStats.setBitrate({ - download: TrackStatsReporter.calculateBitrate( - now.bytesReceived, - before.bytesReceived, - now.timestamp, - before.timestamp, - ), - upload: 0, - }); - } - - public static buildBitrateSend(trackStats: MediaTrackStats, now: any, before: any): void { - trackStats.setBitrate({ - download: 0, - upload: this.calculateBitrate(now.bytesSent, before.bytesSent, now.timestamp, before.timestamp), - }); - } - - public static buildPacketsLost(trackStats: MediaTrackStats, now: any, before: any): void { - const key = now.type === "outbound-rtp" ? "packetsSent" : "packetsReceived"; - - let packetsNow = now[key]; - if (!packetsNow || packetsNow < 0) { - packetsNow = 0; - } - - const packetsBefore = StatsValueFormatter.getNonNegativeValue(before[key]); - const packetsDiff = Math.max(0, packetsNow - packetsBefore); - - const packetsLostNow = StatsValueFormatter.getNonNegativeValue(now.packetsLost); - const packetsLostBefore = StatsValueFormatter.getNonNegativeValue(before.packetsLost); - const packetsLostDiff = Math.max(0, packetsLostNow - packetsLostBefore); - - trackStats.setLoss({ - packetsTotal: packetsDiff + packetsLostDiff, - packetsLost: packetsLostDiff, - isDownloadStream: now.type !== "outbound-rtp", - }); - } - - private static calculateBitrate( - bytesNowAny: any, - bytesBeforeAny: any, - nowTimestamp: number, - beforeTimestamp: number, - ): number { - const bytesNow = StatsValueFormatter.getNonNegativeValue(bytesNowAny); - const bytesBefore = StatsValueFormatter.getNonNegativeValue(bytesBeforeAny); - const bytesProcessed = Math.max(0, bytesNow - bytesBefore); - - const timeMs = nowTimestamp - beforeTimestamp; - let bitrateKbps = 0; - - if (timeMs > 0) { - // TODO is there any reason to round here? - bitrateKbps = Math.round((bytesProcessed * 8) / timeMs); - } - - return bitrateKbps; - } -} diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/src/webrtc/stats/transportStats.ts b/includes/external/matrix/node_modules/matrix-js-sdk/src/webrtc/stats/transportStats.ts deleted file mode 100644 index 2b6e975..0000000 --- a/includes/external/matrix/node_modules/matrix-js-sdk/src/webrtc/stats/transportStats.ts +++ /dev/null @@ -1,26 +0,0 @@ -/* -Copyright 2023 The Matrix.org Foundation C.I.C. - -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. -*/ - -export interface TransportStats { - ip: string; - type: string; - localIp: string; - isFocus: boolean; - localCandidateType: string; - remoteCandidateType: string; - networkType: string; - rtt: number; -} diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/src/webrtc/stats/transportStatsReporter.ts b/includes/external/matrix/node_modules/matrix-js-sdk/src/webrtc/stats/transportStatsReporter.ts deleted file mode 100644 index d419a73..0000000 --- a/includes/external/matrix/node_modules/matrix-js-sdk/src/webrtc/stats/transportStatsReporter.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { TransportStats } from "./transportStats"; - -export class TransportStatsReporter { - public static buildReport( - report: RTCStatsReport | undefined, - now: RTCIceCandidatePairStats, - conferenceStatsTransport: TransportStats[], - isFocus: boolean, - ): TransportStats[] { - const localUsedCandidate = report?.get(now.localCandidateId); - const remoteUsedCandidate = report?.get(now.remoteCandidateId); - - // RTCIceCandidateStats - // https://w3c.github.io/webrtc-stats/#icecandidate-dict* - if (remoteUsedCandidate && localUsedCandidate) { - const remoteIpAddress = - remoteUsedCandidate.ip !== undefined ? remoteUsedCandidate.ip : remoteUsedCandidate.address; - const remotePort = remoteUsedCandidate.port; - const ip = `${remoteIpAddress}:${remotePort}`; - - const localIpAddress = - localUsedCandidate.ip !== undefined ? localUsedCandidate.ip : localUsedCandidate.address; - const localPort = localUsedCandidate.port; - const localIp = `${localIpAddress}:${localPort}`; - - const type = remoteUsedCandidate.protocol; - - // Save the address unless it has been saved already. - if ( - !conferenceStatsTransport.some( - (t: TransportStats) => t.ip === ip && t.type === type && t.localIp === localIp, - ) - ) { - conferenceStatsTransport.push({ - ip, - type, - localIp, - isFocus, - localCandidateType: localUsedCandidate.candidateType, - remoteCandidateType: remoteUsedCandidate.candidateType, - networkType: localUsedCandidate.networkType, - rtt: now.currentRoundTripTime ? now.currentRoundTripTime * 1000 : NaN, - } as TransportStats); - } - } - return conferenceStatsTransport; - } -} |