From 9d05a06fdb34f10deb6ed5c08b6ac540a4a03dd0 Mon Sep 17 00:00:00 2001 From: skyman503 Date: Thu, 27 Apr 2023 11:20:02 +0200 Subject: [PATCH 1/4] init --- .../Sources/MembraneRTC/MembraneRTC.swift | 4 ++ .../MembraneRTC/PeerConnectionManager.swift | 49 +++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/MembraneRTC/Sources/MembraneRTC/MembraneRTC.swift b/MembraneRTC/Sources/MembraneRTC/MembraneRTC.swift index f8ae3112..bde706d4 100644 --- a/MembraneRTC/Sources/MembraneRTC/MembraneRTC.swift +++ b/MembraneRTC/Sources/MembraneRTC/MembraneRTC.swift @@ -433,6 +433,10 @@ public class MembraneRTC: MulticastDelegate, ObservableObje peerConnectionManager.setTrackEncoding(trackId: trackId, encoding: encoding, enabled: enabled) } + public func getStats() { + print(peerConnectionManager.getStats()) + } + /** Changes severity level of debug logs. diff --git a/MembraneRTC/Sources/MembraneRTC/PeerConnectionManager.swift b/MembraneRTC/Sources/MembraneRTC/PeerConnectionManager.swift index 74bad0d6..b236b3ba 100644 --- a/MembraneRTC/Sources/MembraneRTC/PeerConnectionManager.swift +++ b/MembraneRTC/Sources/MembraneRTC/PeerConnectionManager.swift @@ -26,6 +26,8 @@ internal class PeerConnectionManager: NSObject, RTCPeerConnectionDelegate { private let peerConnectionListener: PeerConnectionListener + private var peerConnectionStats: [String: [String: Any]] = [:] + internal init( config: RTCConfiguration, peerConnectionFactory: PeerConnectionFactoryWrapper, peerConnectionListener: PeerConnectionListener @@ -274,6 +276,53 @@ internal class PeerConnectionManager: NSObject, RTCPeerConnectionDelegate { sender.parameters = params } + private func extractRelevantStats(rp: RTCStatisticsReport) { + // print(rp.statistics) + rp.statistics.forEach { it1 in + let it = it1.value + if it.type == "outbound-rtp" { + var tmp: [String: Any] = [:] + if let kind = it.values["kind"] { + tmp["kind"] = kind + } + if let rid = it.values["rid"] { + tmp["rid"] = rid + } + if let bytesSent = it.values["bytesSent"] { + tmp["bytesSent"] = bytesSent + } + if let targetBitrate = it.values["targetBitrate"] { + tmp["targetBitrate"] = targetBitrate + } + if let packetsSent = it.values["packetsSent"] { + tmp["packetsSent"] = packetsSent + } + if let framesEncoded = it.values["framesEncoded"] { + tmp["framesEncoded"] = framesEncoded + } + if let framesPerSecond = it.values["framesPerSecond"] { + tmp["framesPerSecond"] = framesPerSecond + } + if let width = it.values["frameWidth"] as? Int, let height = it.values["frameHeight"] as? Int { + tmp["frameWidthHeightRatio"] = Double(width) / Double(height) + } + if let qualityLimitationDurations = it.values["qualityLimitationDurations"] { + tmp["qualityLimitationDurations"] = qualityLimitationDurations + } + peerConnectionStats[it.id as String] = tmp + } + } + } + + public func getStats() -> [String: [String: Any]] { + if connection != nil { + connection?.statistics(completionHandler: { RTCStatisticsReport in + self.extractRelevantStats(rp: RTCStatisticsReport) + }) + } + return peerConnectionStats + } + private func applyBitrate(encodings: [RTCRtpEncodingParameters], maxBitrate: TrackBandwidthLimit) { switch maxBitrate { case .BandwidthLimit(let limit): From 2908fb146c92d08d0d0d45a45ed6c7b4e704ea0c Mon Sep 17 00:00:00 2001 From: skyman503 Date: Thu, 27 Apr 2023 11:27:48 +0200 Subject: [PATCH 2/4] Add return type --- MembraneRTC/Sources/MembraneRTC/MembraneRTC.swift | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/MembraneRTC/Sources/MembraneRTC/MembraneRTC.swift b/MembraneRTC/Sources/MembraneRTC/MembraneRTC.swift index bde706d4..36731228 100644 --- a/MembraneRTC/Sources/MembraneRTC/MembraneRTC.swift +++ b/MembraneRTC/Sources/MembraneRTC/MembraneRTC.swift @@ -433,8 +433,13 @@ public class MembraneRTC: MulticastDelegate, ObservableObje peerConnectionManager.setTrackEncoding(trackId: trackId, encoding: encoding, enabled: enabled) } - public func getStats() { - print(peerConnectionManager.getStats()) + /** + Returns current connection stats. + + - Returns: a map containing statistics + */ + public func getStats() -> [String: [String: Any]] { + return peerConnectionManager.getStats() } /** From c7605d91027d4eb402d2e29f33f28525fdb15198 Mon Sep 17 00:00:00 2001 From: skyman503 Date: Thu, 27 Apr 2023 16:26:26 +0200 Subject: [PATCH 3/4] Add types --- .../Sources/MembraneRTC/MembraneRTC.swift | 2 +- .../MembraneRTC/PeerConnectionManager.swift | 64 ++++++++-------- .../Sources/MembraneRTC/Types/RTCStats.swift | 73 +++++++++++++++++++ 3 files changed, 107 insertions(+), 32 deletions(-) create mode 100644 MembraneRTC/Sources/MembraneRTC/Types/RTCStats.swift diff --git a/MembraneRTC/Sources/MembraneRTC/MembraneRTC.swift b/MembraneRTC/Sources/MembraneRTC/MembraneRTC.swift index 36731228..d815a128 100644 --- a/MembraneRTC/Sources/MembraneRTC/MembraneRTC.swift +++ b/MembraneRTC/Sources/MembraneRTC/MembraneRTC.swift @@ -438,7 +438,7 @@ public class MembraneRTC: MulticastDelegate, ObservableObje - Returns: a map containing statistics */ - public func getStats() -> [String: [String: Any]] { + public func getStats() -> [String: RTCStats] { return peerConnectionManager.getStats() } diff --git a/MembraneRTC/Sources/MembraneRTC/PeerConnectionManager.swift b/MembraneRTC/Sources/MembraneRTC/PeerConnectionManager.swift index b236b3ba..24da065c 100644 --- a/MembraneRTC/Sources/MembraneRTC/PeerConnectionManager.swift +++ b/MembraneRTC/Sources/MembraneRTC/PeerConnectionManager.swift @@ -26,7 +26,7 @@ internal class PeerConnectionManager: NSObject, RTCPeerConnectionDelegate { private let peerConnectionListener: PeerConnectionListener - private var peerConnectionStats: [String: [String: Any]] = [:] + private var peerConnectionStats: [String: RTCStats] = [:] internal init( config: RTCConfiguration, peerConnectionFactory: PeerConnectionFactoryWrapper, @@ -277,44 +277,46 @@ internal class PeerConnectionManager: NSObject, RTCPeerConnectionDelegate { } private func extractRelevantStats(rp: RTCStatisticsReport) { - // print(rp.statistics) rp.statistics.forEach { it1 in let it = it1.value if it.type == "outbound-rtp" { - var tmp: [String: Any] = [:] - if let kind = it.values["kind"] { - tmp["kind"] = kind - } - if let rid = it.values["rid"] { - tmp["rid"] = rid - } - if let bytesSent = it.values["bytesSent"] { - tmp["bytesSent"] = bytesSent - } - if let targetBitrate = it.values["targetBitrate"] { - tmp["targetBitrate"] = targetBitrate - } - if let packetsSent = it.values["packetsSent"] { - tmp["packetsSent"] = packetsSent - } - if let framesEncoded = it.values["framesEncoded"] { - tmp["framesEncoded"] = framesEncoded - } - if let framesPerSecond = it.values["framesPerSecond"] { - tmp["framesPerSecond"] = framesPerSecond - } - if let width = it.values["frameWidth"] as? Int, let height = it.values["frameHeight"] as? Int { - tmp["frameWidthHeightRatio"] = Double(width) / Double(height) - } - if let qualityLimitationDurations = it.values["qualityLimitationDurations"] { - tmp["qualityLimitationDurations"] = qualityLimitationDurations - } + let duration = it.values["qualityLimitationDurations"] as? [String: Double] + let qualityLimitation: QualityLimitationDurations = QualityLimitationDurations( + bandwidth: duration?["bandwidth"] ?? 0.0, + cpu: duration?["cpu"] ?? 0.0, none: duration?["none"] ?? 0.0, other: duration?["other"] ?? 0.0) + let tmp = RTCOutboundStats( + kind: it.values["kind"] as? String ?? "", + rid: it.values["rid"] as? String ?? "", + bytesSent: it.values["bytesSent"] as? Int ?? 0, + targetBitrate: it.values["targetBitrate"] as? Double ?? 0.0, + packetsSent: it.values["packetsSent"] as? Int ?? 0, + framesEncoded: it.values["framesEncoded"] as? Int ?? 0, + framesPerSecond: it.values["framesPerSecond"] as? Double ?? 0.0, + frameWidthHeightRatio: it.values["frameWidthHeightRatio"] as? Double ?? 0.0, + qualityLimitationDurations: qualityLimitation + ) + + peerConnectionStats[it.id as String] = tmp + } else if it.type == "inbound-rtp" { + let tmp = RTCInboundStats( + kind: it.values["kind"] as? String ?? "", + jitter: it.values["jitter"] as? Double ?? 0.0, + packetsLost: it.values["packetsLost"] as? Int ?? 0, + packetsReceived: it.values["packetsReceived"] as? Int ?? 0, + bytesReceived: it.values["bytesReceived"] as? Int ?? 0, + framesReceived: it.values["framesReceived"] as? Int ?? 0, + frameWidth: it.values["frameWidth"] as? Int ?? 0, + frameHeight: it.values["frameHeight"] as? Int ?? 0, + framesPerSecond: it.values["framesPerSecond"] as? Double ?? 0.0, + framesDropped: it.values["framesDropped"] as? Int ?? 0 + ) + peerConnectionStats[it.id as String] = tmp } } } - public func getStats() -> [String: [String: Any]] { + public func getStats() -> [String: RTCStats] { if connection != nil { connection?.statistics(completionHandler: { RTCStatisticsReport in self.extractRelevantStats(rp: RTCStatisticsReport) diff --git a/MembraneRTC/Sources/MembraneRTC/Types/RTCStats.swift b/MembraneRTC/Sources/MembraneRTC/Types/RTCStats.swift new file mode 100644 index 00000000..bf3958fc --- /dev/null +++ b/MembraneRTC/Sources/MembraneRTC/Types/RTCStats.swift @@ -0,0 +1,73 @@ +public struct QualityLimitationDurations { + public let bandwidth: Double + public let cpu: Double + public let none: Double + public let other: Double + + public init(bandwidth: Double, cpu: Double, none: Double, other: Double) { + self.bandwidth = bandwidth + self.cpu = cpu + self.none = none + self.other = other + } +} + +public protocol RTCStats {} + +public struct RTCOutboundStats: RTCStats { + public let kind: String + public let rid: String + public let bytesSent: Int + public let targetBitrate: Double + public let packetsSent: Int + public let framesEncoded: Int + public let framesPerSecond: Double + public let frameWidthHeightRatio: Double + public let qualityLimitationDurations: QualityLimitationDurations? + + public init( + kind: String = "", rid: String = "", bytesSent: Int = 0, targetBitrate: Double = 0.0, packetsSent: Int = 0, + framesEncoded: Int = 0, framesPerSecond: Double = 0.0, frameWidthHeightRatio: Double = 0.0, + qualityLimitationDurations: QualityLimitationDurations? = nil + ) { + self.kind = kind + self.rid = rid + self.bytesSent = bytesSent + self.targetBitrate = targetBitrate + self.packetsSent = packetsSent + self.framesEncoded = framesEncoded + self.framesPerSecond = framesPerSecond + self.frameWidthHeightRatio = frameWidthHeightRatio + self.qualityLimitationDurations = qualityLimitationDurations + } +} + +public struct RTCInboundStats: RTCStats { + public let kind: String + public let jitter: Double + public let packetsLost: Int + public let packetsReceived: Int + public let bytesReceived: Int + public let framesReceived: Int + public let frameWidth: Int + public let frameHeight: Int + public let framesPerSecond: Double + public let framesDropped: Int + + public init( + kind: String = "", jitter: Double = 0.0, packetsLost: Int = 0, packetsReceived: Int = 0, bytesReceived: Int = 0, + framesReceived: Int = 0, frameWidth: Int = 0, frameHeight: Int = 0, framesPerSecond: Double = 0.0, + framesDropped: Int = 0 + ) { + self.kind = kind + self.jitter = jitter + self.packetsLost = packetsLost + self.packetsReceived = packetsReceived + self.bytesReceived = bytesReceived + self.framesReceived = framesReceived + self.frameWidth = frameWidth + self.frameHeight = frameHeight + self.framesPerSecond = framesPerSecond + self.framesDropped = framesDropped + } +} From 4d109e1ff48708a7cb73ad9156a422a5c614bf7b Mon Sep 17 00:00:00 2001 From: skyman503 Date: Fri, 28 Apr 2023 08:15:12 +0200 Subject: [PATCH 4/4] Use UInt --- .../MembraneRTC/PeerConnectionManager.swift | 28 +++++++------- .../Sources/MembraneRTC/Types/RTCStats.swift | 37 ++++++++++--------- 2 files changed, 35 insertions(+), 30 deletions(-) diff --git a/MembraneRTC/Sources/MembraneRTC/PeerConnectionManager.swift b/MembraneRTC/Sources/MembraneRTC/PeerConnectionManager.swift index 24da065c..e8201d3e 100644 --- a/MembraneRTC/Sources/MembraneRTC/PeerConnectionManager.swift +++ b/MembraneRTC/Sources/MembraneRTC/PeerConnectionManager.swift @@ -284,15 +284,17 @@ internal class PeerConnectionManager: NSObject, RTCPeerConnectionDelegate { let qualityLimitation: QualityLimitationDurations = QualityLimitationDurations( bandwidth: duration?["bandwidth"] ?? 0.0, cpu: duration?["cpu"] ?? 0.0, none: duration?["none"] ?? 0.0, other: duration?["other"] ?? 0.0) + let tmp = RTCOutboundStats( kind: it.values["kind"] as? String ?? "", rid: it.values["rid"] as? String ?? "", - bytesSent: it.values["bytesSent"] as? Int ?? 0, + bytesSent: it.values["bytesSent"] as? UInt ?? 0, targetBitrate: it.values["targetBitrate"] as? Double ?? 0.0, - packetsSent: it.values["packetsSent"] as? Int ?? 0, - framesEncoded: it.values["framesEncoded"] as? Int ?? 0, + packetsSent: it.values["packetsSent"] as? UInt ?? 0, + framesEncoded: it.values["framesEncoded"] as? UInt ?? 0, framesPerSecond: it.values["framesPerSecond"] as? Double ?? 0.0, - frameWidthHeightRatio: it.values["frameWidthHeightRatio"] as? Double ?? 0.0, + frameWidth: it.values["frameWidth"] as? UInt ?? 0, + frameHeight: it.values["frameHeight"] as? UInt ?? 0, qualityLimitationDurations: qualityLimitation ) @@ -301,14 +303,14 @@ internal class PeerConnectionManager: NSObject, RTCPeerConnectionDelegate { let tmp = RTCInboundStats( kind: it.values["kind"] as? String ?? "", jitter: it.values["jitter"] as? Double ?? 0.0, - packetsLost: it.values["packetsLost"] as? Int ?? 0, - packetsReceived: it.values["packetsReceived"] as? Int ?? 0, - bytesReceived: it.values["bytesReceived"] as? Int ?? 0, - framesReceived: it.values["framesReceived"] as? Int ?? 0, - frameWidth: it.values["frameWidth"] as? Int ?? 0, - frameHeight: it.values["frameHeight"] as? Int ?? 0, + packetsLost: it.values["packetsLost"] as? UInt ?? 0, + packetsReceived: it.values["packetsReceived"] as? UInt ?? 0, + bytesReceived: it.values["bytesReceived"] as? UInt ?? 0, + framesReceived: it.values["framesReceived"] as? UInt ?? 0, + frameWidth: it.values["frameWidth"] as? UInt ?? 0, + frameHeight: it.values["frameHeight"] as? UInt ?? 0, framesPerSecond: it.values["framesPerSecond"] as? Double ?? 0.0, - framesDropped: it.values["framesDropped"] as? Int ?? 0 + framesDropped: it.values["framesDropped"] as? UInt ?? 0 ) peerConnectionStats[it.id as String] = tmp @@ -317,8 +319,8 @@ internal class PeerConnectionManager: NSObject, RTCPeerConnectionDelegate { } public func getStats() -> [String: RTCStats] { - if connection != nil { - connection?.statistics(completionHandler: { RTCStatisticsReport in + if let connection = connection { + connection.statistics(completionHandler: { RTCStatisticsReport in self.extractRelevantStats(rp: RTCStatisticsReport) }) } diff --git a/MembraneRTC/Sources/MembraneRTC/Types/RTCStats.swift b/MembraneRTC/Sources/MembraneRTC/Types/RTCStats.swift index bf3958fc..c8f72559 100644 --- a/MembraneRTC/Sources/MembraneRTC/Types/RTCStats.swift +++ b/MembraneRTC/Sources/MembraneRTC/Types/RTCStats.swift @@ -17,17 +17,18 @@ public protocol RTCStats {} public struct RTCOutboundStats: RTCStats { public let kind: String public let rid: String - public let bytesSent: Int + public let bytesSent: UInt public let targetBitrate: Double - public let packetsSent: Int - public let framesEncoded: Int + public let packetsSent: UInt + public let framesEncoded: UInt public let framesPerSecond: Double - public let frameWidthHeightRatio: Double + public let frameWidth: UInt + public let frameHeight: UInt public let qualityLimitationDurations: QualityLimitationDurations? public init( - kind: String = "", rid: String = "", bytesSent: Int = 0, targetBitrate: Double = 0.0, packetsSent: Int = 0, - framesEncoded: Int = 0, framesPerSecond: Double = 0.0, frameWidthHeightRatio: Double = 0.0, + kind: String = "", rid: String = "", bytesSent: UInt = 0, targetBitrate: Double = 0.0, packetsSent: UInt = 0, + framesEncoded: UInt = 0, framesPerSecond: Double = 0.0, frameWidth: UInt = 0, frameHeight: UInt = 0, qualityLimitationDurations: QualityLimitationDurations? = nil ) { self.kind = kind @@ -37,7 +38,8 @@ public struct RTCOutboundStats: RTCStats { self.packetsSent = packetsSent self.framesEncoded = framesEncoded self.framesPerSecond = framesPerSecond - self.frameWidthHeightRatio = frameWidthHeightRatio + self.frameWidth = frameWidth + self.frameHeight = frameHeight self.qualityLimitationDurations = qualityLimitationDurations } } @@ -45,19 +47,20 @@ public struct RTCOutboundStats: RTCStats { public struct RTCInboundStats: RTCStats { public let kind: String public let jitter: Double - public let packetsLost: Int - public let packetsReceived: Int - public let bytesReceived: Int - public let framesReceived: Int - public let frameWidth: Int - public let frameHeight: Int + public let packetsLost: UInt + public let packetsReceived: UInt + public let bytesReceived: UInt + public let framesReceived: UInt + public let frameWidth: UInt + public let frameHeight: UInt public let framesPerSecond: Double - public let framesDropped: Int + public let framesDropped: UInt public init( - kind: String = "", jitter: Double = 0.0, packetsLost: Int = 0, packetsReceived: Int = 0, bytesReceived: Int = 0, - framesReceived: Int = 0, frameWidth: Int = 0, frameHeight: Int = 0, framesPerSecond: Double = 0.0, - framesDropped: Int = 0 + kind: String = "", jitter: Double = 0.0, packetsLost: UInt = 0, packetsReceived: UInt = 0, + bytesReceived: UInt = 0, + framesReceived: UInt = 0, frameWidth: UInt = 0, frameHeight: UInt = 0, framesPerSecond: Double = 0.0, + framesDropped: UInt = 0 ) { self.kind = kind self.jitter = jitter