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.

API de estadísticas de audio y Video

El SDK para iOS de Vonage Video envía estadísticas periódicas de la red de audio y video para editores y suscriptores. Estas incluyen recuentos de paquetes, tasas de bits, datos de velocidad de fotogramas, métricas de pausa/congelación, información de códec y estimación de red del lado del remitente opcional.

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

  • OTPublisherKitNetworkStatsDelegate - estadísticas del editor

  • OTSubscriberKitNetworkStatsDelegate - estadísticas de abonados

Para recibirlos, active el delegado correspondiente en el editor o 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
    }
}

Implementar los callbacks:

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

    if let transport = first.transport {
        print("Estimated uplink bandwidth: \(transport.connectionEstimatedBandwidth) bps")
    }
}

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

    if let transport = first.transport {
        print("Estimated uplink bandwidth: \(transport.connectionEstimatedBandwidth) bps")
    }
}

Para un editor en una sesión enrutada (que utiliza la función Router multimedia de vídeo de Vonage), la matriz de estadísticas incluye un objeto, que define las estadísticas para el flujo de medios de audio o video único que se envía al enrutador de medios de video de Vonage. En una sesión retransmitida, la matriz de estadísticas incluye un objeto para cada suscriptor del flujo publicado. la transmisión publicada.

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

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

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

Activar las estadísticas para abonados

Adjuntar 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!)
    }
}

Implementar los callbacks:

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

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

Además, gestiona los eventos de cambio de calidad de vídeo de los abonados:

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

Estructuras de datos estadísticos

En esta sección se describen las estructuras y propiedades proporcionadas por la API de estadísticas de audio y vídeo de iOS. Aunque todas las plataformas del SDK de vídeo 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 la estimación compartida a nivel de transporte.

  • connectionEstimatedBandwidth - Ancho de banda estimado de la conexión de enlace ascendente disponible (bps).

OTPublisherKitVideoNetworkStats

Proporciona estadísticas sobre la pista de vídeo 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

Proporciona 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 capa SVC.

  • width - Anchura de trama codificada.
  • height - Altura del fotograma codificado.
  • encodedFrameRate - Fotogramas codificados por segundo.
  • bitrate - Velocidad de bits de capa (bps).
  • totalBitrate - Tasa de bits de capa, incluida la sobrecarga 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 (reflejadas tanto en audio como en vídeo).

  • connectionMaxAllocatedBitrate - Tasa de bits 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 decodificados por segundo.
  • 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).

Estadísticas del remitente

Véase el estadísticas del lado del remitente.

Activación de las estadísticas del lado 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.

Suscripción a las estadísticas del lado del remitente

Si el editor del flujo ha activado las estadísticas del lado del remitente, los abonados empezarán a recibirlas automáticamente en cuanto un oyente se registre para recibir estadísticas de vídeo o audio, como se ha descrito anteriormente.

Implementa el método delegado para las estadísticas de vídeo:

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)")
    } else {
        print("Sender-side stats not available yet.")
    }
}

Recepción de eventos estadísticos

Las estadísticas del lado del remitente se envían a través de OTSubscriberKitNetworkStatsDelegate para vídeo y audio, como se muestra arriba. El sitio OTSenderStatsincluido como senderStats miembro en ambos OTSubscriberKitVideoNetworkStats y OTSubscriberKitAudioNetworkStatsproporciona dos propiedades:

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

Estas dos métricas se calculan por paquete de audio y vídeo, por lo que los mismos valores aparecen en las estadísticas de vídeo y audio. Como reflejan el transporte y no las pistas individuales, las métricas se comparten tanto en audio como en vídeo.

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 de estadísticas RTC para el flujo de medios de forma asíncrona.

Antes de llamar a este método, establezca el valor rtcStatsReportDelegate de su editor e implemente 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 que es una matriz JSON de informes de estadísticas 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

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