Client-Beobachtbarkeit: iOS (Swift)

Das Vonage Video SDK stellt detaillierte Metriken zur Stream-Qualität über eine High-Level-Statistik-API zur Verfügung, die für die meisten Anwendungsfälle empfohlen wird und die Audio-, Video-, Netzwerk- und Absenderstatistiken in einer einheitlichen, sitzungsspezifischen Form bereitstellt, die über Peer-Verbindungsübergänge hinweg stabil bleibt. Für fortgeschrittenes Debugging bietet das SDK auch Zugriff auf den rohen WebRTC-Statistikbericht, der unverarbeitete Peer-Verbindungsdaten wiedergibt.

Das SDK stellt auch Netzwerkzustandsmetriken zur Verfügung, die eine umfassende Bewertung des Verbindungszustands sowohl für Herausgeber als auch für Abonnenten ermöglichen. Diese Metriken umfassen eine Bewertung des Netzwerkzustands, den Grund für diese Bewertung und - für Abonnenten - eine Verschlechterungsquelle, die angibt, welche Seite der Verbindung für die beobachteten Probleme verantwortlich ist. Siehe Netzzustand und Ursache der Verschlechterung für Einzelheiten.

Das Vonage Video iOS SDK sendet regelmäßig Audio-, Video- und Media-Link-Statistiken sowohl für Publisher als auch für Abonnenten. Dazu gehören die Anzahl der Pakete, Bitraten, Frame-Rate-Daten, Pausen-/Freeze-Metriken, Codec-Informationen und Netzwerkmetriken auf Transportebene, wie z. B. Bandbreitenschätzung und Netzwerkzustandsbewertung.

Die Statistiken werden durch geliefert:

  • OTPublisherKitNetworkStatsDelegate - Statistiken auf der Verlagsseite (Audio, Video)

  • OTSubscriberKitNetworkStatsDelegate - Statistiken auf der Abonnentenseite (Audio, Video)

Um sie zu empfangen, aktivieren Sie den entsprechenden Delegaten auf dem Verleger oder Abonnenten.

Aktivieren von Statistiken für Verleger

Fügen Sie eine Klasse hinzu, die das OTPublisherKitNetworkStatsDelegate übernimmt:

class MyViewController: UIViewController, OTPublisherKitDelegate, OTPublisherKitNetworkStatsDelegate {
    var publisher: OTPublisher?

    func setupPublisher() {
        let settings = OTPublisherSettings()
        // Configure settings as needed
        publisher = OTPublisher(delegate: self, settings: settings)
        publisher?.networkStatsDelegate = self
    }
}

Implementieren Sie die Rückrufe:

func publisher(_ publisher: OTPublisherKit, videoNetworkStatsUpdated stats: [OTPublisherKitVideoNetworkStats]) {
    let first = stats.first

    // For routed sessions, stats.first is enough.
    // For relayed sessions (one object per subscriber), you would iterate all elements.
    let connectionId = first.connectionId.isEmpty ? "<none>" : first.connectionId
    let subscriberId = first.subscriberId.isEmpty ? "<none>" : first.subscriberId

    print("Publisher Video Stats for connectionId: \(connectionId), subscriberId: \(subscriberId)")
    print("Video bytes sent: \(first.videoBytesSent)")
    print("Video packets sent: \(first.videoPacketsSent)")
    print("Video packets lost: \(first.videoPacketsLost)")
    print("Current average frame rate: \(first.videoFrameRate) fps")

    for layer in first.videoLayers {
        print("Layer: \(layer.width)x\(layer.height)")
        print("  Encoded FPS: \(layer.encodedFrameRate)")
        print("  Bitrate: \(layer.bitrate) bps")
        print("  Total bitrate (incl. RTP overhead): \(layer.totalBitrate) bps")
        print("  Codec: \(layer.codec ?? "<none>")")
        print("  Scalability mode: \(layer.scalabilityMode ?? "<none>")")
        print("  Quality limitation: \(layer.qualityLimitationReason.rawValue)")
    }

}

func publisher(_ publisher: OTPublisherKit, audioNetworkStatsUpdated stats: [OTPublisherKitAudioNetworkStats]) {
    let first = stats.first

    // For routed sessions, stats.first is enough.
    // For relayed sessions (one object per subscriber), you would iterate all elements.
    let connectionId = first.connectionId.isEmpty ? "<none>" : first.connectionId
    let subscriberId = first.subscriberId.isEmpty ? "<none>" : first.subscriberId

    print("Publisher Audio Stats for connectionId: \(connectionId), subscriberId: \(subscriberId)")
    print("Audio bytes sent: \(first.audioBytesSent)")
    print("Audio packets sent: \(first.audioPacketsSent)")
    print("Audio packets lost: \(first.audioPacketsLost)")
}

func publisher(_ publisher: OTPublisherKit, mediaLinkStatsUpdated mediaLinkStats: [OTPublisherKitMediaLinkStats]) {
    if let stats = mediaLinkStats.first {
        print("Publisher uplink bandwidth: \(stats.transport.connectionEstimatedBandwidth) bps")
        print("Network condition: \(stats.transport.networkCondition.rawValue)")
        print("Condition reason: \(stats.transport.networkConditionReason.rawValue)")
    }
}

Für einen Verleger in einer gerouteten Sitzung (eine, die die Vonage Video-Media-Router), enthält das Array stats ein Objekt, das die Statistiken für den einzelnen Audio- oder Video-Medienstrom, der an den Vonage Video Media Router gesendet wird. In einer weitergeleiteten Sitzung enthält das stats-Array ein Objekt für jeden Teilnehmer des des veröffentlichten Streams.

Empfang von Videoqualitätsereignissen bei den Herausgebern

Wenn Sie auch an Videoqualitätsereignissen interessiert sind, implementieren Sie diesen Callback:

func publisher(_ publisher: OTPublisherKit, videoQualityChanged stats: OTPublisherKitVideoNetworkStats, reason: OTPublisherVideoEventReason) {
    print("Publisher video quality event: \(reason.rawValue)")
}

Empfang von Netzwerkzustandsereignissen auf den Publishern

Um Ereignisse zur Änderung von Netzwerkbedingungen für den Herausgeber zu empfangen, implementieren Sie die publisher(_:networkConditionChanged:mediaLinkStats:reason:) Rückruf:

func publisher(_ publisher: OTPublisherKit, networkConditionChanged mediaLinkStats: OTPublisherKitMediaLinkStats, reason: OTNetworkReason) {
    if let transport = mediaLinkStats.transport {
        print("Publisher network condition changed: \(transport.networkCondition.rawValue)")
        print("Reason: \(transport.networkConditionReason.rawValue)")
    }
}

Dieser Rückruf wird ausgelöst, wenn eine signifikante Änderung der Netzbedingungen für den Herausgeber festgestellt wird. Er enthält die aktuelle Medienverbindungsstatistik mit Transportmetriken. Siehe Netzzustand und Ursache der Verschlechterung für Einzelheiten zur Interpretation der Netzzustandsnoten und Gründe.

Aktivieren von Statistiken für Abonnenten

Anhängen einer Klasse, die die OTSubscriberKitNetworkStatsDelegate:

class MyViewController: UIViewController, OTSubscriberKitDelegate, OTSubscriberKitNetworkStatsDelegate {
    var subscriber: OTSubscriber?

    func setupSubscriber(stream: OTStream, session: OTSession) {
        subscriber = OTSubscriber(stream: stream, delegate: self)
        subscriber?.networkStatsDelegate = self
        try? session.subscribe(subscriber!)
    }
}

Implementieren Sie die Rückrufe:

func subscriber(_ subscriber: OTSubscriberKit, videoNetworkStatsUpdated stats: OTSubscriberKitVideoNetworkStats) {
    print("Video bytes received: \(stats.videoBytesReceived)")
}

func subscriber(_ subscriber: OTSubscriberKit, audioNetworkStatsUpdated stats: OTSubscriberKitAudioNetworkStats) {
    print("Audio packets received: \(stats.audioPacketsReceived)")
}

func subscriber(_ subscriber: OTSubscriberKit, mediaLinkStatsUpdated mediaLinkStats: OTSubscriberKitMediaLinkStats) {
    print("Local downlink bandwidth: \(mediaLinkStats.transport.connectionEstimatedBandwidth) bps")
    print("Remote publisher uplink bandwidth: \(mediaLinkStats.remotePublisherTransport.connectionEstimatedBandwidth) bps")
    print("Degradation source: \(mediaLinkStats.networkDegradationSource.rawValue)")
}

Empfang von Videoqualitätsereignissen bei den Abonnenten

Zusätzlich können Sie Ereignisse mit geänderter Videoqualität für Abonnenten behandeln:

func subscriber(_ subscriber: OTSubscriberKit, videoQualityChanged stats: OTSubscriberKitVideoNetworkStats, reason: OTSubscriberVideoEventReason) {
    print("Subscriber video quality event: \(reason.rawValue)")
}

Empfang von Netzwerkzustandsereignissen bei den Teilnehmern

Um Ereignisse zur Änderung von Netzbedingungen für den Teilnehmer zu empfangen, implementieren Sie die subscriber(_:networkConditionChanged:mediaLinkStats:reason:) Rückruf:

func subscriber(_ subscriber: OTSubscriberKit, networkConditionChanged mediaLinkStats: OTSubscriberKitMediaLinkStats, reason: OTNetworkReason) {
    if let transport = mediaLinkStats.transport {
        print("Local network condition: \(transport.networkCondition.rawValue)")
    }
    if let remoteTransport = mediaLinkStats.remotePublisherTransport {
        print("Remote publisher network condition: \(remoteTransport.networkCondition.rawValue)")
    }
    print("Degradation source: \(mediaLinkStats.networkDegradationSource.rawValue)")
}

Dieser Rückruf wird ausgelöst, wenn eine signifikante Änderung der Netzbedingungen für den Teilnehmer oder den entfernten Herausgeber festgestellt wird. Er enthält die aktuelle Medienverbindungsstatistik mit lokalen und entfernten Transportmetriken und der Degradationsquelle. Siehe Netzzustand und Ursache der Verschlechterung für Einzelheiten zur Interpretation der Netzzustandsnoten und Gründe.

Statistik-Datenstrukturen

In diesem Abschnitt werden die Strukturen und Eigenschaften beschrieben, die von der iOS-Audio- und Videostatistik-API bereitgestellt werden. Während alle Video-SDK-Plattformen denselben Satz von Statistiken bereitstellen, kann es geringfügige Unterschiede in der Strukturierung oder Benennung einzelner Felder auf den einzelnen Plattformen geben. Diese Unterschiede spiegeln eher plattformspezifische SDK-Designkonventionen als Unterschiede in den zugrunde liegenden Metriken wider.

Eine plattformunabhängige Erläuterung der verfügbaren Statistiken und ihrer Bedeutung finden Sie unter Übersicht über die Beobachtbarkeit der Kunden.

OTTransportStats

Stellt gemeinsame Metriken auf Transportebene dar.

  • connectionEstimatedBandwidth - Geschätzte verfügbare Verbindungsbandbreite (bps).
  • networkCondition - Aktuelle Netzzustandsbewertung (OTNetworkConditionUnknown, OTNetworkConditionCritical, OTNetworkConditionWarning, OTNetworkConditionFair, OTNetworkConditionGood, oder OTNetworkConditionExcellent).
  • networkConditionReason - Hauptgrund für die Beeinträchtigung des Netzzustandes (OTNetworkReasonNone, OTNetworkReasonUnknown, OTNetworkReasonBandwidth, oder OTNetworkReasonPacketLoss).

OTPublisherKitVideoNetworkStats

Liefert Statistiken über die Videospur eines Herausgebers. Sie umfasst:

  • connectionId - In einer weitergeleiteten Sitzung die Verbindungs-ID des Clients, der den Stream abonniert. Undefiniert in einer gerouteten Sitzung.
  • subscriberId - In einer weitergeleiteten Sitzung die abonnierte ID des Clients, der den Stream abonniert. Undefiniert in einer gerouteten Sitzung.
  • videoPacketsLost - Geschätzte verlorene Videopakete.
  • videoPacketsSent - Gesendete Videopakete.
  • videoBytesSent - Video-Bytes gesendet.
  • timestamp - Unix-Zeitstempel in Millisekunden, als die Statistiken erfasst wurden.
  • startTime - Der Zeitstempel in Millisekunden seit der Unix-Epoche, ab dem die kumulativen Summen zu kumulieren begannen.
  • videoLayers - Das Array der Video-Layer-Statistiken (siehe OTPublisherKitVideoLayerStats).
  • transport - Verkehrsstatistik.

OTPublisherKitAudioNetworkStats

Liefert Statistiken über den Audiotrack eines Verlags. Sie umfasst:

  • connectionId - In einer weitergeleiteten Sitzung die Verbindungs-ID des Clients, der den Stream abonniert. Undefiniert in einer gerouteten Sitzung.
  • subscriberId - In einer weitergeleiteten Sitzung die abonnierte ID des Clients, der den Stream abonniert. Undefiniert in einer gerouteten Sitzung.
  • audioPacketsLost - Geschätzte verlorene Pakete.
  • audioPacketsSent - Audio-Pakete gesendet.
  • audioBytesSent - Gesendete Audio-Bytes.
  • timestamp - Unix-Zeitstempel in Millisekunden.
  • startTime - Der Zeitstempel in Millisekunden seit der Unix-Epoche, ab dem die kumulativen Summen zu kumulieren begannen.
  • transport - Verkehrsstatistik.

OTPublisherKitVideoLayerStats

Steht für eine Simulcast- oder SVC-Schicht.

  • width - Kodierte Bildbreite.
  • height - Kodierte Rahmenhöhe.
  • encodedFrameRate - Kodierte Bilder pro Sekunde.
  • bitrate - Bitrate der Schicht (bps).
  • totalBitrate - Bitrate der Schicht einschließlich RTP-Overhead (bps).
  • scalabilityMode - SVC/Skalierbarkeitsdeskriptor (z. B. "L3T3").
  • qualityLimitationReason - Grund für die Qualitätseinschränkung (Bandbreite, CPU, Codec, Auflösung oder Ebenenwechsel).
  • codec - Der von dieser Videoebene verwendete Codec.

OTSenderStats

Abschätzungsmetriken auf der Senderseite (gespiegelt auf Audio und Video).

  • connectionMaxAllocatedBitrate - Geschätzte maximale Bitrate für die Senderverbindung.
  • connectionEstimatedBandwidth - Aktuelle Bandbreitenabschätzung (bps).

OTSubscriberKitVideoNetworkStats

Liefert Statistiken über die Videospur eines Abonnenten. Sie umfasst:

  • videoPacketsLost - Geschätzte verlorene Videopakete.
  • videoPacketsReceived - Empfangene Videopakete.
  • videoBytesReceived - Empfangene Videobytes.
  • timestamp - Unix-Zeitstempel in Millisekunden, als die Statistiken erfasst wurden.
  • senderStats - Metriken auf der Absenderseite (optional).
  • width - Dekodierte Bildbreite in Pixel.
  • height - Dekodierte Bildhöhe in Pixel.
  • decodedFrameRate - Dekodierte Bilder pro Sekunde.
  • bitrate - Video-Bitrate (bps).
  • totalBitrate - Bitrate einschließlich RTP-Overhead (bps).
  • pauseCount - Numbers of pauses (>5s seit dem letzten Frame). Einschließlich absichtlicher Deaktivierungen und Audio-Fallback-Fälle.
  • totalPausesDuration - Gesamte Pausendauer (ms).
  • freezeCount - Freeze Count (von WebRTC definiertes Freeze-Ereignis).
  • totalFreezesDuration - Gesamtdauer des Einfrierens (ms).
  • codec - Aktueller Decoder-Codec.

OTSubscriberKitAudioNetworkStats

Liefert Statistiken über den Audiotrack eines Abonnenten. Sie umfasst:

  • audioPacketsLost - Geschätzte verlorene Pakete.
  • audioPacketsReceived - Empfangene Pakete.
  • audioBytesReceived - Empfangene Bytes.
  • timestamp - Unix-Zeitstempel in Millisekunden.
  • senderStats - Metriken auf der Absenderseite (optional).

OTPublisherKitMediaLinkStats

Liefert Statistiken auf Transportebene für die Verbindungen eines Verlags.

  • transport - Transportstatistiken für die Uplink-Verbindung dieses Verlags (siehe OTTransportStats)

OTSubscriberKitMediaLinkStats

Liefert Statistiken auf Transportebene für die Verbindungen eines Teilnehmers, einschließlich Einblick in die Netzwerkleistung des entfernten Herausgebers. So können Applications diagnostizieren, ob Verbindungsprobleme vom Downlink des Teilnehmers oder vom Uplink des Publishers ausgehen.

  • transport - Transportstatistiken für die Downlink-Verbindung dieses Teilnehmers (siehe OTTransportStats)
  • remotePublisherTransport - Transportstatistiken für die Uplink-Verbindung des entfernten Herausgebers (erhalten über Statistik der Absender-Seitesiehe OTTransportStats). Diese Statistiken können eingeschränkt sein, wenn die absenderseitigen Statistiken nicht aktiviert sind.
  • networkDegradationSource - Zeigt die Quelle der Netzverschlechterung an (OTNetworkDegradationSourceLocal, OTNetworkDegradationSourceRemote, OTNetworkDegradationSourceBothOrUnclear, oder OTNetworkDegradationSourceUnknown)

Statistik auf der Absenderseite

Siehe die Übersicht der Absenderstatistiken.

Aktivieren der absenderseitigen Statistik

Senderstatistiken werden von den Abonnenten empfangen. Um absenderseitige Statistiken zu erhalten, aktivieren Sie sie für den Herausgeber des Streams, indem Sie die Option senderStatsTrack Eigenschaft zu true für die OTPublisherKitSettings Objekt, das zur Erstellung des Verlags verwendet wird.

let settings = OTPublisherKitSettings()
settings.senderStatsTrack = true

let publisher = OTPublisher(delegate: self, settings: settings)

Wenn senderStatsTrack nicht aktiviert ist, wird kein Absenderstatistikkanal für diesen Verlag veröffentlicht. Der Standardwert ist NO.

Empfangen von absenderseitigen Statistiken

Wenn der Herausgeber die Absenderstatistik aktiviert hat, erhalten die Abonnenten diese automatisch über die OTSubscriberKitNetworkStatsDelegate Rückrufe oben beschrieben. Die senderStats Eigenschaft auf beiden OTSubscriberKitVideoNetworkStats und OTSubscriberKitAudioNetworkStats liefert zwei Metriken:

  • connectionMaxAllocatedBitrate - Die maximale Bitrate, die für die Verbindung geschätzt werden kann
  • connectionEstimatedBandwidth - Die aktuell geschätzte Bandbreite für die Verbindung

Diese Metriken werden pro Audio-Video-Bündel berechnet, so dass in den Video- und Audiostatistiken dieselben Werte erscheinen.

func subscriber(_ subscriber: OTSubscriberKit, videoNetworkStatsUpdated stats: OTSubscriberKitVideoNetworkStats) {
    if let sender = stats.senderStats {
        print("Connection max allocated bitrate: \(sender.connectionMaxAllocatedBitrate)")
        print("Connection current estimated bandwidth: \(sender.connectionEstimatedBandwidth)")
    }
}

Netzzustand und Verschlechterung Quelle

Das SDK liefert sowohl für Publisher als auch für Abonnenten Echtzeit-Netzwerkzustandsmetriken, einschließlich einer Zustandsbewertung, des Grundes für diese Bewertung und einer Verschlechterungsquelle für Abonnenten. Eine vollständige Erläuterung des Netzwerkzustandsmodells, der Bewertungen, der Gründe und der Aktivierung finden Sie in der Übersicht über die Beobachtbarkeit der Kunden.

Netzzustandsdaten sind über zwei Kanäle verfügbar:

  • Regelmäßige Statistiken: Die transport Eigenschaft von Publisher- und Subscriber-Stats-Objekten umfasst networkCondition und networkConditionReason. Die Abonnentenstatistiken geben auch Aufschluss über remotePublisherTransport und networkDegradationSource. Siehe Strukturen der Statistik für Einzelheiten.
  • Ereignisse, bei denen sich der Netzzustand ändert: Dedizierte Rückrufe auf beiden Herausgeber und Teilnehmer werden ausgelöst, wenn eine signifikante Änderung der Netzbedingungen festgestellt wird.

Das folgende Beispiel zeigt, wie die Daten über den Zustand des Teilnehmernetzes verwendet werden können, um die Ursache der Verschlechterung zu ermitteln:

func subscriber(_ subscriber: OTSubscriberKit, networkConditionChanged videoStats: OTSubscriberKitVideoNetworkStats, audioStats: OTSubscriberKitAudioNetworkStats, reason: OTNetworkReason) {

    let localCondition = videoStats.transport?.networkCondition ?? .unknown
    let remoteCondition = videoStats.remotePublisherTransport?.networkCondition ?? .unknown
    let source = videoStats.networkDegradationSource

    switch source {
    case .local:
        print("Local network is degraded (condition: \(localCondition.rawValue))")
    case .remote:
        print("Remote publisher network is degraded (condition: \(remoteCondition.rawValue))")
    case .bothOrUnclear:
        print("Degradation source unclear — local: \(localCondition.rawValue), remote: \(remoteCondition.rawValue)")
    default:
        break
    }
}

RTC-Statistikbericht

Um Low-Level-Stream-Statistiken zu erhalten, verwenden Sie die getRtcStatsReport() Methode auf OTPublisherKit. Dadurch werden RTC-Statistikberichte für den Medienstrom asynchron bereitgestellt.

Bevor Sie diese Methode aufrufen, setzen Sie die rtcStatsReportDelegate Eigenschaft Ihres Verlegers und implementieren Sie die Delegate-Methode publisher(_:rtcStatsReport:) von OTPublisherKitRtcStatsReportDelegate. Wenn die Statistiken verfügbar sind, wird diese Methode mit einem Array von OTPublisherRtcStats Objekte. Jedes Objekt enthält eine jsonArrayOfReports Eigenschaft, bei der es sich um ein JSON-Array mit RTC-Statistiken handelt, die dem von WebRTC in Webbrowsern verwendeten Format ähneln.

Beispiel

class MyViewController: UIViewController, OTPublisherKitRtcStatsReportDelegate {
    var publisher: OTPublisher?

    func setupPublisher() {
        // Create and configure the publisher
        publisher = OTPublisher(delegate: self, settings: OTPublisherKitSettings())
        publisher?.rtcStatsReportDelegate = self
    }

    func fetchRtcStats() {
        publisher?.getRtcStatsReport()
    }

    // Delegate method called when stats are ready
    func publisher(_ publisher: OTPublisherKit, rtcStatsReport stats: [OTPublisherRtcStats]) {
        for stat in stats {
            print("RTC Stats JSON: \(stat.jsonArrayOfReports)")
        }
    }
}

Siehe diese Mozilla-Dokumente. Siehe auch diese W3C-Dokumentation.

Muster

Die Vonage Video iOS SDK Client SDK Beobachtbarkeit Beispielanwendung demonstriert die Funktionen zur Beobachtung von Clients in einer mobilen Anwendung, die mit dem iOS Client SDK erstellt wurde.