Source File
stats.go
Belonging Package
github.com/pion/webrtc/v4
// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>// SPDX-License-Identifier: MITpackage webrtcimport ()// A Stats object contains a set of statistics copies out of a monitored component// of the WebRTC stack at a specific time.type Stats interface {statsMarker()}// UnmarshalStatsJSON unmarshals a Stats object from JSON.func ( []byte) (Stats, error) { //nolint:cycloptype struct {StatsType `json:"type"`}:= {}:= json.Unmarshal(, &)if != nil {return nil, fmt.Errorf("unmarshal json type: %w", )}switch . {case StatsTypeCodec:return unmarshalCodecStats()case StatsTypeInboundRTP:return unmarshalInboundRTPStreamStats()case StatsTypeOutboundRTP:return unmarshalOutboundRTPStreamStats()case StatsTypeRemoteInboundRTP:return unmarshalRemoteInboundRTPStreamStats()case StatsTypeRemoteOutboundRTP:return unmarshalRemoteOutboundRTPStreamStats()case StatsTypeCSRC:return unmarshalCSRCStats()case StatsTypeMediaSource:return unmarshalMediaSourceStats()case StatsTypeMediaPlayout:return unmarshalMediaPlayoutStats()case StatsTypePeerConnection:return unmarshalPeerConnectionStats()case StatsTypeDataChannel:return unmarshalDataChannelStats()case StatsTypeStream:return unmarshalStreamStats()case StatsTypeTrack:return unmarshalTrackStats()case StatsTypeSender:return unmarshalSenderStats()case StatsTypeReceiver:return unmarshalReceiverStats()case StatsTypeTransport:return unmarshalTransportStats()case StatsTypeCandidatePair:return unmarshalICECandidatePairStats()case StatsTypeLocalCandidate, StatsTypeRemoteCandidate:return unmarshalICECandidateStats()case StatsTypeCertificate:return unmarshalCertificateStats()case StatsTypeSCTPTransport:return unmarshalSCTPTransportStats()default:return nil, fmt.Errorf("type: %w", ErrUnknownType)}}// StatsType indicates the type of the object that a Stats object represents.type StatsType stringconst (// StatsTypeCodec is used by CodecStats.StatsTypeCodec StatsType = "codec"// StatsTypeInboundRTP is used by InboundRTPStreamStats.StatsTypeInboundRTP StatsType = "inbound-rtp"// StatsTypeOutboundRTP is used by OutboundRTPStreamStats.StatsTypeOutboundRTP StatsType = "outbound-rtp"// StatsTypeRemoteInboundRTP is used by RemoteInboundRTPStreamStats.StatsTypeRemoteInboundRTP StatsType = "remote-inbound-rtp"// StatsTypeRemoteOutboundRTP is used by RemoteOutboundRTPStreamStats.StatsTypeRemoteOutboundRTP StatsType = "remote-outbound-rtp"// StatsTypeCSRC is used by RTPContributingSourceStats.StatsTypeCSRC StatsType = "csrc"// StatsTypeMediaSource is used by AudioSourceStats or VideoSourceStats depending on kind.StatsTypeMediaSource = "media-source"// StatsTypeMediaPlayout is used by AudioPlayoutStats.StatsTypeMediaPlayout StatsType = "media-playout"// StatsTypePeerConnection used by PeerConnectionStats.StatsTypePeerConnection StatsType = "peer-connection"// StatsTypeDataChannel is used by DataChannelStats.StatsTypeDataChannel StatsType = "data-channel"// StatsTypeStream is used by MediaStreamStats.StatsTypeStream StatsType = "stream"// StatsTypeTrack is used by SenderVideoTrackAttachmentStats and SenderAudioTrackAttachmentStats depending on kind.StatsTypeTrack StatsType = "track"// StatsTypeSender is used by the AudioSenderStats or VideoSenderStats depending on kind.StatsTypeSender StatsType = "sender"// StatsTypeReceiver is used by the AudioReceiverStats or VideoReceiverStats depending on kind.StatsTypeReceiver StatsType = "receiver"// StatsTypeTransport is used by TransportStats.StatsTypeTransport StatsType = "transport"// StatsTypeCandidatePair is used by ICECandidatePairStats.StatsTypeCandidatePair StatsType = "candidate-pair"// StatsTypeLocalCandidate is used by ICECandidateStats for the local candidate.StatsTypeLocalCandidate StatsType = "local-candidate"// StatsTypeRemoteCandidate is used by ICECandidateStats for the remote candidate.StatsTypeRemoteCandidate StatsType = "remote-candidate"// StatsTypeCertificate is used by CertificateStats.StatsTypeCertificate StatsType = "certificate"// StatsTypeSCTPTransport is used by SCTPTransportStats.StatsTypeSCTPTransport StatsType = "sctp-transport")// MediaKind indicates the kind of media (audio or video).type MediaKind stringconst (// MediaKindAudio indicates this is audio stats.MediaKindAudio MediaKind = "audio"// MediaKindVideo indicates this is video stats.MediaKindVideo MediaKind = "video")// StatsTimestamp is a timestamp represented by the floating point number of// milliseconds since the epoch.type StatsTimestamp float64// Time returns the time.Time represented by this timestamp.func ( StatsTimestamp) () time.Time {:= float64():= int64( * float64(time.Millisecond))return time.Unix(0, ).UTC()}func statsTimestampFrom( time.Time) StatsTimestamp {return StatsTimestamp(.UnixNano() / int64(time.Millisecond))}func statsTimestampNow() StatsTimestamp {return statsTimestampFrom(time.Now())}// StatsReport collects Stats objects indexed by their ID.type StatsReport map[string]Statstype statsReportCollector struct {collectingGroup sync.WaitGroupreport StatsReportmux sync.Mutex}func newStatsReportCollector() *statsReportCollector {return &statsReportCollector{report: make(StatsReport)}}func ( *statsReportCollector) () {.collectingGroup.Add(1)}func ( *statsReportCollector) ( string, Stats) {.mux.Lock()defer .mux.Unlock().report[] =.collectingGroup.Done()}func ( *statsReportCollector) () {.collectingGroup.Done()}func ( *statsReportCollector) () StatsReport {.collectingGroup.Wait().mux.Lock()defer .mux.Unlock()return .report}// CodecType specifies whether a CodecStats objects represents a media format// that is being encoded or decoded.type CodecType stringconst (// CodecTypeEncode means the attached CodecStats represents a media format that// is being encoded, or that the implementation is prepared to encode.CodecTypeEncode CodecType = "encode"// CodecTypeDecode means the attached CodecStats represents a media format// that the implementation is prepared to decode.CodecTypeDecode CodecType = "decode")// CodecStats contains statistics for a codec that is currently being used by RTP streams// being sent or received by this PeerConnection object.type CodecStats struct {// Timestamp is the timestamp associated with this object.Timestamp StatsTimestamp `json:"timestamp"`// Type is the object's StatsTypeType StatsType `json:"type"`// ID is a unique id that is associated with the component inspected to produce// this Stats object. Two Stats objects will have the same ID if they were produced// by inspecting the same underlying object.ID string `json:"id"`// PayloadType as used in RTP encoding or decodingPayloadType PayloadType `json:"payloadType"`// CodecType of this CodecStatsCodecType CodecType `json:"codecType"`// TransportID is the unique identifier of the transport on which this codec is// being used, which can be used to look up the corresponding TransportStats object.TransportID string `json:"transportId"`// MimeType is the codec MIME media type/subtype. e.g., video/vp8 or equivalent.MimeType string `json:"mimeType"`// ClockRate represents the media sampling rate.ClockRate uint32 `json:"clockRate"`// Channels is 2 for stereo, missing for most other cases.Channels uint8 `json:"channels"`// SDPFmtpLine is the a=fmtp line in the SDP corresponding to the codec,// i.e., after the colon following the PT.SDPFmtpLine string `json:"sdpFmtpLine"`// Implementation identifies the implementation used. This is useful for diagnosing// interoperability issues.Implementation string `json:"implementation"`}func ( CodecStats) () {}func unmarshalCodecStats( []byte) (CodecStats, error) {var CodecStats:= json.Unmarshal(, &)if != nil {return CodecStats{}, fmt.Errorf("unmarshal codec stats: %w", )}return , nil}// InboundRTPStreamStats contains statistics for an inbound RTP stream that is// currently received with this PeerConnection object.type InboundRTPStreamStats struct {// Mid represents a mid value of RTPTransceiver owning this stream, if that value is not// null. Otherwise, this member is not present.Mid string `json:"mid"`// Timestamp is the timestamp associated with this object.Timestamp StatsTimestamp `json:"timestamp"`// Type is the object's StatsTypeType StatsType `json:"type"`// ID is a unique id that is associated with the component inspected to produce// this Stats object. Two Stats objects will have the same ID if they were produced// by inspecting the same underlying object.ID string `json:"id"`// SSRC is the 32-bit unsigned integer value used to identify the source of the// stream of RTP packets that this stats object concerns.SSRC SSRC `json:"ssrc"`// Kind is either "audio" or "video"Kind string `json:"kind"`// It is a unique identifier that is associated to the object that was inspected// to produce the TransportStats associated with this RTP stream.TransportID string `json:"transportId"`// CodecID is a unique identifier that is associated to the object that was inspected// to produce the CodecStats associated with this RTP stream.CodecID string `json:"codecId"`// FIRCount counts the total number of Full Intra Request (FIR) packets received// by the sender. This metric is only valid for video and is sent by receiver.FIRCount uint32 `json:"firCount"`// PLICount counts the total number of Picture Loss Indication (PLI) packets// received by the sender. This metric is only valid for video and is sent by receiver.PLICount uint32 `json:"pliCount"`// TotalProcessingDelay is the sum of the time, in seconds, each audio sample or video frame// takes from the time the first RTP packet is received (reception timestamp) and to the time// the corresponding sample or frame is decoded (decoded timestamp). At this point the audio// sample or video frame is ready for playout by the MediaStreamTrack. Typically ready for// playout here means after the audio sample or video frame is fully decoded by the decoder.TotalProcessingDelay float64 `json:"totalProcessingDelay"`// NACKCount counts the total number of Negative ACKnowledgement (NACK) packets// received by the sender and is sent by receiver.NACKCount uint32 `json:"nackCount"`// JitterBufferDelay is the sum of the time, in seconds, each audio sample or a video frame// takes from the time the first packet is received by the jitter buffer (ingest timestamp)// to the time it exits the jitter buffer (emit timestamp). The average jitter buffer delay// can be calculated by dividing the JitterBufferDelay with the JitterBufferEmittedCount.JitterBufferDelay float64 `json:"jitterBufferDelay"`// JitterBufferTargetDelay is increased by the target jitter buffer delay every time a sample is emitted// by the jitter buffer. The added target is the target delay, in seconds, at the time that// the sample was emitted from the jitter buffer. To get the average target delay,// divide by JitterBufferEmittedCountJitterBufferTargetDelay float64 `json:"jitterBufferTargetDelay"`// JitterBufferEmittedCount is the total number of audio samples or video frames that// have come out of the jitter buffer (increasing jitterBufferDelay).JitterBufferEmittedCount uint64 `json:"jitterBufferEmittedCount"`// JitterBufferMinimumDelay works the same way as jitterBufferTargetDelay, except that// it is not affected by external mechanisms that increase the jitter buffer target delay,// such as jitterBufferTarget, AV sync, or any other mechanisms. This metric is purely// based on the network characteristics such as jitter and packet loss, and can be seen// as the minimum obtainable jitter buffer delay if no external factors would affect it.// The metric is updated every time JitterBufferEmittedCount is updated.JitterBufferMinimumDelay float64 `json:"jitterBufferMinimumDelay"`// TotalSamplesReceived is the total number of samples that have been received on// this RTP stream. This includes concealedSamples. Does not exist for video.TotalSamplesReceived uint64 `json:"totalSamplesReceived"`// ConcealedSamples is the total number of samples that are concealed samples.// A concealed sample is a sample that was replaced with synthesized samples generated// locally before being played out. Examples of samples that have to be concealed are// samples from lost packets (reported in packetsLost) or samples from packets that// arrive too late to be played out (reported in packetsDiscarded). Does not exist for video.ConcealedSamples uint64 `json:"concealedSamples"`// SilentConcealedSamples is the total number of concealed samples inserted that// are "silent". Playing out silent samples results in silence or comfort noise.// This is a subset of concealedSamples. Does not exist for video.SilentConcealedSamples uint64 `json:"silentConcealedSamples"`// ConcealmentEvents increases every time a concealed sample is synthesized after// a non-concealed sample. That is, multiple consecutive concealed samples will increase// the concealedSamples count multiple times but is a single concealment event.// Does not exist for video.ConcealmentEvents uint64 `json:"concealmentEvents"`// InsertedSamplesForDeceleration is increased by the difference between the number of// samples received and the number of samples played out when playout is slowed down.// If playout is slowed down by inserting samples, this will be the number of inserted samples.// Does not exist for video.InsertedSamplesForDeceleration uint64 `json:"insertedSamplesForDeceleration"`// RemovedSamplesForAcceleration is increased by the difference between the number of// samples received and the number of samples played out when playout is sped up. If speedup// is achieved by removing samples, this will be the count of samples removed.// Does not exist for video.RemovedSamplesForAcceleration uint64 `json:"removedSamplesForAcceleration"`// AudioLevel represents the audio level of the receiving track..//// The value is a value between 0..1 (linear), where 1.0 represents 0 dBov,// 0 represents silence, and 0.5 represents approximately 6 dBSPL change in// the sound pressure level from 0 dBov. Does not exist for video.AudioLevel float64 `json:"audioLevel"`// TotalAudioEnergy represents the audio energy of the receiving track. It is calculated// by duration * Math.pow(energy/maxEnergy, 2) for each audio sample received (and thus// counted by TotalSamplesReceived). Does not exist for video.TotalAudioEnergy float64 `json:"totalAudioEnergy"`// TotalSamplesDuration represents the total duration in seconds of all samples that have been// received (and thus counted by TotalSamplesReceived). Can be used with totalAudioEnergy to// compute an average audio level over different intervals. Does not exist for video.TotalSamplesDuration float64 `json:"totalSamplesDuration"`// SLICount counts the total number of Slice Loss Indication (SLI) packets received// by the sender. This metric is only valid for video and is sent by receiver.SLICount uint32 `json:"sliCount"`// QPSum is the sum of the QP values of frames passed. The count of frames is// in FramesDecoded for inbound stream stats, and in FramesEncoded for outbound stream stats.QPSum uint64 `json:"qpSum"`// TotalDecodeTime is the total number of seconds that have been spent decoding the FramesDecoded// frames of this stream. The average decode time can be calculated by dividing this value// with FramesDecoded. The time it takes to decode one frame is the time passed between// feeding the decoder a frame and the decoder returning decoded data for that frame.TotalDecodeTime float64 `json:"totalDecodeTime"`// TotalInterFrameDelay is the sum of the interframe delays in seconds between consecutively// rendered frames, recorded just after a frame has been rendered. The interframe delay variance// be calculated from TotalInterFrameDelay, TotalSquaredInterFrameDelay, and FramesRendered according// to the formula: (TotalSquaredInterFrameDelay - TotalInterFrameDelay^2 / FramesRendered) / FramesRendered.// Does not exist for audio.TotalInterFrameDelay float64 `json:"totalInterFrameDelay"`// TotalSquaredInterFrameDelay is the sum of the squared interframe delays in seconds// between consecutively rendered frames, recorded just after a frame has been rendered.// See TotalInterFrameDelay for details on how to calculate the interframe delay variance.// Does not exist for audio.TotalSquaredInterFrameDelay float64 `json:"totalSquaredInterFrameDelay"`// PacketsReceived is the total number of RTP packets received for this SSRC.PacketsReceived uint32 `json:"packetsReceived"`// PacketsLost is the total number of RTP packets lost for this SSRC. Note that// because of how this is estimated, it can be negative if more packets are received than sent.PacketsLost int32 `json:"packetsLost"`// Jitter is the packet jitter measured in seconds for this SSRCJitter float64 `json:"jitter"`// PacketsDiscarded is the cumulative number of RTP packets discarded by the jitter// buffer due to late or early-arrival, i.e., these packets are not played out.// RTP packets discarded due to packet duplication are not reported in this metric.PacketsDiscarded uint32 `json:"packetsDiscarded"`// PacketsRepaired is the cumulative number of lost RTP packets repaired after applying// an error-resilience mechanism. It is measured for the primary source RTP packets// and only counted for RTP packets that have no further chance of repair.PacketsRepaired uint32 `json:"packetsRepaired"`// BurstPacketsLost is the cumulative number of RTP packets lost during loss bursts.BurstPacketsLost uint32 `json:"burstPacketsLost"`// BurstPacketsDiscarded is the cumulative number of RTP packets discarded during discard bursts.BurstPacketsDiscarded uint32 `json:"burstPacketsDiscarded"`// BurstLossCount is the cumulative number of bursts of lost RTP packets.BurstLossCount uint32 `json:"burstLossCount"`// BurstDiscardCount is the cumulative number of bursts of discarded RTP packets.BurstDiscardCount uint32 `json:"burstDiscardCount"`// BurstLossRate is the fraction of RTP packets lost during bursts to the// total number of RTP packets expected in the bursts.BurstLossRate float64 `json:"burstLossRate"`// BurstDiscardRate is the fraction of RTP packets discarded during bursts to// the total number of RTP packets expected in bursts.BurstDiscardRate float64 `json:"burstDiscardRate"`// GapLossRate is the fraction of RTP packets lost during the gap periods.GapLossRate float64 `json:"gapLossRate"`// GapDiscardRate is the fraction of RTP packets discarded during the gap periods.GapDiscardRate float64 `json:"gapDiscardRate"`// TrackID is the identifier of the stats object representing the receiving track,// a ReceiverAudioTrackAttachmentStats or ReceiverVideoTrackAttachmentStats.TrackID string `json:"trackId"`// ReceiverID is the stats ID used to look up the AudioReceiverStats or VideoReceiverStats// object receiving this stream.ReceiverID string `json:"receiverId"`// RemoteID is used for looking up the remote RemoteOutboundRTPStreamStats object// for the same SSRC.RemoteID string `json:"remoteId"`// FramesDecoded represents the total number of frames correctly decoded for this SSRC,// i.e., frames that would be displayed if no frames are dropped. Only valid for video.FramesDecoded uint32 `json:"framesDecoded"`// KeyFramesDecoded represents the total number of key frames, such as key frames in// VP8 [RFC6386] or IDR-frames in H.264 [RFC6184], successfully decoded for this RTP// media stream. This is a subset of FramesDecoded. FramesDecoded - KeyFramesDecoded// gives you the number of delta frames decoded. Does not exist for audio.KeyFramesDecoded uint32 `json:"keyFramesDecoded"`// FramesRendered represents the total number of frames that have been rendered.// It is incremented just after a frame has been rendered. Does not exist for audio.FramesRendered uint32 `json:"framesRendered"`// FramesDropped is the total number of frames dropped prior to decode or dropped// because the frame missed its display deadline for this receiver's track.// The measurement begins when the receiver is created and is a cumulative metric// as defined in Appendix A (g) of [RFC7004]. Does not exist for audio.FramesDropped uint32 `json:"framesDropped"`// FrameWidth represents the width of the last decoded frame. Before the first// frame is decoded this member does not exist. Does not exist for audio.FrameWidth uint32 `json:"frameWidth"`// FrameHeight represents the height of the last decoded frame. Before the first// frame is decoded this member does not exist. Does not exist for audio.FrameHeight uint32 `json:"frameHeight"`// LastPacketReceivedTimestamp represents the timestamp at which the last packet was// received for this SSRC. This differs from Timestamp, which represents the time// at which the statistics were generated by the local endpoint.LastPacketReceivedTimestamp StatsTimestamp `json:"lastPacketReceivedTimestamp"`// HeaderBytesReceived is the total number of RTP header and padding bytes received for this SSRC.// This includes retransmissions. This does not include the size of transport layer headers such// as IP or UDP. headerBytesReceived + bytesReceived equals the number of bytes received as// payload over the transport.HeaderBytesReceived uint64 `json:"headerBytesReceived"`// AverageRTCPInterval is the average RTCP interval between two consecutive compound RTCP packets.// This is calculated by the sending endpoint when sending compound RTCP reports.// Compound packets must contain at least a RTCP RR or SR packet and an SDES packet// with the CNAME item.AverageRTCPInterval float64 `json:"averageRtcpInterval"`// FECPacketsReceived is the total number of RTP FEC packets received for this SSRC.// This counter can also be incremented when receiving FEC packets in-band with media packets (e.g., with Opus).FECPacketsReceived uint32 `json:"fecPacketsReceived"`// FECPacketsDiscarded is the total number of RTP FEC packets received for this SSRC where the// error correction payload was discarded by the application. This may happen// 1. if all the source packets protected by the FEC packet were received or already// recovered by a separate FEC packet, or// 2. if the FEC packet arrived late, i.e., outside the recovery window, and the// lost RTP packets have already been skipped during playout.// This is a subset of FECPacketsReceived.FECPacketsDiscarded uint64 `json:"fecPacketsDiscarded"`// BytesReceived is the total number of bytes received for this SSRC.BytesReceived uint64 `json:"bytesReceived"`// FramesReceived represents the total number of complete frames received on this RTP stream.// This metric is incremented when the complete frame is received. Does not exist for audio.FramesReceived uint32 `json:"framesReceived"`// PacketsFailedDecryption is the cumulative number of RTP packets that failed// to be decrypted. These packets are not counted by PacketsDiscarded.PacketsFailedDecryption uint32 `json:"packetsFailedDecryption"`// PacketsDuplicated is the cumulative number of packets discarded because they// are duplicated. Duplicate packets are not counted in PacketsDiscarded.//// Duplicated packets have the same RTP sequence number and content as a previously// received packet. If multiple duplicates of a packet are received, all of them are counted.// An improved estimate of lost packets can be calculated by adding PacketsDuplicated to PacketsLost.PacketsDuplicated uint32 `json:"packetsDuplicated"`// PerDSCPPacketsReceived is the total number of packets received for this SSRC,// per Differentiated Services code point (DSCP) [RFC2474]. DSCPs are identified// as decimal integers in string form. Note that due to network remapping and bleaching,// these numbers are not expected to match the numbers seen on sending. Not all// OSes make this information available.PerDSCPPacketsReceived map[string]uint32 `json:"perDscpPacketsReceived"`// Identifies the decoder implementation used. This is useful for diagnosing interoperability issues.// Does not exist for audio.DecoderImplementation string `json:"decoderImplementation"`// PauseCount is the total number of video pauses experienced by this receiver.// Video is considered to be paused if time passed since last rendered frame exceeds 5 seconds.// PauseCount is incremented when a frame is rendered after such a pause. Does not exist for audio.PauseCount uint32 `json:"pauseCount"`// TotalPausesDuration is the total duration of pauses (for definition of pause see PauseCount), in seconds.// Does not exist for audio.TotalPausesDuration float64 `json:"totalPausesDuration"`// FreezeCount is the total number of video freezes experienced by this receiver.// It is a freeze if frame duration, which is time interval between two consecutively rendered frames,// is equal or exceeds Max(3 * avg_frame_duration_ms, avg_frame_duration_ms + 150),// where avg_frame_duration_ms is linear average of durations of last 30 rendered frames.// Does not exist for audio.FreezeCount uint32 `json:"freezeCount"`// TotalFreezesDuration is the total duration of rendered frames which are considered as frozen// (for definition of freeze see freezeCount), in seconds. Does not exist for audio.TotalFreezesDuration float64 `json:"totalFreezesDuration"`// PowerEfficientDecoder indicates whether the decoder currently used is considered power efficient// by the user agent. Does not exist for audio.PowerEfficientDecoder bool `json:"powerEfficientDecoder"`}func ( InboundRTPStreamStats) () {}func unmarshalInboundRTPStreamStats( []byte) (InboundRTPStreamStats, error) {var InboundRTPStreamStats:= json.Unmarshal(, &)if != nil {return InboundRTPStreamStats{}, fmt.Errorf("unmarshal inbound rtp stream stats: %w", )}return , nil}// QualityLimitationReason lists the reason for limiting the resolution and/or framerate.// Only valid for video.type QualityLimitationReason stringconst (// QualityLimitationReasonNone means the resolution and/or framerate is not limited.QualityLimitationReasonNone QualityLimitationReason = "none"// QualityLimitationReasonCPU means the resolution and/or framerate is primarily limited due to CPU load.QualityLimitationReasonCPU QualityLimitationReason = "cpu"// QualityLimitationReasonBandwidth means the resolution and/or framerate is primarily limited// due to congestion cues during bandwidth estimation.// Typical, congestion control algorithms use inter-arrival time, round-trip time,// packet or other congestion cues to perform bandwidth estimation.QualityLimitationReasonBandwidth QualityLimitationReason = "bandwidth"// QualityLimitationReasonOther means the resolution and/or framerate is primarily limited// for a reason other than the above.QualityLimitationReasonOther QualityLimitationReason = "other")// OutboundRTPStreamStats contains statistics for an outbound RTP stream that is// currently sent with this PeerConnection object.type OutboundRTPStreamStats struct {// Mid represents a mid value of RTPTransceiver owning this stream, if that value is not// null. Otherwise, this member is not present.Mid string `json:"mid"`// Rid only exists if a rid has been set for this RTP stream.// Must not exist for audio.Rid string `json:"rid"`// MediaSourceID is the identifier of the stats object representing the track currently// attached to the sender of this stream, an RTCMediaSourceStats.MediaSourceID string `json:"mediaSourceId"`// Timestamp is the timestamp associated with this object.Timestamp StatsTimestamp `json:"timestamp"`// Type is the object's StatsTypeType StatsType `json:"type"`// ID is a unique id that is associated with the component inspected to produce// this Stats object. Two Stats objects will have the same ID if they were produced// by inspecting the same underlying object.ID string `json:"id"`// SSRC is the 32-bit unsigned integer value used to identify the source of the// stream of RTP packets that this stats object concerns.SSRC SSRC `json:"ssrc"`// Kind is either "audio" or "video"Kind string `json:"kind"`// It is a unique identifier that is associated to the object that was inspected// to produce the TransportStats associated with this RTP stream.TransportID string `json:"transportId"`// CodecID is a unique identifier that is associated to the object that was inspected// to produce the CodecStats associated with this RTP stream.CodecID string `json:"codecId"`// HeaderBytesSent is the total number of RTP header and padding bytes sent for this SSRC. This does not// include the size of transport layer headers such as IP or UDP.// HeaderBytesSent + BytesSent equals the number of bytes sent as payload over the transport.HeaderBytesSent uint64 `json:"headerBytesSent"`// RetransmittedPacketsSent is the total number of packets that were retransmitted for this SSRC.// This is a subset of packetsSent. If RTX is not negotiated, retransmitted packets are sent// over this ssrc. If RTX was negotiated, retransmitted packets are sent over a separate SSRC// but is still accounted for here.RetransmittedPacketsSent uint64 `json:"retransmittedPacketsSent"`// RetransmittedBytesSent is the total number of bytes that were retransmitted for this SSRC,// only including payload bytes. This is a subset of bytesSent. If RTX is not negotiated,// retransmitted bytes are sent over this ssrc. If RTX was negotiated, retransmitted bytes// are sent over a separate SSRC but is still accounted for here.RetransmittedBytesSent uint64 `json:"retransmittedBytesSent"`// FIRCount counts the total number of Full Intra Request (FIR) packets received// by the sender. This metric is only valid for video and is sent by receiver.FIRCount uint32 `json:"firCount"`// PLICount counts the total number of Picture Loss Indication (PLI) packets// received by the sender. This metric is only valid for video and is sent by receiver.PLICount uint32 `json:"pliCount"`// NACKCount counts the total number of Negative ACKnowledgement (NACK) packets// received by the sender and is sent by receiver.NACKCount uint32 `json:"nackCount"`// SLICount counts the total number of Slice Loss Indication (SLI) packets received// by the sender. This metric is only valid for video and is sent by receiver.SLICount uint32 `json:"sliCount"`// QPSum is the sum of the QP values of frames passed. The count of frames is// in FramesDecoded for inbound stream stats, and in FramesEncoded for outbound stream stats.QPSum uint64 `json:"qpSum"`// PacketsSent is the total number of RTP packets sent for this SSRC.PacketsSent uint32 `json:"packetsSent"`// PacketsDiscardedOnSend is the total number of RTP packets for this SSRC that// have been discarded due to socket errors, i.e. a socket error occurred when handing// the packets to the socket. This might happen due to various reasons, including// full buffer or no available memory.PacketsDiscardedOnSend uint32 `json:"packetsDiscardedOnSend"`// FECPacketsSent is the total number of RTP FEC packets sent for this SSRC.// This counter can also be incremented when sending FEC packets in-band with// media packets (e.g., with Opus).FECPacketsSent uint32 `json:"fecPacketsSent"`// BytesSent is the total number of bytes sent for this SSRC.BytesSent uint64 `json:"bytesSent"`// BytesDiscardedOnSend is the total number of bytes for this SSRC that have// been discarded due to socket errors, i.e. a socket error occurred when handing// the packets containing the bytes to the socket. This might happen due to various// reasons, including full buffer or no available memory.BytesDiscardedOnSend uint64 `json:"bytesDiscardedOnSend"`// TrackID is the identifier of the stats object representing the current track// attachment to the sender of this stream, a SenderAudioTrackAttachmentStats// or SenderVideoTrackAttachmentStats.TrackID string `json:"trackId"`// SenderID is the stats ID used to look up the AudioSenderStats or VideoSenderStats// object sending this stream.SenderID string `json:"senderId"`// RemoteID is used for looking up the remote RemoteInboundRTPStreamStats object// for the same SSRC.RemoteID string `json:"remoteId"`// LastPacketSentTimestamp represents the timestamp at which the last packet was// sent for this SSRC. This differs from timestamp, which represents the time at// which the statistics were generated by the local endpoint.LastPacketSentTimestamp StatsTimestamp `json:"lastPacketSentTimestamp"`// TargetBitrate is the current target bitrate configured for this particular SSRC// and is the Transport Independent Application Specific (TIAS) bitrate [RFC3890].// Typically, the target bitrate is a configuration parameter provided to the codec's// encoder and does not count the size of the IP or other transport layers like TCP or UDP.// It is measured in bits per second and the bitrate is calculated over a 1 second window.TargetBitrate float64 `json:"targetBitrate"`// TotalEncodedBytesTarget is increased by the target frame size in bytes every time// a frame has been encoded. The actual frame size may be bigger or smaller than this number.// This value goes up every time framesEncoded goes up.TotalEncodedBytesTarget uint64 `json:"totalEncodedBytesTarget"`// FrameWidth represents the width of the last encoded frame. The resolution of the// encoded frame may be lower than the media source. Before the first frame is encoded// this member does not exist. Does not exist for audio.FrameWidth uint32 `json:"frameWidth"`// FrameHeight represents the height of the last encoded frame. The resolution of the// encoded frame may be lower than the media source. Before the first frame is encoded// this member does not exist. Does not exist for audio.FrameHeight uint32 `json:"frameHeight"`// FramesPerSecond is the number of encoded frames during the last second. This may be// lower than the media source frame rate. Does not exist for audio.FramesPerSecond float64 `json:"framesPerSecond"`// FramesSent represents the total number of frames sent on this RTP stream. Does not exist for audio.FramesSent uint32 `json:"framesSent"`// HugeFramesSent represents the total number of huge frames sent by this RTP stream.// Huge frames, by definition, are frames that have an encoded size at least 2.5 times// the average size of the frames. The average size of the frames is defined as the// target bitrate per second divided by the target FPS at the time the frame was encoded.// These are usually complex to encode frames with a lot of changes in the picture.// This can be used to estimate, e.g slide changes in the streamed presentation.// Does not exist for audio.HugeFramesSent uint32 `json:"hugeFramesSent"`// FramesEncoded represents the total number of frames successfully encoded for this RTP media stream.// Only valid for video.FramesEncoded uint32 `json:"framesEncoded"`// KeyFramesEncoded represents the total number of key frames, such as key frames in VP8 [RFC6386] or// IDR-frames in H.264 [RFC6184], successfully encoded for this RTP media stream. This is a subset of// FramesEncoded. FramesEncoded - KeyFramesEncoded gives you the number of delta frames encoded.// Does not exist for audio.KeyFramesEncoded uint32 `json:"keyFramesEncoded"`// TotalEncodeTime is the total number of seconds that has been spent encoding the// framesEncoded frames of this stream. The average encode time can be calculated by// dividing this value with FramesEncoded. The time it takes to encode one frame is the// time passed between feeding the encoder a frame and the encoder returning encoded data// for that frame. This does not include any additional time it may take to packetize the resulting data.TotalEncodeTime float64 `json:"totalEncodeTime"`// TotalPacketSendDelay is the total number of seconds that packets have spent buffered// locally before being transmitted onto the network. The time is measured from when// a packet is emitted from the RTP packetizer until it is handed over to the OS network socket.// This measurement is added to totalPacketSendDelay when packetsSent is incremented.TotalPacketSendDelay float64 `json:"totalPacketSendDelay"`// AverageRTCPInterval is the average RTCP interval between two consecutive compound RTCP// packets. This is calculated by the sending endpoint when sending compound RTCP reports.// Compound packets must contain at least a RTCP RR or SR packet and an SDES packet with the CNAME item.AverageRTCPInterval float64 `json:"averageRtcpInterval"`// QualityLimitationReason is the current reason for limiting the resolution and/or framerate,// or "none" if not limited. Only valid for video.QualityLimitationReason QualityLimitationReason `json:"qualityLimitationReason"`// QualityLimitationDurations is record of the total time, in seconds, that this// stream has spent in each quality limitation state. The record includes a mapping// for all QualityLimitationReason types, including "none". Only valid for video.QualityLimitationDurations map[string]float64 `json:"qualityLimitationDurations"`// QualityLimitationResolutionChanges is the number of times that the resolution has changed// because we are quality limited (qualityLimitationReason has a value other than "none").// The counter is initially zero and increases when the resolution goes up or down.// For example, if a 720p track is sent as 480p for some time and then recovers to 720p,// qualityLimitationResolutionChanges will have the value 2. Does not exist for audio.QualityLimitationResolutionChanges uint32 `json:"qualityLimitationResolutionChanges"`// PerDSCPPacketsSent is the total number of packets sent for this SSRC, per DSCP.// DSCPs are identified as decimal integers in string form.PerDSCPPacketsSent map[string]uint32 `json:"perDscpPacketsSent"`// Active indicates whether this RTP stream is configured to be sent or disabled. Note that an// active stream can still not be sending, e.g. when being limited by network conditions.Active bool `json:"active"`// Identifies the encoder implementation used. This is useful for diagnosing interoperability issues.// Does not exist for audio.EncoderImplementation string `json:"encoderImplementation"`// PowerEfficientEncoder indicates whether the encoder currently used is considered power efficient.// by the user agent. Does not exist for audio.PowerEfficientEncoder bool `json:"powerEfficientEncoder"`// ScalabilityMode identifies the layering mode used for video encoding. Does not exist for audio.ScalabilityMode string `json:"scalabilityMode"`}func ( OutboundRTPStreamStats) () {}func unmarshalOutboundRTPStreamStats( []byte) (OutboundRTPStreamStats, error) {var OutboundRTPStreamStats:= json.Unmarshal(, &)if != nil {return OutboundRTPStreamStats{}, fmt.Errorf("unmarshal outbound rtp stream stats: %w", )}return , nil}// RemoteInboundRTPStreamStats contains statistics for the remote endpoint's inbound// RTP stream corresponding to an outbound stream that is currently sent with this// PeerConnection object. It is measured at the remote endpoint and reported in an RTCP// Receiver Report (RR) or RTCP Extended Report (XR).type RemoteInboundRTPStreamStats struct {// Timestamp is the timestamp associated with this object.Timestamp StatsTimestamp `json:"timestamp"`// Type is the object's StatsTypeType StatsType `json:"type"`// ID is a unique id that is associated with the component inspected to produce// this Stats object. Two Stats objects will have the same ID if they were produced// by inspecting the same underlying object.ID string `json:"id"`// SSRC is the 32-bit unsigned integer value used to identify the source of the// stream of RTP packets that this stats object concerns.SSRC SSRC `json:"ssrc"`// Kind is either "audio" or "video"Kind string `json:"kind"`// It is a unique identifier that is associated to the object that was inspected// to produce the TransportStats associated with this RTP stream.TransportID string `json:"transportId"`// CodecID is a unique identifier that is associated to the object that was inspected// to produce the CodecStats associated with this RTP stream.CodecID string `json:"codecId"`// FIRCount counts the total number of Full Intra Request (FIR) packets received// by the sender. This metric is only valid for video and is sent by receiver.FIRCount uint32 `json:"firCount"`// PLICount counts the total number of Picture Loss Indication (PLI) packets// received by the sender. This metric is only valid for video and is sent by receiver.PLICount uint32 `json:"pliCount"`// NACKCount counts the total number of Negative ACKnowledgement (NACK) packets// received by the sender and is sent by receiver.NACKCount uint32 `json:"nackCount"`// SLICount counts the total number of Slice Loss Indication (SLI) packets received// by the sender. This metric is only valid for video and is sent by receiver.SLICount uint32 `json:"sliCount"`// QPSum is the sum of the QP values of frames passed. The count of frames is// in FramesDecoded for inbound stream stats, and in FramesEncoded for outbound stream stats.QPSum uint64 `json:"qpSum"`// PacketsReceived is the total number of RTP packets received for this SSRC.PacketsReceived uint32 `json:"packetsReceived"`// PacketsLost is the total number of RTP packets lost for this SSRC. Note that// because of how this is estimated, it can be negative if more packets are received than sent.PacketsLost int32 `json:"packetsLost"`// Jitter is the packet jitter measured in seconds for this SSRCJitter float64 `json:"jitter"`// PacketsDiscarded is the cumulative number of RTP packets discarded by the jitter// buffer due to late or early-arrival, i.e., these packets are not played out.// RTP packets discarded due to packet duplication are not reported in this metric.PacketsDiscarded uint32 `json:"packetsDiscarded"`// PacketsRepaired is the cumulative number of lost RTP packets repaired after applying// an error-resilience mechanism. It is measured for the primary source RTP packets// and only counted for RTP packets that have no further chance of repair.PacketsRepaired uint32 `json:"packetsRepaired"`// BurstPacketsLost is the cumulative number of RTP packets lost during loss bursts.BurstPacketsLost uint32 `json:"burstPacketsLost"`// BurstPacketsDiscarded is the cumulative number of RTP packets discarded during discard bursts.BurstPacketsDiscarded uint32 `json:"burstPacketsDiscarded"`// BurstLossCount is the cumulative number of bursts of lost RTP packets.BurstLossCount uint32 `json:"burstLossCount"`// BurstDiscardCount is the cumulative number of bursts of discarded RTP packets.BurstDiscardCount uint32 `json:"burstDiscardCount"`// BurstLossRate is the fraction of RTP packets lost during bursts to the// total number of RTP packets expected in the bursts.BurstLossRate float64 `json:"burstLossRate"`// BurstDiscardRate is the fraction of RTP packets discarded during bursts to// the total number of RTP packets expected in bursts.BurstDiscardRate float64 `json:"burstDiscardRate"`// GapLossRate is the fraction of RTP packets lost during the gap periods.GapLossRate float64 `json:"gapLossRate"`// GapDiscardRate is the fraction of RTP packets discarded during the gap periods.GapDiscardRate float64 `json:"gapDiscardRate"`// LocalID is used for looking up the local OutboundRTPStreamStats object for the same SSRC.LocalID string `json:"localId"`// RoundTripTime is the estimated round trip time for this SSRC based on the// RTCP timestamps in the RTCP Receiver Report (RR) and measured in seconds.RoundTripTime float64 `json:"roundTripTime"`// TotalRoundTripTime represents the cumulative sum of all round trip time measurements// in seconds since the beginning of the session. The individual round trip time is calculated// based on the RTCP timestamps in the RTCP Receiver Report (RR) [RFC3550], hence requires// a DLSR value other than 0. The average round trip time can be computed from// TotalRoundTripTime by dividing it by RoundTripTimeMeasurements.TotalRoundTripTime float64 `json:"totalRoundTripTime"`// FractionLost is the fraction packet loss reported for this SSRC.FractionLost float64 `json:"fractionLost"`// RoundTripTimeMeasurements represents the total number of RTCP RR blocks received for this SSRC// that contain a valid round trip time. This counter will not increment if the RoundTripTime can// not be calculated because no RTCP Receiver Report with a DLSR value other than 0 has been received.RoundTripTimeMeasurements uint64 `json:"roundTripTimeMeasurements"`}func ( RemoteInboundRTPStreamStats) () {}func unmarshalRemoteInboundRTPStreamStats( []byte) (RemoteInboundRTPStreamStats, error) {var RemoteInboundRTPStreamStats:= json.Unmarshal(, &)if != nil {return RemoteInboundRTPStreamStats{}, fmt.Errorf("unmarshal remote inbound rtp stream stats: %w", )}return , nil}// RemoteOutboundRTPStreamStats contains statistics for the remote endpoint's outbound// RTP stream corresponding to an inbound stream that is currently received with this// PeerConnection object. It is measured at the remote endpoint and reported in an// RTCP Sender Report (SR).type RemoteOutboundRTPStreamStats struct {// Timestamp is the timestamp associated with this object.Timestamp StatsTimestamp `json:"timestamp"`// Type is the object's StatsTypeType StatsType `json:"type"`// ID is a unique id that is associated with the component inspected to produce// this Stats object. Two Stats objects will have the same ID if they were produced// by inspecting the same underlying object.ID string `json:"id"`// SSRC is the 32-bit unsigned integer value used to identify the source of the// stream of RTP packets that this stats object concerns.SSRC SSRC `json:"ssrc"`// Kind is either "audio" or "video"Kind string `json:"kind"`// It is a unique identifier that is associated to the object that was inspected// to produce the TransportStats associated with this RTP stream.TransportID string `json:"transportId"`// CodecID is a unique identifier that is associated to the object that was inspected// to produce the CodecStats associated with this RTP stream.CodecID string `json:"codecId"`// FIRCount counts the total number of Full Intra Request (FIR) packets received// by the sender. This metric is only valid for video and is sent by receiver.FIRCount uint32 `json:"firCount"`// PLICount counts the total number of Picture Loss Indication (PLI) packets// received by the sender. This metric is only valid for video and is sent by receiver.PLICount uint32 `json:"pliCount"`// NACKCount counts the total number of Negative ACKnowledgement (NACK) packets// received by the sender and is sent by receiver.NACKCount uint32 `json:"nackCount"`// SLICount counts the total number of Slice Loss Indication (SLI) packets received// by the sender. This metric is only valid for video and is sent by receiver.SLICount uint32 `json:"sliCount"`// QPSum is the sum of the QP values of frames passed. The count of frames is// in FramesDecoded for inbound stream stats, and in FramesEncoded for outbound stream stats.QPSum uint64 `json:"qpSum"`// PacketsSent is the total number of RTP packets sent for this SSRC.PacketsSent uint32 `json:"packetsSent"`// PacketsDiscardedOnSend is the total number of RTP packets for this SSRC that// have been discarded due to socket errors, i.e. a socket error occurred when handing// the packets to the socket. This might happen due to various reasons, including// full buffer or no available memory.PacketsDiscardedOnSend uint32 `json:"packetsDiscardedOnSend"`// FECPacketsSent is the total number of RTP FEC packets sent for this SSRC.// This counter can also be incremented when sending FEC packets in-band with// media packets (e.g., with Opus).FECPacketsSent uint32 `json:"fecPacketsSent"`// BytesSent is the total number of bytes sent for this SSRC.BytesSent uint64 `json:"bytesSent"`// BytesDiscardedOnSend is the total number of bytes for this SSRC that have// been discarded due to socket errors, i.e. a socket error occurred when handing// the packets containing the bytes to the socket. This might happen due to various// reasons, including full buffer or no available memory.BytesDiscardedOnSend uint64 `json:"bytesDiscardedOnSend"`// LocalID is used for looking up the local InboundRTPStreamStats object for the same SSRC.LocalID string `json:"localId"`// RemoteTimestamp represents the remote timestamp at which these statistics were// sent by the remote endpoint. This differs from timestamp, which represents the// time at which the statistics were generated or received by the local endpoint.// The RemoteTimestamp, if present, is derived from the NTP timestamp in an RTCP// Sender Report (SR) packet, which reflects the remote endpoint's clock.// That clock may not be synchronized with the local clock.RemoteTimestamp StatsTimestamp `json:"remoteTimestamp"`// ReportsSent represents the total number of RTCP Sender Report (SR) blocks sent for this SSRC.ReportsSent uint64 `json:"reportsSent"`// RoundTripTime is estimated round trip time for this SSRC based on the latest// RTCP Sender Report (SR) that contains a DLRR report block as defined in [RFC3611].// The Calculation of the round trip time is defined in section 4.5. of [RFC3611].// Does not exist if the latest SR does not contain the DLRR report block, or if the last RR timestamp// in the DLRR report block is zero, or if the delay since last RR value in the DLRR report block is zero.RoundTripTime float64 `json:"roundTripTime"`// TotalRoundTripTime represents the cumulative sum of all round trip time measurements in seconds// since the beginning of the session. The individual round trip time is calculated based on the DLRR// report block in the RTCP Sender Report (SR) [RFC3611]. This counter will not increment if the// RoundTripTime can not be calculated. The average round trip time can be computed from// TotalRoundTripTime by dividing it by RoundTripTimeMeasurements.TotalRoundTripTime float64 `json:"totalRoundTripTime"`// RoundTripTimeMeasurements represents the total number of RTCP Sender Report (SR) blocks// received for this SSRC that contain a DLRR report block that can derive a valid round trip time// according to [RFC3611]. This counter will not increment if the RoundTripTime can not be calculated.RoundTripTimeMeasurements uint64 `json:"roundTripTimeMeasurements"`}func ( RemoteOutboundRTPStreamStats) () {}func unmarshalRemoteOutboundRTPStreamStats( []byte) (RemoteOutboundRTPStreamStats, error) {var RemoteOutboundRTPStreamStats:= json.Unmarshal(, &)if != nil {return RemoteOutboundRTPStreamStats{}, fmt.Errorf("unmarshal remote outbound rtp stream stats: %w", )}return , nil}// RTPContributingSourceStats contains statistics for a contributing source (CSRC) that contributed// to an inbound RTP stream.type RTPContributingSourceStats struct {// Timestamp is the timestamp associated with this object.Timestamp StatsTimestamp `json:"timestamp"`// Type is the object's StatsTypeType StatsType `json:"type"`// ID is a unique id that is associated with the component inspected to produce// this Stats object. Two Stats objects will have the same ID if they were produced// by inspecting the same underlying object.ID string `json:"id"`// ContributorSSRC is the SSRC identifier of the contributing source represented// by this stats object. It is a 32-bit unsigned integer that appears in the CSRC// list of any packets the relevant source contributed to.ContributorSSRC SSRC `json:"contributorSsrc"`// InboundRTPStreamID is the ID of the InboundRTPStreamStats object representing// the inbound RTP stream that this contributing source is contributing to.InboundRTPStreamID string `json:"inboundRtpStreamId"`// PacketsContributedTo is the total number of RTP packets that this contributing// source contributed to. This value is incremented each time a packet is counted// by InboundRTPStreamStats.packetsReceived, and the packet's CSRC list contains// the SSRC identifier of this contributing source, ContributorSSRC.PacketsContributedTo uint32 `json:"packetsContributedTo"`// AudioLevel is present if the last received RTP packet that this source contributed// to contained an [RFC6465] mixer-to-client audio level header extension. The value// of audioLevel is between 0..1 (linear), where 1.0 represents 0 dBov, 0 represents// silence, and 0.5 represents approximately 6 dBSPL change in the sound pressure level from 0 dBov.AudioLevel float64 `json:"audioLevel"`}func ( RTPContributingSourceStats) () {}func unmarshalCSRCStats( []byte) (RTPContributingSourceStats, error) {var RTPContributingSourceStats:= json.Unmarshal(, &)if != nil {return RTPContributingSourceStats{}, fmt.Errorf("unmarshal csrc stats: %w", )}return , nil}// AudioSourceStats represents an audio track that is attached to one or more senders.type AudioSourceStats struct {// Timestamp is the timestamp associated with this object.Timestamp StatsTimestamp `json:"timestamp"`// Type is the object's StatsTypeType StatsType `json:"type"`// ID is a unique id that is associated with the component inspected to produce// this Stats object. Two Stats objects will have the same ID if they were produced// by inspecting the same underlying object.ID string `json:"id"`// TrackIdentifier represents the id property of the track.TrackIdentifier string `json:"trackIdentifier"`// Kind is "audio"Kind string `json:"kind"`// AudioLevel represents the output audio level of the track.//// The value is a value between 0..1 (linear), where 1.0 represents 0 dBov,// 0 represents silence, and 0.5 represents approximately 6 dBSPL change in// the sound pressure level from 0 dBov.//// If the track is sourced from an Receiver, does no audio processing, has a// constant level, and has a volume setting of 1.0, the audio level is expected// to be the same as the audio level of the source SSRC, while if the volume setting// is 0.5, the AudioLevel is expected to be half that value.AudioLevel float64 `json:"audioLevel"`// TotalAudioEnergy is the total energy of all the audio samples sent/received// for this object, calculated by duration * Math.pow(energy/maxEnergy, 2) for// each audio sample seen.TotalAudioEnergy float64 `json:"totalAudioEnergy"`// TotalSamplesDuration represents the total duration in seconds of all samples// that have sent or received (and thus counted by TotalSamplesSent or TotalSamplesReceived).// Can be used with TotalAudioEnergy to compute an average audio level over different intervals.TotalSamplesDuration float64 `json:"totalSamplesDuration"`// EchoReturnLoss is only present while the sender is sending a track sourced from// a microphone where echo cancellation is applied. Calculated in decibels.EchoReturnLoss float64 `json:"echoReturnLoss"`// EchoReturnLossEnhancement is only present while the sender is sending a track// sourced from a microphone where echo cancellation is applied. Calculated in decibels.EchoReturnLossEnhancement float64 `json:"echoReturnLossEnhancement"`// DroppedSamplesDuration represents the total duration, in seconds, of samples produced by the device that got// dropped before reaching the media source. Only applicable if this media source is backed by an audio capture device.DroppedSamplesDuration float64 `json:"droppedSamplesDuration"`// DroppedSamplesEvents is the number of dropped samples events. This counter increases every time a sample is// dropped after a non-dropped sample. That is, multiple consecutive dropped samples will increase// droppedSamplesDuration multiple times but is a single dropped samples event.DroppedSamplesEvents uint64 `json:"droppedSamplesEvents"`// TotalCaptureDelay is the total delay, in seconds, for each audio sample between the time the sample was emitted// by the capture device and the sample reaching the source. This can be used together with totalSamplesCaptured to// calculate the average capture delay per sample.// Only applicable if the audio source represents an audio capture device.TotalCaptureDelay float64 `json:"totalCaptureDelay"`// TotalSamplesCaptured is the total number of captured samples reaching the audio source, i.e. that were not dropped// by the capture pipeline. The frequency of the media source is not necessarily the same as the frequency of encoders// later in the pipeline. Only applicable if the audio source represents an audio capture device.TotalSamplesCaptured uint64 `json:"totalSamplesCaptured"`}func ( AudioSourceStats) () {}// VideoSourceStats represents a video track that is attached to one or more senders.type VideoSourceStats struct {// Timestamp is the timestamp associated with this object.Timestamp StatsTimestamp `json:"timestamp"`// Type is the object's StatsTypeType StatsType `json:"type"`// ID is a unique id that is associated with the component inspected to produce// this Stats object. Two Stats objects will have the same ID if they were produced// by inspecting the same underlying object.ID string `json:"id"`// TrackIdentifier represents the id property of the track.TrackIdentifier string `json:"trackIdentifier"`// Kind is "video"Kind string `json:"kind"`// Width is width of the last frame originating from this source in pixels.Width uint32 `json:"width"`// Height is height of the last frame originating from this source in pixels.Height uint32 `json:"height"`// Frames is the total number of frames originating from this source.Frames uint32 `json:"frames"`// FramesPerSecond is the number of frames originating from this source, measured during the last second.FramesPerSecond float64 `json:"framesPerSecond"`}func ( VideoSourceStats) () {}func unmarshalMediaSourceStats( []byte) (Stats, error) {type struct {string `json:"kind"`}:= {}:= json.Unmarshal(, &)if != nil {return nil, fmt.Errorf("unmarshal json kind: %w", )}switch MediaKind(.) {case MediaKindAudio:var AudioSourceStats:= json.Unmarshal(, &)if != nil {return nil, fmt.Errorf("unmarshal audio source stats: %w", )}return , nilcase MediaKindVideo:var VideoSourceStats:= json.Unmarshal(, &)if != nil {return nil, fmt.Errorf("unmarshal video source stats: %w", )}return , nildefault:return nil, fmt.Errorf("kind: %w", ErrUnknownType)}}// AudioPlayoutStats represents one playout path - if the same playout stats object is referenced by multiple// RTCInboundRtpStreamStats this is an indication that audio mixing is happening in which case sample counters in this// stats object refer to the samples after mixing. Only applicable if the playout path represents an audio device.type AudioPlayoutStats struct {// Timestamp is the timestamp associated with this object.Timestamp StatsTimestamp `json:"timestamp"`// Type is the object's StatsTypeType StatsType `json:"type"`// ID is a unique id that is associated with the component inspected to produce// this Stats object. Two Stats objects will have the same ID if they were produced// by inspecting the same underlying object.ID string `json:"id"`// Kind is "audio"Kind string `json:"kind"`// SynthesizedSamplesDuration is measured in seconds and is incremented each time an audio sample is synthesized by// this playout path. This metric can be used together with totalSamplesDuration to calculate the percentage of played// out media being synthesized. If the playout path is unable to produce audio samples on time for device playout,// samples are synthesized to be playout out instead. Synthesization typically only happens if the pipeline is// underperforming. Samples synthesized by the RTCInboundRtpStreamStats are not counted for here, but in// InboundRtpStreamStats.concealedSamples.SynthesizedSamplesDuration float64 `json:"synthesizedSamplesDuration"`// SynthesizedSamplesEvents is the number of synthesized samples events. This counter increases every time a sample// is synthesized after a non-synthesized sample. That is, multiple consecutive synthesized samples will increase// synthesizedSamplesDuration multiple times but is a single synthesization samples event.SynthesizedSamplesEvents uint64 `json:"synthesizedSamplesEvents"`// TotalSamplesDuration represents the total duration in seconds of all samples// that have sent or received (and thus counted by TotalSamplesSent or TotalSamplesReceived).// Can be used with TotalAudioEnergy to compute an average audio level over different intervals.TotalSamplesDuration float64 `json:"totalSamplesDuration"`// When audio samples are pulled by the playout device, this counter is incremented with the estimated delay of the// playout path for that audio sample. The playout delay includes the delay from being emitted to the actual time of// playout on the device. This metric can be used together with totalSamplesCount to calculate the average// playout delay per sample.TotalPlayoutDelay float64 `json:"totalPlayoutDelay"`// When audio samples are pulled by the playout device, this counter is incremented with the number of samples// emitted for playout.TotalSamplesCount uint64 `json:"totalSamplesCount"`}func ( AudioPlayoutStats) () {}func unmarshalMediaPlayoutStats( []byte) (Stats, error) {var AudioPlayoutStats:= json.Unmarshal(, &)if != nil {return nil, fmt.Errorf("unmarshal audio playout stats: %w", )}return , nil}// PeerConnectionStats contains statistics related to the PeerConnection object.type PeerConnectionStats struct {// Timestamp is the timestamp associated with this object.Timestamp StatsTimestamp `json:"timestamp"`// Type is the object's StatsTypeType StatsType `json:"type"`// ID is a unique id that is associated with the component inspected to produce// this Stats object. Two Stats objects will have the same ID if they were produced// by inspecting the same underlying object.ID string `json:"id"`// DataChannelsOpened represents the number of unique DataChannels that have// entered the "open" state during their lifetime.DataChannelsOpened uint32 `json:"dataChannelsOpened"`// DataChannelsClosed represents the number of unique DataChannels that have// left the "open" state during their lifetime (due to being closed by either// end or the underlying transport being closed). DataChannels that transition// from "connecting" to "closing" or "closed" without ever being "open"// are not counted in this number.DataChannelsClosed uint32 `json:"dataChannelsClosed"`// DataChannelsRequested Represents the number of unique DataChannels returned// from a successful createDataChannel() call on the PeerConnection. If the// underlying data transport is not established, these may be in the "connecting" state.DataChannelsRequested uint32 `json:"dataChannelsRequested"`// DataChannelsAccepted represents the number of unique DataChannels signaled// in a "datachannel" event on the PeerConnection.DataChannelsAccepted uint32 `json:"dataChannelsAccepted"`}func ( PeerConnectionStats) () {}func unmarshalPeerConnectionStats( []byte) (PeerConnectionStats, error) {var PeerConnectionStats:= json.Unmarshal(, &)if != nil {return PeerConnectionStats{}, fmt.Errorf("unmarshal pc stats: %w", )}return , nil}// DataChannelStats contains statistics related to each DataChannel ID.type DataChannelStats struct {// Timestamp is the timestamp associated with this object.Timestamp StatsTimestamp `json:"timestamp"`// Type is the object's StatsTypeType StatsType `json:"type"`// ID is a unique id that is associated with the component inspected to produce// this Stats object. Two Stats objects will have the same ID if they were produced// by inspecting the same underlying object.ID string `json:"id"`// Label is the "label" value of the DataChannel object.Label string `json:"label"`// Protocol is the "protocol" value of the DataChannel object.Protocol string `json:"protocol"`// DataChannelIdentifier is the "id" attribute of the DataChannel object.DataChannelIdentifier int32 `json:"dataChannelIdentifier"`// TransportID the ID of the TransportStats object for transport used to carry this datachannel.TransportID string `json:"transportId"`// State is the "readyState" value of the DataChannel object.State DataChannelState `json:"state"`// MessagesSent represents the total number of API "message" events sent.MessagesSent uint32 `json:"messagesSent"`// BytesSent represents the total number of payload bytes sent on this// datachannel not including headers or padding.BytesSent uint64 `json:"bytesSent"`// MessagesReceived represents the total number of API "message" events received.MessagesReceived uint32 `json:"messagesReceived"`// BytesReceived represents the total number of bytes received on this// datachannel not including headers or padding.BytesReceived uint64 `json:"bytesReceived"`}func ( DataChannelStats) () {}func unmarshalDataChannelStats( []byte) (DataChannelStats, error) {var DataChannelStats:= json.Unmarshal(, &)if != nil {return DataChannelStats{}, fmt.Errorf("unmarshal data channel stats: %w", )}return , nil}// MediaStreamStats contains statistics related to a specific MediaStream.type MediaStreamStats struct {// Timestamp is the timestamp associated with this object.Timestamp StatsTimestamp `json:"timestamp"`// Type is the object's StatsTypeType StatsType `json:"type"`// ID is a unique id that is associated with the component inspected to produce// this Stats object. Two Stats objects will have the same ID if they were produced// by inspecting the same underlying object.ID string `json:"id"`// StreamIdentifier is the "id" property of the MediaStreamStreamIdentifier string `json:"streamIdentifier"`// TrackIDs is a list of the identifiers of the stats object representing the// stream's tracks, either ReceiverAudioTrackAttachmentStats or ReceiverVideoTrackAttachmentStats.TrackIDs []string `json:"trackIds"`}func ( MediaStreamStats) () {}func unmarshalStreamStats( []byte) (MediaStreamStats, error) {var MediaStreamStats:= json.Unmarshal(, &)if != nil {return MediaStreamStats{}, fmt.Errorf("unmarshal stream stats: %w", )}return , nil}// AudioSenderStats represents the stats about one audio sender of a PeerConnection// object for which one calls GetStats.//// It appears in the stats as soon as the RTPSender is added by either AddTrack// or AddTransceiver, or by media negotiation.type AudioSenderStats struct {// Timestamp is the timestamp associated with this object.Timestamp StatsTimestamp `json:"timestamp"`// Type is the object's StatsTypeType StatsType `json:"type"`// ID is a unique id that is associated with the component inspected to produce// this Stats object. Two Stats objects will have the same ID if they were produced// by inspecting the same underlying object.ID string `json:"id"`// TrackIdentifier represents the id property of the track.TrackIdentifier string `json:"trackIdentifier"`// RemoteSource is true if the source is remote, for instance if it is sourced// from another host via a PeerConnection. False otherwise. Only applicable for 'track' stats.RemoteSource bool `json:"remoteSource"`// Ended reflects the "ended" state of the track.Ended bool `json:"ended"`// Kind is "audio"Kind string `json:"kind"`// AudioLevel represents the output audio level of the track.//// The value is a value between 0..1 (linear), where 1.0 represents 0 dBov,// 0 represents silence, and 0.5 represents approximately 6 dBSPL change in// the sound pressure level from 0 dBov.//// If the track is sourced from an Receiver, does no audio processing, has a// constant level, and has a volume setting of 1.0, the audio level is expected// to be the same as the audio level of the source SSRC, while if the volume setting// is 0.5, the AudioLevel is expected to be half that value.//// For outgoing audio tracks, the AudioLevel is the level of the audio being sent.AudioLevel float64 `json:"audioLevel"`// TotalAudioEnergy is the total energy of all the audio samples sent/received// for this object, calculated by duration * Math.pow(energy/maxEnergy, 2) for// each audio sample seen.TotalAudioEnergy float64 `json:"totalAudioEnergy"`// VoiceActivityFlag represents whether the last RTP packet sent or played out// by this track contained voice activity or not based on the presence of the// V bit in the extension header, as defined in [RFC6464].//// This value indicates the voice activity in the latest RTP packet played out// from a given SSRC, and is defined in RTPSynchronizationSource.voiceActivityFlag.VoiceActivityFlag bool `json:"voiceActivityFlag"`// TotalSamplesDuration represents the total duration in seconds of all samples// that have sent or received (and thus counted by TotalSamplesSent or TotalSamplesReceived).// Can be used with TotalAudioEnergy to compute an average audio level over different intervals.TotalSamplesDuration float64 `json:"totalSamplesDuration"`// EchoReturnLoss is only present while the sender is sending a track sourced from// a microphone where echo cancellation is applied. Calculated in decibels.EchoReturnLoss float64 `json:"echoReturnLoss"`// EchoReturnLossEnhancement is only present while the sender is sending a track// sourced from a microphone where echo cancellation is applied. Calculated in decibels.EchoReturnLossEnhancement float64 `json:"echoReturnLossEnhancement"`// TotalSamplesSent is the total number of samples that have been sent by this sender.TotalSamplesSent uint64 `json:"totalSamplesSent"`}func ( AudioSenderStats) () {}// SenderAudioTrackAttachmentStats object represents the stats about one attachment// of an audio MediaStreamTrack to the PeerConnection object for which one calls GetStats.//// It appears in the stats as soon as it is attached (via AddTrack, via AddTransceiver,// via ReplaceTrack on an RTPSender object).//// If an audio track is attached twice (via AddTransceiver or ReplaceTrack), there// will be two SenderAudioTrackAttachmentStats objects, one for each attachment.// They will have the same "TrackIdentifier" attribute, but different "ID" attributes.//// If the track is detached from the PeerConnection (via removeTrack or via replaceTrack),// it continues to appear, but with the "ObjectDeleted" member set to true.type SenderAudioTrackAttachmentStats AudioSenderStatsfunc ( SenderAudioTrackAttachmentStats) () {}// VideoSenderStats represents the stats about one video sender of a PeerConnection// object for which one calls GetStats.//// It appears in the stats as soon as the sender is added by either AddTrack or// AddTransceiver, or by media negotiation.type VideoSenderStats struct {// Timestamp is the timestamp associated with this object.Timestamp StatsTimestamp `json:"timestamp"`// Type is the object's StatsTypeType StatsType `json:"type"`// ID is a unique id that is associated with the component inspected to produce// this Stats object. Two Stats objects will have the same ID if they were produced// by inspecting the same underlying object.ID string `json:"id"`// Kind is "video"Kind string `json:"kind"`// FramesCaptured represents the total number of frames captured, before encoding,// for this RTPSender (or for this MediaStreamTrack, if type is "track"). For example,// if type is "sender" and this sender's track represents a camera, then this is the// number of frames produced by the camera for this track while being sent by this sender,// combined with the number of frames produced by all tracks previously attached to this// sender while being sent by this sender. Framerates can vary due to hardware limitations// or environmental factors such as lighting conditions.FramesCaptured uint32 `json:"framesCaptured"`// FramesSent represents the total number of frames sent by this RTPSender// (or for this MediaStreamTrack, if type is "track").FramesSent uint32 `json:"framesSent"`// HugeFramesSent represents the total number of huge frames sent by this RTPSender// (or for this MediaStreamTrack, if type is "track"). Huge frames, by definition,// are frames that have an encoded size at least 2.5 times the average size of the frames.// The average size of the frames is defined as the target bitrate per second divided// by the target fps at the time the frame was encoded. These are usually complex// to encode frames with a lot of changes in the picture. This can be used to estimate,// e.g slide changes in the streamed presentation. If a huge frame is also a key frame,// then both counters HugeFramesSent and KeyFramesSent are incremented.HugeFramesSent uint32 `json:"hugeFramesSent"`// KeyFramesSent represents the total number of key frames sent by this RTPSender// (or for this MediaStreamTrack, if type is "track"), such as Infra-frames in// VP8 [RFC6386] or I-frames in H.264 [RFC6184]. This is a subset of FramesSent.// FramesSent - KeyFramesSent gives you the number of delta frames sent.KeyFramesSent uint32 `json:"keyFramesSent"`}func ( VideoSenderStats) () {}// SenderVideoTrackAttachmentStats represents the stats about one attachment of a// video MediaStreamTrack to the PeerConnection object for which one calls GetStats.//// It appears in the stats as soon as it is attached (via AddTrack, via AddTransceiver,// via ReplaceTrack on an RTPSender object).//// If a video track is attached twice (via AddTransceiver or ReplaceTrack), there// will be two SenderVideoTrackAttachmentStats objects, one for each attachment.// They will have the same "TrackIdentifier" attribute, but different "ID" attributes.//// If the track is detached from the PeerConnection (via RemoveTrack or via ReplaceTrack),// it continues to appear, but with the "ObjectDeleted" member set to true.type SenderVideoTrackAttachmentStats VideoSenderStatsfunc ( SenderVideoTrackAttachmentStats) () {}func unmarshalSenderStats( []byte) (Stats, error) {type struct {string `json:"kind"`}:= {}:= json.Unmarshal(, &)if != nil {return nil, fmt.Errorf("unmarshal json kind: %w", )}switch MediaKind(.) {case MediaKindAudio:var AudioSenderStats:= json.Unmarshal(, &)if != nil {return nil, fmt.Errorf("unmarshal audio sender stats: %w", )}return , nilcase MediaKindVideo:var VideoSenderStats:= json.Unmarshal(, &)if != nil {return nil, fmt.Errorf("unmarshal video sender stats: %w", )}return , nildefault:return nil, fmt.Errorf("kind: %w", ErrUnknownType)}}func unmarshalTrackStats( []byte) (Stats, error) {type struct {string `json:"kind"`}:= {}:= json.Unmarshal(, &)if != nil {return nil, fmt.Errorf("unmarshal json kind: %w", )}switch MediaKind(.) {case MediaKindAudio:var SenderAudioTrackAttachmentStats:= json.Unmarshal(, &)if != nil {return nil, fmt.Errorf("unmarshal audio track stats: %w", )}return , nilcase MediaKindVideo:var SenderVideoTrackAttachmentStats:= json.Unmarshal(, &)if != nil {return nil, fmt.Errorf("unmarshal video track stats: %w", )}return , nildefault:return nil, fmt.Errorf("kind: %w", ErrUnknownType)}}// AudioReceiverStats contains audio metrics related to a specific receiver.type AudioReceiverStats struct {// Timestamp is the timestamp associated with this object.Timestamp StatsTimestamp `json:"timestamp"`// Type is the object's StatsTypeType StatsType `json:"type"`// ID is a unique id that is associated with the component inspected to produce// this Stats object. Two Stats objects will have the same ID if they were produced// by inspecting the same underlying object.ID string `json:"id"`// Kind is "audio"Kind string `json:"kind"`// AudioLevel represents the output audio level of the track.//// The value is a value between 0..1 (linear), where 1.0 represents 0 dBov,// 0 represents silence, and 0.5 represents approximately 6 dBSPL change in// the sound pressure level from 0 dBov.//// If the track is sourced from an Receiver, does no audio processing, has a// constant level, and has a volume setting of 1.0, the audio level is expected// to be the same as the audio level of the source SSRC, while if the volume setting// is 0.5, the AudioLevel is expected to be half that value.//// For outgoing audio tracks, the AudioLevel is the level of the audio being sent.AudioLevel float64 `json:"audioLevel"`// TotalAudioEnergy is the total energy of all the audio samples sent/received// for this object, calculated by duration * Math.pow(energy/maxEnergy, 2) for// each audio sample seen.TotalAudioEnergy float64 `json:"totalAudioEnergy"`// VoiceActivityFlag represents whether the last RTP packet sent or played out// by this track contained voice activity or not based on the presence of the// V bit in the extension header, as defined in [RFC6464].//// This value indicates the voice activity in the latest RTP packet played out// from a given SSRC, and is defined in RTPSynchronizationSource.voiceActivityFlag.VoiceActivityFlag bool `json:"voiceActivityFlag"`// TotalSamplesDuration represents the total duration in seconds of all samples// that have sent or received (and thus counted by TotalSamplesSent or TotalSamplesReceived).// Can be used with TotalAudioEnergy to compute an average audio level over different intervals.TotalSamplesDuration float64 `json:"totalSamplesDuration"`// EstimatedPlayoutTimestamp is the estimated playout time of this receiver's// track. The playout time is the NTP timestamp of the last playable sample that// has a known timestamp (from an RTCP SR packet mapping RTP timestamps to NTP// timestamps), extrapolated with the time elapsed since it was ready to be played out.// This is the "current time" of the track in NTP clock time of the sender and// can be present even if there is no audio currently playing.//// This can be useful for estimating how much audio and video is out of// sync for two tracks from the same source:// AudioTrackStats.EstimatedPlayoutTimestamp - VideoTrackStats.EstimatedPlayoutTimestampEstimatedPlayoutTimestamp StatsTimestamp `json:"estimatedPlayoutTimestamp"`// JitterBufferDelay is the sum of the time, in seconds, each sample takes from// the time it is received and to the time it exits the jitter buffer.// This increases upon samples exiting, having completed their time in the buffer// (incrementing JitterBufferEmittedCount). The average jitter buffer delay can// be calculated by dividing the JitterBufferDelay with the JitterBufferEmittedCount.JitterBufferDelay float64 `json:"jitterBufferDelay"`// JitterBufferEmittedCount is the total number of samples that have come out// of the jitter buffer (increasing JitterBufferDelay).JitterBufferEmittedCount uint64 `json:"jitterBufferEmittedCount"`// TotalSamplesReceived is the total number of samples that have been received// by this receiver. This includes ConcealedSamples.TotalSamplesReceived uint64 `json:"totalSamplesReceived"`// ConcealedSamples is the total number of samples that are concealed samples.// A concealed sample is a sample that is based on data that was synthesized// to conceal packet loss and does not represent incoming data.ConcealedSamples uint64 `json:"concealedSamples"`// ConcealmentEvents is the number of concealment events. This counter increases// every time a concealed sample is synthesized after a non-concealed sample.// That is, multiple consecutive concealed samples will increase the concealedSamples// count multiple times but is a single concealment event.ConcealmentEvents uint64 `json:"concealmentEvents"`}func ( AudioReceiverStats) () {}// VideoReceiverStats contains video metrics related to a specific receiver.type VideoReceiverStats struct {// Timestamp is the timestamp associated with this object.Timestamp StatsTimestamp `json:"timestamp"`// Type is the object's StatsTypeType StatsType `json:"type"`// ID is a unique id that is associated with the component inspected to produce// this Stats object. Two Stats objects will have the same ID if they were produced// by inspecting the same underlying object.ID string `json:"id"`// Kind is "video"Kind string `json:"kind"`// FrameWidth represents the width of the last processed frame for this track.// Before the first frame is processed this attribute is missing.FrameWidth uint32 `json:"frameWidth"`// FrameHeight represents the height of the last processed frame for this track.// Before the first frame is processed this attribute is missing.FrameHeight uint32 `json:"frameHeight"`// FramesPerSecond represents the nominal FPS value before the degradation preference// is applied. It is the number of complete frames in the last second. For sending// tracks it is the current captured FPS and for the receiving tracks it is the// current decoding framerate.FramesPerSecond float64 `json:"framesPerSecond"`// EstimatedPlayoutTimestamp is the estimated playout time of this receiver's// track. The playout time is the NTP timestamp of the last playable sample that// has a known timestamp (from an RTCP SR packet mapping RTP timestamps to NTP// timestamps), extrapolated with the time elapsed since it was ready to be played out.// This is the "current time" of the track in NTP clock time of the sender and// can be present even if there is no audio currently playing.//// This can be useful for estimating how much audio and video is out of// sync for two tracks from the same source:// AudioTrackStats.EstimatedPlayoutTimestamp - VideoTrackStats.EstimatedPlayoutTimestampEstimatedPlayoutTimestamp StatsTimestamp `json:"estimatedPlayoutTimestamp"`// JitterBufferDelay is the sum of the time, in seconds, each sample takes from// the time it is received and to the time it exits the jitter buffer.// This increases upon samples exiting, having completed their time in the buffer// (incrementing JitterBufferEmittedCount). The average jitter buffer delay can// be calculated by dividing the JitterBufferDelay with the JitterBufferEmittedCount.JitterBufferDelay float64 `json:"jitterBufferDelay"`// JitterBufferEmittedCount is the total number of samples that have come out// of the jitter buffer (increasing JitterBufferDelay).JitterBufferEmittedCount uint64 `json:"jitterBufferEmittedCount"`// FramesReceived Represents the total number of complete frames received for// this receiver. This metric is incremented when the complete frame is received.FramesReceived uint32 `json:"framesReceived"`// KeyFramesReceived represents the total number of complete key frames received// for this MediaStreamTrack, such as Infra-frames in VP8 [RFC6386] or I-frames// in H.264 [RFC6184]. This is a subset of framesReceived. `framesReceived - keyFramesReceived`// gives you the number of delta frames received. This metric is incremented when// the complete key frame is received. It is not incremented if a partial key// frames is received and sent for decoding, i.e., the frame could not be recovered// via retransmission or FEC.KeyFramesReceived uint32 `json:"keyFramesReceived"`// FramesDecoded represents the total number of frames correctly decoded for this// SSRC, i.e., frames that would be displayed if no frames are dropped.FramesDecoded uint32 `json:"framesDecoded"`// FramesDropped is the total number of frames dropped predecode or dropped// because the frame missed its display deadline for this receiver's track.FramesDropped uint32 `json:"framesDropped"`// The cumulative number of partial frames lost. This metric is incremented when// the frame is sent to the decoder. If the partial frame is received and recovered// via retransmission or FEC before decoding, the FramesReceived counter is incremented.PartialFramesLost uint32 `json:"partialFramesLost"`// FullFramesLost is the cumulative number of full frames lost.FullFramesLost uint32 `json:"fullFramesLost"`}func ( VideoReceiverStats) () {}func unmarshalReceiverStats( []byte) (Stats, error) {type struct {string `json:"kind"`}:= {}:= json.Unmarshal(, &)if != nil {return nil, fmt.Errorf("unmarshal json kind: %w", )}switch MediaKind(.) {case MediaKindAudio:var AudioReceiverStats:= json.Unmarshal(, &)if != nil {return nil, fmt.Errorf("unmarshal audio receiver stats: %w", )}return , nilcase MediaKindVideo:var VideoReceiverStats:= json.Unmarshal(, &)if != nil {return nil, fmt.Errorf("unmarshal video receiver stats: %w", )}return , nildefault:return nil, fmt.Errorf("kind: %w", ErrUnknownType)}}// TransportStats contains transport statistics related to the PeerConnection object.type TransportStats struct {// Timestamp is the timestamp associated with this object.Timestamp StatsTimestamp `json:"timestamp"`// Type is the object's StatsTypeType StatsType `json:"type"`// ID is a unique id that is associated with the component inspected to produce// this Stats object. Two Stats objects will have the same ID if they were produced// by inspecting the same underlying object.ID string `json:"id"`// PacketsSent represents the total number of packets sent over this transport.PacketsSent uint32 `json:"packetsSent"`// PacketsReceived represents the total number of packets received on this transport.PacketsReceived uint32 `json:"packetsReceived"`// BytesSent represents the total number of payload bytes sent on this PeerConnection// not including headers or padding.BytesSent uint64 `json:"bytesSent"`// BytesReceived represents the total number of bytes received on this PeerConnection// not including headers or padding.BytesReceived uint64 `json:"bytesReceived"`// RTCPTransportStatsID is the ID of the transport that gives stats for the RTCP// component If RTP and RTCP are not multiplexed and this record has only// the RTP component stats.RTCPTransportStatsID string `json:"rtcpTransportStatsId"`// ICERole is set to the current value of the "role" attribute of the underlying// DTLSTransport's "iceTransport".ICERole ICERole `json:"iceRole"`// DTLSState is set to the current value of the "state" attribute of the underlying DTLSTransport.DTLSState DTLSTransportState `json:"dtlsState"`// ICEState is set to the current value of the "state" attribute of the underlying// RTCIceTransport's "state".ICEState ICETransportState `json:"iceState"`// SelectedCandidatePairID is a unique identifier that is associated to the object// that was inspected to produce the ICECandidatePairStats associated with this transport.SelectedCandidatePairID string `json:"selectedCandidatePairId"`// LocalCertificateID is the ID of the CertificateStats for the local certificate.// Present only if DTLS is negotiated.LocalCertificateID string `json:"localCertificateId"`// LocalCertificateID is the ID of the CertificateStats for the remote certificate.// Present only if DTLS is negotiated.RemoteCertificateID string `json:"remoteCertificateId"`// DTLSCipher is the descriptive name of the cipher suite used for the DTLS transport,// as defined in the "Description" column of the IANA cipher suite registry.DTLSCipher string `json:"dtlsCipher"`// SRTPCipher is the descriptive name of the protection profile used for the SRTP// transport, as defined in the "Profile" column of the IANA DTLS-SRTP protection// profile registry.SRTPCipher string `json:"srtpCipher"`}func ( TransportStats) () {}func unmarshalTransportStats( []byte) (TransportStats, error) {var TransportStats:= json.Unmarshal(, &)if != nil {return TransportStats{}, fmt.Errorf("unmarshal transport stats: %w", )}return , nil}// StatsICECandidatePairState is the state of an ICE candidate pair used in the// ICECandidatePairStats object.type StatsICECandidatePairState stringfunc toStatsICECandidatePairState( ice.CandidatePairState) (StatsICECandidatePairState, error) {switch {case ice.CandidatePairStateWaiting:return StatsICECandidatePairStateWaiting, nilcase ice.CandidatePairStateInProgress:return StatsICECandidatePairStateInProgress, nilcase ice.CandidatePairStateFailed:return StatsICECandidatePairStateFailed, nilcase ice.CandidatePairStateSucceeded:return StatsICECandidatePairStateSucceeded, nildefault:// NOTE: this should never happen[tm]:= fmt.Errorf("%w: %s", errStatsICECandidateStateInvalid, .String())return StatsICECandidatePairState("Unknown"),}}func toICECandidatePairStats( ice.CandidatePairStats) (ICECandidatePairStats, error) {, := toStatsICECandidatePairState(.State)if != nil {return ICECandidatePairStats{},}return ICECandidatePairStats{Timestamp: statsTimestampFrom(.Timestamp),Type: StatsTypeCandidatePair,ID: newICECandidatePairStatsID(.LocalCandidateID, .RemoteCandidateID),// TransportID:LocalCandidateID: .LocalCandidateID,RemoteCandidateID: .RemoteCandidateID,State: ,Nominated: .Nominated,PacketsSent: .PacketsSent,PacketsReceived: .PacketsReceived,BytesSent: .BytesSent,BytesReceived: .BytesReceived,LastPacketSentTimestamp: statsTimestampFrom(.LastPacketSentTimestamp),LastPacketReceivedTimestamp: statsTimestampFrom(.LastPacketReceivedTimestamp),FirstRequestTimestamp: statsTimestampFrom(.FirstRequestTimestamp),LastRequestTimestamp: statsTimestampFrom(.LastRequestTimestamp),FirstResponseTimestamp: statsTimestampFrom(.FirstResponseTimestamp),LastResponseTimestamp: statsTimestampFrom(.LastResponseTimestamp),FirstRequestReceivedTimestamp: statsTimestampFrom(.FirstRequestReceivedTimestamp),LastRequestReceivedTimestamp: statsTimestampFrom(.LastRequestReceivedTimestamp),TotalRoundTripTime: .TotalRoundTripTime,CurrentRoundTripTime: .CurrentRoundTripTime,AvailableOutgoingBitrate: .AvailableOutgoingBitrate,AvailableIncomingBitrate: .AvailableIncomingBitrate,CircuitBreakerTriggerCount: .CircuitBreakerTriggerCount,RequestsReceived: .RequestsReceived,RequestsSent: .RequestsSent,ResponsesReceived: .ResponsesReceived,ResponsesSent: .ResponsesSent,RetransmissionsReceived: .RetransmissionsReceived,RetransmissionsSent: .RetransmissionsSent,ConsentRequestsSent: .ConsentRequestsSent,ConsentExpiredTimestamp: statsTimestampFrom(.ConsentExpiredTimestamp),}, nil}const (// StatsICECandidatePairStateFrozen means a check for this pair hasn't been// performed, and it can't yet be performed until some other check succeeds,// allowing this pair to unfreeze and move into the Waiting state.StatsICECandidatePairStateFrozen StatsICECandidatePairState = "frozen"// StatsICECandidatePairStateWaiting means a check has not been performed for// this pair, and can be performed as soon as it is the highest-priority Waiting// pair on the check list.StatsICECandidatePairStateWaiting StatsICECandidatePairState = "waiting"// StatsICECandidatePairStateInProgress means a check has been sent for this pair,// but the transaction is in progress.StatsICECandidatePairStateInProgress StatsICECandidatePairState = "in-progress"// StatsICECandidatePairStateFailed means a check for this pair was already done// and failed, either never producing any response or producing an unrecoverable// failure response.StatsICECandidatePairStateFailed StatsICECandidatePairState = "failed"// StatsICECandidatePairStateSucceeded means a check for this pair was already// done and produced a successful result.StatsICECandidatePairStateSucceeded StatsICECandidatePairState = "succeeded")// ICECandidatePairStats contains ICE candidate pair statistics related// to the ICETransport objects.type ICECandidatePairStats struct {// Timestamp is the timestamp associated with this object.Timestamp StatsTimestamp `json:"timestamp"`// Type is the object's StatsTypeType StatsType `json:"type"`// ID is a unique id that is associated with the component inspected to produce// this Stats object. Two Stats objects will have the same ID if they were produced// by inspecting the same underlying object.ID string `json:"id"`// TransportID is a unique identifier that is associated to the object that// was inspected to produce the TransportStats associated with this candidate pair.TransportID string `json:"transportId"`// LocalCandidateID is a unique identifier that is associated to the object// that was inspected to produce the ICECandidateStats for the local candidate// associated with this candidate pair.LocalCandidateID string `json:"localCandidateId"`// RemoteCandidateID is a unique identifier that is associated to the object// that was inspected to produce the ICECandidateStats for the remote candidate// associated with this candidate pair.RemoteCandidateID string `json:"remoteCandidateId"`// State represents the state of the checklist for the local and remote// candidates in a pair.State StatsICECandidatePairState `json:"state"`// Nominated is true when this valid pair that should be used for media// if it is the highest-priority one amongst those whose nominated flag is setNominated bool `json:"nominated"`// PacketsSent represents the total number of packets sent on this candidate pair.PacketsSent uint32 `json:"packetsSent"`// PacketsReceived represents the total number of packets received on this candidate pair.PacketsReceived uint32 `json:"packetsReceived"`// BytesSent represents the total number of payload bytes sent on this candidate pair// not including headers or padding.BytesSent uint64 `json:"bytesSent"`// BytesReceived represents the total number of payload bytes received on this candidate pair// not including headers or padding.BytesReceived uint64 `json:"bytesReceived"`// LastPacketSentTimestamp represents the timestamp at which the last packet was// sent on this particular candidate pair, excluding STUN packets.LastPacketSentTimestamp StatsTimestamp `json:"lastPacketSentTimestamp"`// LastPacketReceivedTimestamp represents the timestamp at which the last packet// was received on this particular candidate pair, excluding STUN packets.LastPacketReceivedTimestamp StatsTimestamp `json:"lastPacketReceivedTimestamp"`// FirstRequestTimestamp represents the timestamp at which the first STUN request// was sent on this particular candidate pair.FirstRequestTimestamp StatsTimestamp `json:"firstRequestTimestamp"`// LastRequestTimestamp represents the timestamp at which the last STUN request// was sent on this particular candidate pair. The average interval between two// consecutive connectivity checks sent can be calculated with// (LastRequestTimestamp - FirstRequestTimestamp) / RequestsSent.LastRequestTimestamp StatsTimestamp `json:"lastRequestTimestamp"`// FirstResponseTimestamp represents the timestamp at which the first STUN response// was received on this particular candidate pair.FirstResponseTimestamp StatsTimestamp `json:"firstResponseTimestamp"`// LastResponseTimestamp represents the timestamp at which the last STUN response// was received on this particular candidate pair.LastResponseTimestamp StatsTimestamp `json:"lastResponseTimestamp"`// FirstRequestReceivedTimestamp represents the timestamp at which the first// connectivity check request was received.FirstRequestReceivedTimestamp StatsTimestamp `json:"firstRequestReceivedTimestamp"`// LastRequestReceivedTimestamp represents the timestamp at which the last// connectivity check request was received.LastRequestReceivedTimestamp StatsTimestamp `json:"lastRequestReceivedTimestamp"`// TotalRoundTripTime represents the sum of all round trip time measurements// in seconds since the beginning of the session, based on STUN connectivity// check responses (ResponsesReceived), including those that reply to requests// that are sent in order to verify consent. The average round trip time can// be computed from TotalRoundTripTime by dividing it by ResponsesReceived.TotalRoundTripTime float64 `json:"totalRoundTripTime"`// CurrentRoundTripTime represents the latest round trip time measured in seconds,// computed from both STUN connectivity checks, including those that are sent// for consent verification.CurrentRoundTripTime float64 `json:"currentRoundTripTime"`// AvailableOutgoingBitrate is calculated by the underlying congestion control// by combining the available bitrate for all the outgoing RTP streams using// this candidate pair. The bitrate measurement does not count the size of the// IP or other transport layers like TCP or UDP. It is similar to the TIAS defined// in RFC 3890, i.e., it is measured in bits per second and the bitrate is calculated// over a 1 second window.AvailableOutgoingBitrate float64 `json:"availableOutgoingBitrate"`// AvailableIncomingBitrate is calculated by the underlying congestion control// by combining the available bitrate for all the incoming RTP streams using// this candidate pair. The bitrate measurement does not count the size of the// IP or other transport layers like TCP or UDP. It is similar to the TIAS defined// in RFC 3890, i.e., it is measured in bits per second and the bitrate is// calculated over a 1 second window.AvailableIncomingBitrate float64 `json:"availableIncomingBitrate"`// CircuitBreakerTriggerCount represents the number of times the circuit breaker// is triggered for this particular 5-tuple, ceasing transmission.CircuitBreakerTriggerCount uint32 `json:"circuitBreakerTriggerCount"`// RequestsReceived represents the total number of connectivity check requests// received (including retransmissions). It is impossible for the receiver to// tell whether the request was sent in order to check connectivity or check// consent, so all connectivity checks requests are counted here.RequestsReceived uint64 `json:"requestsReceived"`// RequestsSent represents the total number of connectivity check requests// sent (not including retransmissions).RequestsSent uint64 `json:"requestsSent"`// ResponsesReceived represents the total number of connectivity check responses received.ResponsesReceived uint64 `json:"responsesReceived"`// ResponsesSent represents the total number of connectivity check responses sent.// Since we cannot distinguish connectivity check requests and consent requests,// all responses are counted.ResponsesSent uint64 `json:"responsesSent"`// RetransmissionsReceived represents the total number of connectivity check// request retransmissions received.RetransmissionsReceived uint64 `json:"retransmissionsReceived"`// RetransmissionsSent represents the total number of connectivity check// request retransmissions sent.RetransmissionsSent uint64 `json:"retransmissionsSent"`// ConsentRequestsSent represents the total number of consent requests sent.ConsentRequestsSent uint64 `json:"consentRequestsSent"`// ConsentExpiredTimestamp represents the timestamp at which the latest valid// STUN binding response expired.ConsentExpiredTimestamp StatsTimestamp `json:"consentExpiredTimestamp"`// PacketsDiscardedOnSend retpresents the total number of packets for this candidate pair// that have been discarded due to socket errors, i.e. a socket error occurred// when handing the packets to the socket. This might happen due to various reasons,// including full buffer or no available memory.PacketsDiscardedOnSend uint32 `json:"packetsDiscardedOnSend"`// BytesDiscardedOnSend represents the total number of bytes for this candidate pair// that have been discarded due to socket errors, i.e. a socket error occurred// when handing the packets containing the bytes to the socket. This might happen due// to various reasons, including full buffer or no available memory.// Calculated as defined in [RFC3550] section 6.4.1.BytesDiscardedOnSend uint32 `json:"bytesDiscardedOnSend"`}func ( ICECandidatePairStats) () {}func unmarshalICECandidatePairStats( []byte) (ICECandidatePairStats, error) {var ICECandidatePairStats:= json.Unmarshal(, &)if != nil {return ICECandidatePairStats{}, fmt.Errorf("unmarshal ice candidate pair stats: %w", )}return , nil}// ICECandidateStats contains ICE candidate statistics related to the ICETransport objects.type ICECandidateStats struct {// Timestamp is the timestamp associated with this object.Timestamp StatsTimestamp `json:"timestamp"`// Type is the object's StatsTypeType StatsType `json:"type"`// ID is a unique id that is associated with the component inspected to produce// this Stats object. Two Stats objects will have the same ID if they were produced// by inspecting the same underlying object.ID string `json:"id"`// TransportID is a unique identifier that is associated to the object that// was inspected to produce the TransportStats associated with this candidate.TransportID string `json:"transportId"`// NetworkType represents the type of network interface used by the base of a// local candidate (the address the ICE agent sends from). Only present for// local candidates; it's not possible to know what type of network interface// a remote candidate is using.//// Note:// This stat only tells you about the network interface used by the first "hop";// it's possible that a connection will be bottlenecked by another type of network.// For example, when using Wi-Fi tethering, the networkType of the relevant candidate// would be "wifi", even when the next hop is over a cellular connection.//// DEPRECATED. Although it may still work in some browsers, the networkType property was deprecated for// preserving privacy.NetworkType string `json:"networkType,omitempty"`// IP is the IP address of the candidate, allowing for IPv4 addresses and// IPv6 addresses, but fully qualified domain names (FQDNs) are not allowed.IP string `json:"ip"`// Port is the port number of the candidate.Port int32 `json:"port"`// Protocol is one of udp and tcp.Protocol string `json:"protocol"`// CandidateType is the "Type" field of the ICECandidate.CandidateType ICECandidateType `json:"candidateType"`// Priority is the "Priority" field of the ICECandidate.Priority int32 `json:"priority"`// URL is the URL of the TURN or STUN server indicated in the that translated// this IP address. It is the URL address surfaced in an PeerConnectionICEEvent.URL string `json:"url"`// RelayProtocol is the protocol used by the endpoint to communicate with the// TURN server. This is only present for local candidates. Valid values for// the TURN URL protocol is one of udp, tcp, or tls.RelayProtocol string `json:"relayProtocol"`// Deleted is true if the candidate has been deleted/freed. For host candidates,// this means that any network resources (typically a socket) associated with the// candidate have been released. For TURN candidates, this means the TURN allocation// is no longer active.//// Only defined for local candidates. For remote candidates, this property is not applicable.Deleted bool `json:"deleted"`}func ( ICECandidateStats) () {}func unmarshalICECandidateStats( []byte) (ICECandidateStats, error) {var ICECandidateStats:= json.Unmarshal(, &)if != nil {return ICECandidateStats{}, fmt.Errorf("unmarshal ice candidate stats: %w", )}return , nil}// CertificateStats contains information about a certificate used by an ICETransport.type CertificateStats struct {// Timestamp is the timestamp associated with this object.Timestamp StatsTimestamp `json:"timestamp"`// Type is the object's StatsTypeType StatsType `json:"type"`// ID is a unique id that is associated with the component inspected to produce// this Stats object. Two Stats objects will have the same ID if they were produced// by inspecting the same underlying object.ID string `json:"id"`// Fingerprint is the fingerprint of the certificate.Fingerprint string `json:"fingerprint"`// FingerprintAlgorithm is the hash function used to compute the certificate fingerprint. For instance, "sha-256".FingerprintAlgorithm string `json:"fingerprintAlgorithm"`// Base64Certificate is the DER-encoded base-64 representation of the certificate.Base64Certificate string `json:"base64Certificate"`// IssuerCertificateID refers to the stats object that contains the next certificate// in the certificate chain. If the current certificate is at the end of the chain// (i.e. a self-signed certificate), this will not be set.IssuerCertificateID string `json:"issuerCertificateId"`}func ( CertificateStats) () {}func unmarshalCertificateStats( []byte) (CertificateStats, error) {var CertificateStats:= json.Unmarshal(, &)if != nil {return CertificateStats{}, fmt.Errorf("unmarshal certificate stats: %w", )}return , nil}// SCTPTransportStats contains information about a certificate used by an SCTPTransport.type SCTPTransportStats struct {// Timestamp is the timestamp associated with this object.Timestamp StatsTimestamp `json:"timestamp"`// Type is the object's StatsTypeType StatsType `json:"type"`// ID is a unique id that is associated with the component inspected to produce// this Stats object. Two Stats objects will have the same ID if they were produced// by inspecting the same underlying object.ID string `json:"id"`// TransportID is the identifier of the object that was inspected to produce the// RTCTransportStats for the DTLSTransport and ICETransport supporting the SCTP transport.TransportID string `json:"transportId"`// SmoothedRoundTripTime is the latest smoothed round-trip time value,// corresponding to spinfo_srtt defined in [RFC6458] but converted to seconds.// If there has been no round-trip time measurements yet, this value is undefined.SmoothedRoundTripTime float64 `json:"smoothedRoundTripTime"`// CongestionWindow is the latest congestion window, corresponding to spinfo_cwnd defined in [RFC6458].CongestionWindow uint32 `json:"congestionWindow"`// ReceiverWindow is the latest receiver window, corresponding to sstat_rwnd defined in [RFC6458].ReceiverWindow uint32 `json:"receiverWindow"`// MTU is the latest maximum transmission unit, corresponding to spinfo_mtu defined in [RFC6458].MTU uint32 `json:"mtu"`// UNACKData is the number of unacknowledged DATA chunks, corresponding to sstat_unackdata defined in [RFC6458].UNACKData uint32 `json:"unackData"`// BytesSent represents the total number of bytes sent on this SCTPTransportBytesSent uint64 `json:"bytesSent"`// BytesReceived represents the total number of bytes received on this SCTPTransportBytesReceived uint64 `json:"bytesReceived"`}func ( SCTPTransportStats) () {}func unmarshalSCTPTransportStats( []byte) (SCTPTransportStats, error) {var SCTPTransportStatsif := json.Unmarshal(, &); != nil {return SCTPTransportStats{}, fmt.Errorf("unmarshal sctp transport stats: %w", )}return , nil}
![]() |
The pages are generated with Golds v0.8.2. (GOOS=linux GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds. |