Observabilidad del cliente: iOS (Swift)

El SDK de video de Vonage expone métricas detalladas de la calidad de la transmisión a través de una API de estadísticas de alto nivel, recomendada para la mayoría de los casos de uso, que proporciona estadísticas de audio, video, red y del lado del emisor en una forma unificada y consciente de la sesión que permanece estable a través de las transiciones de conexión entre pares. Para la depuración avanzada, el SDK también ofrece acceso al informe de estadísticas WebRTC sin procesar, que refleja los datos de la conexión entre pares sin procesar.

El SDK también proporciona métricas sobre el estado de la red que ofrecen una evaluación general del estado de la conexión, tanto para los emisores como para los suscriptores. Estas métricas incluyen una puntuación del estado de la red, el motivo que explica dicha puntuación y, en el caso de los suscriptores, una fuente de degradación que indica qué lado de la conexión es responsable de los problemas observados. Véase Estado de la red y origen de la degradación Para más información.

API de estadísticas de audio, vídeo y enlaces multimedia

El SDK de Vonage Video para iOS envía estadísticas periódicas sobre audio, vídeo y enlaces multimedia, tanto para los emisores como para los suscriptores. Entre ellas se incluyen el recuento de paquetes, las velocidades de bits, los datos sobre la frecuencia de fotogramas, las métricas de pausa y congelación, la información sobre códecs y las métricas de red a nivel de transporte, como la estimación del ancho de banda y la puntuación del estado de la red.

Las estadísticas se entregan a través de:

  • OTPublisherKitNetworkStatsDelegate - estadísticas del editor (audio, vídeo)

  • OTSubscriberKitNetworkStatsDelegate — estadísticas del lado del suscriptor (audio, vídeo)

Para recibirlos, activa el delegado correspondiente en el editor o en el suscriptor.

Estadísticas para editores

Adjunta una clase que adopte OTPublisherKitNetworkStatsDelegate:

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
    }
}

Implementa las funciones de devolución de llamada:

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)")
    }
}

Para un editor en una sesión enrutada (que utiliza la función Router multimedia de vídeo de Vonage), la matriz «stats» incluye un objeto que define las estadísticas de la única secuencia multimedia de audio o vídeo que se envía al Vonage Video Media Router. En una sesión retransmitida, la matriz «stats» incluye un objeto por cada suscriptor de la secuencia publicada.

Recepción de eventos de calidad de vídeo en los editores

Si también te interesan los eventos relacionados con la calidad del vídeo, implementa esta función de devolución de llamada:

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

Recepción de eventos de estado de la red en los editores

Para recibir eventos de cambio de estado de la red para el editor, implemente la función publisher(_:networkConditionChanged:mediaLinkStats:reason:) función de devolución de llamada:

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)")
    }
}

Esta llamada de retorno se activa cuando se detecta un cambio significativo en las condiciones de la red para el editor. Incluye las estadísticas actuales del enlace multimedia con métricas de transporte. Véase Estado de la red y origen de la degradación para más detalles sobre la interpretación de las puntuaciones y razones del estado de la red.

Activar las estadísticas para abonados

Adjunta una clase que adopte 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!)
    }
}

Implementa las funciones de devolución de llamada:

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)")
}

Recepción de eventos de calidad de vídeo en los abonados

Además, gestiona los eventos relacionados con cambios en la calidad de vídeo de los suscriptores:

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

Recepción de eventos de estado de la red en los abonados

Para recibir eventos de cambio en el estado de la red del abonado, implementa el subscriber(_:networkConditionChanged:mediaLinkStats:reason:) función de devolución de llamada:

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)")
}

Esta llamada de retorno se activa cuando se detecta un cambio significativo en las condiciones de la red para el abonado o el editor remoto. Incluye las estadísticas actuales del enlace multimedia con las métricas de transporte local y remoto y la fuente de degradación. Véase Estado de la red y origen de la degradación para más detalles sobre la interpretación de las puntuaciones y razones del estado de la red.

Estadística y estructuras de datos

En esta sección se describen las estructuras y propiedades que proporciona la API de estadísticas de audio y vídeo de iOS. Aunque todas las plataformas Video SDK exponen el mismo conjunto de estadísticas, puede haber pequeñas diferencias en la forma en que cada plataforma estructura o nombra los campos individuales. Estas variaciones reflejan convenciones de diseño del SDK específicas de cada plataforma más que diferencias en las métricas subyacentes.

Para una explicación independiente de la plataforma de las estadísticas disponibles y lo que representan, consulte visión general de la observabilidad del cliente.

OTTransportStats

Representa métricas compartidas a nivel de transporte.

  • connectionEstimatedBandwidth – Ancho de banda de conexión disponible estimado (bps).
  • networkCondition – Puntuación del estado actual de la red (OTNetworkConditionUnknown, OTNetworkConditionCritical, OTNetworkConditionWarning, OTNetworkConditionFair, OTNetworkConditionGood, o OTNetworkConditionExcellent).
  • networkConditionReason - Razón principal que afecta al estado de la red (OTNetworkReasonNone, OTNetworkReasonUnknown, OTNetworkReasonBandwidth, o OTNetworkReasonPacketLoss).

OTPublisherKitVideoNetworkStats

Proporciona estadísticas sobre la trayectoria de los vídeos de un editor. Incluye:

  • connectionId - En una sesión retransmitida, el identificador de conexión del cliente que se suscribe al flujo. No definido en una sesión enrutada.
  • subscriberId - En una sesión retransmitida, el ID suscrito del cliente que se suscribe al flujo. No definido en una sesión enrutada.
  • videoPacketsLost - Estimación de paquetes de vídeo perdidos.
  • videoPacketsSent - Paquetes de vídeo enviados.
  • videoBytesSent - Bytes de vídeo enviados.
  • timestamp - Marca de tiempo Unix en milisegundos cuando se recopilaron las estadísticas.
  • startTime - La marca de tiempo, en milisegundos desde la época Unix, a partir de la cual comenzaron a acumularse los totales acumulados.
  • videoLayers - La matriz de estadísticas de la capa de vídeo (véase OTPublisherKitVideoLayerStats).
  • transport – Estadísticas de transporte.

OTPublisherKitAudioNetworkStats

Ofrece estadísticas sobre la pista de audio de un editor. Incluye:

  • connectionId - En una sesión retransmitida, el identificador de conexión del cliente que se suscribe al flujo. No definido en una sesión enrutada.
  • subscriberId - En una sesión retransmitida, el ID suscrito del cliente que se suscribe al flujo. No definido en una sesión enrutada.
  • audioPacketsLost - Estimación de paquetes perdidos.
  • audioPacketsSent – Paquetes de audio enviados.
  • audioBytesSent - Bytes de audio enviados.
  • timestamp – Marca de tiempo Unix en milisegundos.
  • startTime - La marca de tiempo, en milisegundos desde la época Unix, a partir de la cual comenzaron a acumularse los totales acumulados.
  • transport – Estadísticas de transporte.

OTPublisherKitVideoLayerStats

Representa una capa de emisión simultánea o una capa SVC.

  • width - Anchura de trama codificada.
  • height – Altura del fotograma codificado.
  • encodedFrameRate – Fotogramas por segundo codificados.
  • bitrate – Velocidad de transmisión de la capa (bps).
  • totalBitrate – Velocidad de transmisión de la capa, incluida la sobrecarga de RTP (bps).
  • scalabilityMode - Descriptor SVC/escalabilidad (por ejemplo, "L3T3").
  • qualityLimitationReason - Motivo de la limitación de calidad (ancho de banda, CPU, códec, resolución o cambio de capa).
  • codec – El códec utilizado por esta capa de vídeo.

OTSenderStats

Métricas de estimación del lado del emisor (aplicadas tanto al audio como al vídeo).

  • connectionMaxAllocatedBitrate – Velocidad de transmisión máxima estimada para la conexión del remitente.
  • connectionEstimatedBandwidth – Estimación del ancho de banda actual (bps).

OTSubscriberKitVideoNetworkStats

Proporciona estadísticas sobre la pista de vídeo de un abonado. Incluye:

  • videoPacketsLost - Estimación de paquetes de vídeo perdidos.
  • videoPacketsReceived - Paquetes de vídeo recibidos.
  • videoBytesReceived - Bytes de vídeo recibidos.
  • timestamp - Marca de tiempo Unix en milisegundos cuando se recopilaron las estadísticas.
  • senderStats – Métricas del lado del remitente (opcional).
  • width - Anchura del fotograma descodificado en píxeles.
  • height – Altura del fotograma descodificado en píxeles.
  • decodedFrameRate – Fotogramas por segundo decodificados.
  • bitrate - Velocidad de bits de vídeo (bps).
  • totalBitrate - Bitrate incluyendo la sobrecarga RTP (bps).
  • pauseCount - Numbers de pausas (>5s desde el último fotograma). Incluye desactivaciones intencionadas y casos de audio-fallback.
  • totalPausesDuration - Duración total de la pausa (ms).
  • freezeCount - Recuento de congelaciones (evento de congelación definido por WebRTC).
  • totalFreezesDuration - Duración total de la congelación (ms).
  • codec - Códec decodificador actual.

OTSubscriberKitAudioNetworkStats

Proporciona estadísticas sobre la pista de audio de un abonado. Incluye:

  • audioPacketsLost - Estimación de paquetes perdidos.
  • audioPacketsReceived - Paquetes recibidos.
  • audioBytesReceived - Bytes recibidos.
  • timestamp – Marca de tiempo Unix en milisegundos.
  • senderStats – Métricas del lado del remitente (opcional).

OTPublisherKitMediaLinkStats

Proporciona estadísticas a nivel de transporte para las conexiones de un editor.

  • transport - Estadísticas de transporte para la conexión de enlace ascendente de este editor (véase OTTransportStats)

OTSubscriberKitMediaLinkStats

Proporciona estadísticas a nivel de transporte para las conexiones de un abonado, incluida la visibilidad del rendimiento de la red del editor remoto. Esto permite a las aplicaciones diagnosticar si los problemas de conexión se originan en el enlace descendente del abonado o en el enlace ascendente del editor.

  • transport — Estadísticas de tráfico de la conexión de bajada de este abonado (véase OTTransportStats)
  • remotePublisherTransport - Estadísticas de transporte de la conexión de enlace ascendente del editor remoto (obtenidas mediante estadísticas del lado del remitenteVer OTTransportStats). Estas estadísticas pueden estar limitadas si las estadísticas del lado del remitente no están activadas.
  • networkDegradationSource - Indica la fuente de degradación de la red (OTNetworkDegradationSourceLocal, OTNetworkDegradationSourceRemote, OTNetworkDegradationSourceBothOrUnclear, o OTNetworkDegradationSourceUnknown)

Estadísticas del remitente

Véase el Resumen de las estadísticas del lado del remitente.

Activación de las estadísticas del remitente

Las estadísticas del lado del emisor se reciben en los abonados. Para recibir las estadísticas del lado del emisor, habilítelas para el editor del flujo estableciendo el parámetro senderStatsTrack propiedad a true para la OTPublisherKitSettings utilizado para crear el editor.

let settings = OTPublisherKitSettings()
settings.senderStatsTrack = true

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

Si senderStatsTrack no está activado, no se publicará ningún canal de estadísticas del remitente para este editor. El valor por defecto es NO.

Recepción de estadísticas del remitente

Si el editor ha activado las estadísticas del remitente, los suscriptores las reciben automáticamente a través del OTSubscriberKitNetworkStatsDelegate funciones de devolución de llamada descrito anteriormente. En senderStats propiedad en ambos OTSubscriberKitVideoNetworkStats y OTSubscriberKitAudioNetworkStats proporciona dos métricas:

  • connectionMaxAllocatedBitrate - El bitrate máximo que puede estimarse para la conexión
  • connectionEstimatedBandwidth - El ancho de banda estimado actual para la conexión

Estas métricas se calculan por paquete de audio y vídeo, por lo que los mismos valores aparecen tanto en las estadísticas de vídeo como en las de audio.

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)")
    }
}

Estado y degradación de la red Fuente

El SDK proporciona métricas en tiempo real sobre el estado de la red tanto para los editores como para los suscriptores, incluyendo una puntuación de estado, el motivo que la determina y, en el caso de los suscriptores, la fuente de la degradación. Para obtener una explicación detallada del modelo de estado de la red, las puntuaciones, los motivos y cómo activarlo, consulta el visión general de la observabilidad del cliente.

Los datos sobre el estado de la red están disponibles a través de dos canales:

  • Estadísticas periódicas: En transport Las propiedades de los objetos de estadísticas de emisores y suscriptores incluyen networkCondition y networkConditionReason. Las estadísticas de los abonados también exponen remotePublisherTransport y networkDegradationSource. Véase Estructuras estadísticas Para más información.
  • Eventos relacionados con cambios en el estado de la red: Devoluciones de llamada dedicadas en ambos editor y suscriptor se activan cuando se detecta un cambio significativo en el estado de la red.

El siguiente ejemplo muestra cómo utilizar los datos de estado de la red del abonado para identificar la fuente de degradación:

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
    }
}

Informe de estadísticas de RTC

Para obtener estadísticas de flujo de bajo nivel, utilice la función getRtcStatsReport() método en OTPublisherKit. Esto proporciona informes estadísticos de RTC para la transmisión multimedia de forma asíncrona.

Antes de llamar a este método, configura el rtcStatsReportDelegate proiedad de tu editor e implementa el método delegado publisher(_:rtcStatsReport:) de OTPublisherKitRtcStatsReportDelegate. Cuando las estadísticas están disponibles, se llama a este método con un array de OTPublisherRtcStats objetos. Cada objeto contiene un jsonArrayOfReports propiedad, que es un array JSON de informes de estadísticas de RTC similar al formato utilizado por WebRTC en los navegadores web.

Ejemplo

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)")
        }
    }
}

Véase estos documentos de Mozilla. Véase también esta documentación del W3C.

Muestra

El Aplicación de muestra de observabilidad del Client SDK de Vonage Video para iOS muestra las funciones de observabilidad del cliente en una aplicación móvil desarrollada con el Client SDK para iOS.