2024-05-15 23:15:00 +00:00
// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
// SPDX-License-Identifier: MIT
2022-03-10 09:44:48 +00:00
package webrtc
import (
2024-06-05 20:10:03 +00:00
"encoding/json"
2022-03-10 09:44:48 +00:00
"fmt"
"sync"
"time"
"github.com/pion/ice/v2"
)
// A Stats object contains a set of statistics copies out of a monitored component
// of the WebRTC stack at a specific time.
2024-06-05 20:10:03 +00:00
type Stats interface {
statsMarker ( )
}
// UnmarshalStatsJSON unmarshals a Stats object from JSON
func UnmarshalStatsJSON ( b [ ] byte ) ( Stats , error ) {
type typeJSON struct {
Type StatsType ` json:"type" `
}
typeHolder := typeJSON { }
err := json . Unmarshal ( b , & typeHolder )
if err != nil {
return nil , fmt . Errorf ( "unmarshal json type: %w" , err )
}
switch typeHolder . Type {
case StatsTypeCodec :
return unmarshalCodecStats ( b )
case StatsTypeInboundRTP :
return unmarshalInboundRTPStreamStats ( b )
case StatsTypeOutboundRTP :
return unmarshalOutboundRTPStreamStats ( b )
case StatsTypeRemoteInboundRTP :
return unmarshalRemoteInboundRTPStreamStats ( b )
case StatsTypeRemoteOutboundRTP :
return unmarshalRemoteOutboundRTPStreamStats ( b )
case StatsTypeCSRC :
return unmarshalCSRCStats ( b )
case StatsTypeMediaSource :
return unmarshalMediaSourceStats ( b )
case StatsTypeMediaPlayout :
return unmarshalMediaPlayoutStats ( b )
case StatsTypePeerConnection :
return unmarshalPeerConnectionStats ( b )
case StatsTypeDataChannel :
return unmarshalDataChannelStats ( b )
case StatsTypeStream :
return unmarshalStreamStats ( b )
case StatsTypeTrack :
return unmarshalTrackStats ( b )
case StatsTypeSender :
return unmarshalSenderStats ( b )
case StatsTypeReceiver :
return unmarshalReceiverStats ( b )
case StatsTypeTransport :
return unmarshalTransportStats ( b )
case StatsTypeCandidatePair :
return unmarshalICECandidatePairStats ( b )
case StatsTypeLocalCandidate , StatsTypeRemoteCandidate :
return unmarshalICECandidateStats ( b )
case StatsTypeCertificate :
return unmarshalCertificateStats ( b )
case StatsTypeSCTPTransport :
return unmarshalSCTPTransportStats ( b )
default :
return nil , fmt . Errorf ( "type: %w" , ErrUnknownType )
}
}
2022-03-10 09:44:48 +00:00
// StatsType indicates the type of the object that a Stats object represents.
type StatsType string
const (
// 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"
2024-06-05 20:10:03 +00:00
// StatsTypeMediaSource is used by AudioSourceStats or VideoSourceStats depending on kind.
StatsTypeMediaSource = "media-source"
// StatsTypeMediaPlayout is used by AudioPlayoutStats.
StatsTypeMediaPlayout StatsType = "media-playout"
2022-03-10 09:44:48 +00:00
// 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"
2024-06-05 20:10:03 +00:00
// StatsTypeTrack is used by SenderVideoTrackAttachmentStats and SenderAudioTrackAttachmentStats depending on kind.
2022-03-10 09:44:48 +00:00
StatsTypeTrack StatsType = "track"
2024-06-05 20:10:03 +00:00
// StatsTypeSender is used by the AudioSenderStats or VideoSenderStats depending on kind.
2022-03-10 09:44:48 +00:00
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"
2024-06-05 20:10:03 +00:00
// StatsTypeSCTPTransport is used by SCTPTransportStats
StatsTypeSCTPTransport StatsType = "sctp-transport"
)
// MediaKind indicates the kind of media (audio or video)
type MediaKind string
const (
// MediaKindAudio indicates this is audio stats
MediaKindAudio MediaKind = "audio"
// MediaKindVideo indicates this is video stats
MediaKindVideo MediaKind = "video"
2022-03-10 09:44:48 +00:00
)
// 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 ( s StatsTimestamp ) Time ( ) time . Time {
millis := float64 ( s )
nanos := int64 ( millis * float64 ( time . Millisecond ) )
return time . Unix ( 0 , nanos ) . UTC ( )
}
func statsTimestampFrom ( t time . Time ) StatsTimestamp {
return StatsTimestamp ( t . UnixNano ( ) / int64 ( time . Millisecond ) )
}
func statsTimestampNow ( ) StatsTimestamp {
return statsTimestampFrom ( time . Now ( ) )
}
// StatsReport collects Stats objects indexed by their ID.
type StatsReport map [ string ] Stats
type statsReportCollector struct {
collectingGroup sync . WaitGroup
report StatsReport
mux sync . Mutex
}
func newStatsReportCollector ( ) * statsReportCollector {
return & statsReportCollector { report : make ( StatsReport ) }
}
func ( src * statsReportCollector ) Collecting ( ) {
src . collectingGroup . Add ( 1 )
}
func ( src * statsReportCollector ) Collect ( id string , stats Stats ) {
src . mux . Lock ( )
defer src . mux . Unlock ( )
src . report [ id ] = stats
src . collectingGroup . Done ( )
}
func ( src * statsReportCollector ) Done ( ) {
src . collectingGroup . Done ( )
}
func ( src * statsReportCollector ) Ready ( ) StatsReport {
src . collectingGroup . Wait ( )
src . mux . Lock ( )
defer src . mux . Unlock ( )
return src . report
}
// CodecType specifies whether a CodecStats objects represents a media format
// that is being encoded or decoded
type CodecType string
const (
// 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 StatsType
Type 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 decoding
PayloadType PayloadType ` json:"payloadType" `
// CodecType of this CodecStats
CodecType 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" `
}
2024-06-05 20:10:03 +00:00
func ( s CodecStats ) statsMarker ( ) { }
func unmarshalCodecStats ( b [ ] byte ) ( CodecStats , error ) {
var codecStats CodecStats
err := json . Unmarshal ( b , & codecStats )
if err != nil {
return CodecStats { } , fmt . Errorf ( "unmarshal codec stats: %w" , err )
}
return codecStats , nil
}
2022-03-10 09:44:48 +00:00
// InboundRTPStreamStats contains statistics for an inbound RTP stream that is
// currently received with this PeerConnection object.
type InboundRTPStreamStats struct {
// Timestamp is the timestamp associated with this object.
Timestamp StatsTimestamp ` json:"timestamp" `
// Type is the object's StatsType
Type 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 SSRC
Jitter 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" `
// 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" `
// 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" `
// BytesReceived is the total number of bytes received for this SSRC.
BytesReceived uint64 ` json:"bytesReceived" `
// 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" `
}
2024-06-05 20:10:03 +00:00
func ( s InboundRTPStreamStats ) statsMarker ( ) { }
func unmarshalInboundRTPStreamStats ( b [ ] byte ) ( InboundRTPStreamStats , error ) {
var inboundRTPStreamStats InboundRTPStreamStats
err := json . Unmarshal ( b , & inboundRTPStreamStats )
if err != nil {
return InboundRTPStreamStats { } , fmt . Errorf ( "unmarshal inbound rtp stream stats: %w" , err )
}
return inboundRTPStreamStats , nil
}
2022-03-10 09:44:48 +00:00
// QualityLimitationReason lists the reason for limiting the resolution and/or framerate.
// Only valid for video.
type QualityLimitationReason string
const (
// 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 {
// Timestamp is the timestamp associated with this object.
Timestamp StatsTimestamp ` json:"timestamp" `
// Type is the object's StatsType
Type 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" `
// 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" `
// FramesEncoded represents the total number of frames successfully encoded for this RTP media stream.
// Only valid for video.
FramesEncoded uint32 ` json:"framesEncoded" `
// 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" `
// 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" `
// 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" `
}
2024-06-05 20:10:03 +00:00
func ( s OutboundRTPStreamStats ) statsMarker ( ) { }
func unmarshalOutboundRTPStreamStats ( b [ ] byte ) ( OutboundRTPStreamStats , error ) {
var outboundRTPStreamStats OutboundRTPStreamStats
err := json . Unmarshal ( b , & outboundRTPStreamStats )
if err != nil {
return OutboundRTPStreamStats { } , fmt . Errorf ( "unmarshal outbound rtp stream stats: %w" , err )
}
return outboundRTPStreamStats , nil
}
2022-03-10 09:44:48 +00:00
// 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 StatsType
Type 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 SSRC
Jitter 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" `
2024-06-05 20:10:03 +00:00
// FractionLost is the fraction packet loss reported for this SSRC.
2022-03-10 09:44:48 +00:00
FractionLost float64 ` json:"fractionLost" `
}
2024-06-05 20:10:03 +00:00
func ( s RemoteInboundRTPStreamStats ) statsMarker ( ) { }
func unmarshalRemoteInboundRTPStreamStats ( b [ ] byte ) ( RemoteInboundRTPStreamStats , error ) {
var remoteInboundRTPStreamStats RemoteInboundRTPStreamStats
err := json . Unmarshal ( b , & remoteInboundRTPStreamStats )
if err != nil {
return RemoteInboundRTPStreamStats { } , fmt . Errorf ( "unmarshal remote inbound rtp stream stats: %w" , err )
}
return remoteInboundRTPStreamStats , nil
}
2022-03-10 09:44:48 +00:00
// 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 StatsType
Type 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" `
}
2024-06-05 20:10:03 +00:00
func ( s RemoteOutboundRTPStreamStats ) statsMarker ( ) { }
func unmarshalRemoteOutboundRTPStreamStats ( b [ ] byte ) ( RemoteOutboundRTPStreamStats , error ) {
var remoteOutboundRTPStreamStats RemoteOutboundRTPStreamStats
err := json . Unmarshal ( b , & remoteOutboundRTPStreamStats )
if err != nil {
return RemoteOutboundRTPStreamStats { } , fmt . Errorf ( "unmarshal remote outbound rtp stream stats: %w" , err )
}
return remoteOutboundRTPStreamStats , nil
}
2022-03-10 09:44:48 +00:00
// 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 StatsType
Type 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" `
}
2024-06-05 20:10:03 +00:00
func ( s RTPContributingSourceStats ) statsMarker ( ) { }
func unmarshalCSRCStats ( b [ ] byte ) ( RTPContributingSourceStats , error ) {
var csrcStats RTPContributingSourceStats
err := json . Unmarshal ( b , & csrcStats )
if err != nil {
return RTPContributingSourceStats { } , fmt . Errorf ( "unmarshal csrc stats: %w" , err )
}
return csrcStats , 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 StatsType
Type 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 ( s AudioSourceStats ) statsMarker ( ) { }
// 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 StatsType
Type 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 ( s VideoSourceStats ) statsMarker ( ) { }
func unmarshalMediaSourceStats ( b [ ] byte ) ( Stats , error ) {
type kindJSON struct {
Kind string ` json:"kind" `
}
kindHolder := kindJSON { }
err := json . Unmarshal ( b , & kindHolder )
if err != nil {
return nil , fmt . Errorf ( "unmarshal json kind: %w" , err )
}
switch MediaKind ( kindHolder . Kind ) {
case MediaKindAudio :
var mediaSourceStats AudioSourceStats
err := json . Unmarshal ( b , & mediaSourceStats )
if err != nil {
return nil , fmt . Errorf ( "unmarshal audio source stats: %w" , err )
}
return mediaSourceStats , nil
case MediaKindVideo :
var mediaSourceStats VideoSourceStats
err := json . Unmarshal ( b , & mediaSourceStats )
if err != nil {
return nil , fmt . Errorf ( "unmarshal video source stats: %w" , err )
}
return mediaSourceStats , nil
default :
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 StatsType
Type 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 ( s AudioPlayoutStats ) statsMarker ( ) { }
func unmarshalMediaPlayoutStats ( b [ ] byte ) ( Stats , error ) {
var audioPlayoutStats AudioPlayoutStats
err := json . Unmarshal ( b , & audioPlayoutStats )
if err != nil {
return nil , fmt . Errorf ( "unmarshal audio playout stats: %w" , err )
}
return audioPlayoutStats , nil
}
2022-03-10 09:44:48 +00:00
// 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 StatsType
Type 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" `
}
2024-06-05 20:10:03 +00:00
func ( s PeerConnectionStats ) statsMarker ( ) { }
func unmarshalPeerConnectionStats ( b [ ] byte ) ( PeerConnectionStats , error ) {
var pcStats PeerConnectionStats
err := json . Unmarshal ( b , & pcStats )
if err != nil {
return PeerConnectionStats { } , fmt . Errorf ( "unmarshal pc stats: %w" , err )
}
return pcStats , nil
}
2022-03-10 09:44:48 +00:00
// 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 StatsType
Type 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" `
}
2024-06-05 20:10:03 +00:00
func ( s DataChannelStats ) statsMarker ( ) { }
func unmarshalDataChannelStats ( b [ ] byte ) ( DataChannelStats , error ) {
var dataChannelStats DataChannelStats
err := json . Unmarshal ( b , & dataChannelStats )
if err != nil {
return DataChannelStats { } , fmt . Errorf ( "unmarshal data channel stats: %w" , err )
}
return dataChannelStats , nil
}
2022-03-10 09:44:48 +00:00
// 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 StatsType
Type 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 MediaStream
StreamIdentifier 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" `
}
2024-06-05 20:10:03 +00:00
func ( s MediaStreamStats ) statsMarker ( ) { }
func unmarshalStreamStats ( b [ ] byte ) ( MediaStreamStats , error ) {
var streamStats MediaStreamStats
err := json . Unmarshal ( b , & streamStats )
if err != nil {
return MediaStreamStats { } , fmt . Errorf ( "unmarshal stream stats: %w" , err )
}
return streamStats , nil
}
2022-03-10 09:44:48 +00:00
// 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 StatsType
Type 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" `
2024-06-05 20:10:03 +00:00
// Kind is "audio"
2022-03-10 09:44:48 +00:00
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" `
}
2024-06-05 20:10:03 +00:00
func ( s AudioSenderStats ) statsMarker ( ) { }
2022-03-10 09:44:48 +00:00
// 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 AudioSenderStats
2024-06-05 20:10:03 +00:00
func ( s SenderAudioTrackAttachmentStats ) statsMarker ( ) { }
2022-03-10 09:44:48 +00:00
// 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 StatsType
Type 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" `
2024-06-05 20:10:03 +00:00
// Kind is "video"
Kind string ` json:"kind" `
2022-03-10 09:44:48 +00:00
// 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" `
}
2024-06-05 20:10:03 +00:00
func ( s VideoSenderStats ) statsMarker ( ) { }
2022-03-10 09:44:48 +00:00
// 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 VideoSenderStats
2024-06-05 20:10:03 +00:00
func ( s SenderVideoTrackAttachmentStats ) statsMarker ( ) { }
func unmarshalSenderStats ( b [ ] byte ) ( Stats , error ) {
type kindJSON struct {
Kind string ` json:"kind" `
}
kindHolder := kindJSON { }
err := json . Unmarshal ( b , & kindHolder )
if err != nil {
return nil , fmt . Errorf ( "unmarshal json kind: %w" , err )
}
switch MediaKind ( kindHolder . Kind ) {
case MediaKindAudio :
var senderStats AudioSenderStats
err := json . Unmarshal ( b , & senderStats )
if err != nil {
return nil , fmt . Errorf ( "unmarshal audio sender stats: %w" , err )
}
return senderStats , nil
case MediaKindVideo :
var senderStats VideoSenderStats
err := json . Unmarshal ( b , & senderStats )
if err != nil {
return nil , fmt . Errorf ( "unmarshal video sender stats: %w" , err )
}
return senderStats , nil
default :
return nil , fmt . Errorf ( "kind: %w" , ErrUnknownType )
}
}
func unmarshalTrackStats ( b [ ] byte ) ( Stats , error ) {
type kindJSON struct {
Kind string ` json:"kind" `
}
kindHolder := kindJSON { }
err := json . Unmarshal ( b , & kindHolder )
if err != nil {
return nil , fmt . Errorf ( "unmarshal json kind: %w" , err )
}
switch MediaKind ( kindHolder . Kind ) {
case MediaKindAudio :
var trackStats SenderAudioTrackAttachmentStats
err := json . Unmarshal ( b , & trackStats )
if err != nil {
return nil , fmt . Errorf ( "unmarshal audio track stats: %w" , err )
}
return trackStats , nil
case MediaKindVideo :
var trackStats SenderVideoTrackAttachmentStats
err := json . Unmarshal ( b , & trackStats )
if err != nil {
return nil , fmt . Errorf ( "unmarshal video track stats: %w" , err )
}
return trackStats , nil
default :
return nil , fmt . Errorf ( "kind: %w" , ErrUnknownType )
}
}
2022-03-10 09:44:48 +00:00
// 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 StatsType
Type 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" `
2024-06-05 20:10:03 +00:00
// Kind is "audio"
Kind string ` json:"kind" `
2022-03-10 09:44:48 +00:00
// 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.EstimatedPlayoutTimestamp
EstimatedPlayoutTimestamp 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" `
}
2024-06-05 20:10:03 +00:00
func ( s AudioReceiverStats ) statsMarker ( ) { }
2022-03-10 09:44:48 +00:00
// 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 StatsType
Type 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" `
2024-06-05 20:10:03 +00:00
// Kind is "video"
Kind string ` json:"kind" `
2022-03-10 09:44:48 +00:00
// 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.EstimatedPlayoutTimestamp
EstimatedPlayoutTimestamp 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" `
}
2024-06-05 20:10:03 +00:00
func ( s VideoReceiverStats ) statsMarker ( ) { }
func unmarshalReceiverStats ( b [ ] byte ) ( Stats , error ) {
type kindJSON struct {
Kind string ` json:"kind" `
}
kindHolder := kindJSON { }
err := json . Unmarshal ( b , & kindHolder )
if err != nil {
return nil , fmt . Errorf ( "unmarshal json kind: %w" , err )
}
switch MediaKind ( kindHolder . Kind ) {
case MediaKindAudio :
var receiverStats AudioReceiverStats
err := json . Unmarshal ( b , & receiverStats )
if err != nil {
return nil , fmt . Errorf ( "unmarshal audio receiver stats: %w" , err )
}
return receiverStats , nil
case MediaKindVideo :
var receiverStats VideoReceiverStats
err := json . Unmarshal ( b , & receiverStats )
if err != nil {
return nil , fmt . Errorf ( "unmarshal video receiver stats: %w" , err )
}
return receiverStats , nil
default :
return nil , fmt . Errorf ( "kind: %w" , ErrUnknownType )
}
}
2022-03-10 09:44:48 +00:00
// 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 StatsType
Type 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 "transport".
ICERole ICERole ` json:"iceRole" `
// DTLSState is set to the current value of the "state" attribute of the underlying DTLSTransport.
DTLSState DTLSTransportState ` json:"dtlsState" `
// 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" `
}
2024-06-05 20:10:03 +00:00
func ( s TransportStats ) statsMarker ( ) { }
func unmarshalTransportStats ( b [ ] byte ) ( TransportStats , error ) {
var transportStats TransportStats
err := json . Unmarshal ( b , & transportStats )
if err != nil {
return TransportStats { } , fmt . Errorf ( "unmarshal transport stats: %w" , err )
}
return transportStats , nil
}
2022-03-10 09:44:48 +00:00
// StatsICECandidatePairState is the state of an ICE candidate pair used in the
// ICECandidatePairStats object.
type StatsICECandidatePairState string
func toStatsICECandidatePairState ( state ice . CandidatePairState ) ( StatsICECandidatePairState , error ) {
switch state {
case ice . CandidatePairStateWaiting :
return StatsICECandidatePairStateWaiting , nil
case ice . CandidatePairStateInProgress :
return StatsICECandidatePairStateInProgress , nil
case ice . CandidatePairStateFailed :
return StatsICECandidatePairStateFailed , nil
case ice . CandidatePairStateSucceeded :
return StatsICECandidatePairStateSucceeded , nil
default :
// NOTE: this should never happen[tm]
err := fmt . Errorf ( "%w: %s" , errStatsICECandidateStateInvalid , state . String ( ) )
return StatsICECandidatePairState ( "Unknown" ) , err
}
}
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 StatsType
Type 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 set
Nominated 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" `
// LastResponseTimestamp represents the timestamp at which the last STUN response
// was received on this particular candidate pair.
LastResponseTimestamp StatsTimestamp ` json:"lastResponseTimestamp" `
// 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" `
}
2024-06-05 20:10:03 +00:00
func ( s ICECandidatePairStats ) statsMarker ( ) { }
func unmarshalICECandidatePairStats ( b [ ] byte ) ( ICECandidatePairStats , error ) {
var iceCandidatePairStats ICECandidatePairStats
err := json . Unmarshal ( b , & iceCandidatePairStats )
if err != nil {
return ICECandidatePairStats { } , fmt . Errorf ( "unmarshal ice candidate pair stats: %w" , err )
}
return iceCandidatePairStats , nil
}
2022-03-10 09:44:48 +00:00
// 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 StatsType
Type 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.
2024-06-05 20:10:03 +00:00
//
// DEPRECATED. Although it may still work in some browsers, the networkType property was deprecated for
// preserving privacy.
NetworkType NetworkType ` json:"networkType,omitempty" `
2022-03-10 09:44:48 +00:00
// 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" `
}
2024-06-05 20:10:03 +00:00
func ( s ICECandidateStats ) statsMarker ( ) { }
func unmarshalICECandidateStats ( b [ ] byte ) ( ICECandidateStats , error ) {
var iceCandidateStats ICECandidateStats
err := json . Unmarshal ( b , & iceCandidateStats )
if err != nil {
return ICECandidateStats { } , fmt . Errorf ( "unmarshal ice candidate stats: %w" , err )
}
return iceCandidateStats , nil
}
2022-03-10 09:44:48 +00:00
// 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 StatsType
Type 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" `
}
2024-06-05 20:10:03 +00:00
func ( s CertificateStats ) statsMarker ( ) { }
func unmarshalCertificateStats ( b [ ] byte ) ( CertificateStats , error ) {
var certificateStats CertificateStats
err := json . Unmarshal ( b , & certificateStats )
if err != nil {
return CertificateStats { } , fmt . Errorf ( "unmarshal certificate stats: %w" , err )
}
return certificateStats , 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 StatsType
Type 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 SCTPTransport
BytesSent uint64 ` json:"bytesSent" `
// BytesReceived represents the total number of bytes received on this SCTPTransport
BytesReceived uint64 ` json:"bytesReceived" `
}
func ( s SCTPTransportStats ) statsMarker ( ) { }
func unmarshalSCTPTransportStats ( b [ ] byte ) ( SCTPTransportStats , error ) {
var sctpTransportStats SCTPTransportStats
if err := json . Unmarshal ( b , & sctpTransportStats ) ; err != nil {
return SCTPTransportStats { } , fmt . Errorf ( "unmarshal sctp transport stats: %w" , err )
}
return sctpTransportStats , nil
}