Skip to content
This repository has been archived by the owner on May 10, 2024. It is now read-only.

Commit

Permalink
[MV-410] Add getStats function (#39)
Browse files Browse the repository at this point in the history
  • Loading branch information
skyman503 authored Apr 27, 2023
1 parent 7719f5c commit 1f88e81
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import org.membraneframework.rtc.events.OfferData
import org.membraneframework.rtc.media.*
import org.membraneframework.rtc.models.EncodingReason
import org.membraneframework.rtc.models.Peer
import org.membraneframework.rtc.models.RTCStats
import org.membraneframework.rtc.models.TrackContext
import org.membraneframework.rtc.models.VadStatus
import org.membraneframework.rtc.transport.EventTransportError
Expand Down Expand Up @@ -491,4 +492,8 @@ constructor(

listener.onTrackReady(trackContext)
}

fun getStats(): Map<String, RTCStats> {
return peerConnectionManager.getStats()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import android.content.Intent
import kotlinx.coroutines.Dispatchers
import org.membraneframework.rtc.dagger.DaggerMembraneRTCComponent
import org.membraneframework.rtc.media.*
import org.membraneframework.rtc.models.RTCStats
import org.membraneframework.rtc.utils.Metadata
import org.webrtc.Logging

Expand Down Expand Up @@ -206,6 +207,14 @@ private constructor(
Logging.enableLogToDebugOutput(severity)
}

/**
* Returns current connection stats
* @return a map containing statistics
*/
fun getStats(): Map<String, RTCStats> {
return client.getStats()
}

companion object {
/**
* Creates an instance of <strong>MembraneRTC</strong> client and starts the connecting process.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,14 @@ import org.membraneframework.rtc.media.LocalScreencastTrack
import org.membraneframework.rtc.media.LocalTrack
import org.membraneframework.rtc.media.LocalVideoTrack
import org.membraneframework.rtc.media.TrackBandwidthLimit
import org.membraneframework.rtc.models.QualityLimitationDurations
import org.membraneframework.rtc.models.RTCInboundStats
import org.membraneframework.rtc.models.RTCOutboundStats
import org.membraneframework.rtc.models.RTCStats
import org.membraneframework.rtc.utils.*
import org.webrtc.*
import timber.log.Timber
import java.math.BigInteger
import java.util.*
import kotlin.math.pow

Expand All @@ -35,6 +40,7 @@ internal class PeerConnectionManager

private var peerConnection: PeerConnection? = null
private val peerConnectionMutex = Mutex()
private val peerConnectionStats = mutableMapOf<String, RTCStats>()

private var iceServers: List<PeerConnection.IceServer>? = null
private var config: PeerConnection.RTCConfiguration? = null
Expand Down Expand Up @@ -466,6 +472,55 @@ internal class PeerConnectionManager
override fun onRenegotiationNeeded() {
Timber.d("Renegotiation needed")
}

fun getStats(): Map<String, RTCStats> {
peerConnection?.getStats { rtcStatsReport -> extractRelevantStats(rtcStatsReport) }
return peerConnectionStats.toMap()
}

private fun extractRelevantStats(rp: RTCStatsReport) {
rp.statsMap.values.forEach {
if (it.type == "outbound-rtp") {
val durations = it.members["qualityLimitationDurations"] as? Map<*, *>
val qualityLimitation = QualityLimitationDurations(
durations?.get("bandwidth") as? Double ?: 0.0,
durations?.get("cpu") as? Double ?: 0.0,
durations?.get("none") as? Double ?: 0.0,
durations?.get("other") as? Double ?: 0.0
)

val tmp = RTCOutboundStats(
it.members["kind"] as? String,
it.members["rid"] as? String,
it.members["bytesSent"] as? BigInteger,
it.members["targetBitrate"] as? Double,
it.members["packetsSent"] as? Long,
it.members["framesEncoded"] as? Long,
it.members["framesPerSecond"] as? Double,
it.members["frameWidth"] as? Long,
it.members["frameHeight"] as? Long,
qualityLimitation
)

peerConnectionStats[it.id as String] = tmp
} else if (it.type == "inbound-rtp") {
val tmp = RTCInboundStats(
it.members["kind"] as? String,
it.members["jitter"] as? Double,
it.members["packetsLost"] as? Int,
it.members["packetsReceived"] as? Long,
it.members["bytesReceived"] as? BigInteger,
it.members["framesReceived"] as? Int,
it.members["frameWidth"] as? Long,
it.members["frameHeight"] as? Long,
it.members["framesPerSecond"] as? Double,
it.members["framesDropped"] as? Long
)

peerConnectionStats[it.id as String] = tmp
}
}
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package org.membraneframework.rtc.models

import java.math.BigInteger

data class QualityLimitationDurations(
val bandwidth: Double,
val cpu: Double,
val none: Double,
val other: Double
)

open class RTCStats

data class RTCOutboundStats(
val kind: String? = "",
val rid: String? = "",
val bytesSent: BigInteger? = BigInteger("0"),
val targetBitrate: Double? = 0.0,
val packetsSent: Long? = 0,
val framesEncoded: Long? = 0,
val framesPerSecond: Double? = 0.0,
val frameWidth: Long? = 0,
val frameHeight: Long? = 0,
val qualityLimitationDurations: QualityLimitationDurations?
) : RTCStats()

data class RTCInboundStats(
val kind: String? = "",
val jitter: Double? = 0.0,
val packetsLost: Int? = 0,
val packetsReceived: Long? = 0,
val bytesReceived: BigInteger? = BigInteger("0"),
val framesReceived: Int? = 0,
val frameWidth: Long? = 0,
val frameHeight: Long? = 0,
val framesPerSecond: Double? = 0.0,
val framesDropped: Long? = 0
) : RTCStats()

0 comments on commit 1f88e81

Please sign in to comment.