Observabilidade do cliente: iOS

O SDK de vídeo da Vonage disponibiliza métricas detalhadas sobre a qualidade do fluxo por meio de uma API de estatísticas de alto nível — recomendada para a maioria dos casos de uso —, que fornece estatísticas de áudio, vídeo, rede e do lado do remetente de forma unificada e sensível à sessão, mantendo-se estável durante as transições entre conexões entre pares. Para depuração avançada, o SDK também oferece acesso ao relatório bruto de estatísticas do WebRTC, que reflete dados não processados das conexões entre pares.

O SDK também disponibiliza métricas de condição de rede que oferecem uma avaliação geral do estado da conexão, tanto para emissores quanto para assinantes. Essas métricas incluem uma pontuação de condição de rede, o motivo por trás dessa pontuação e — para os assinantes — uma fonte de degradação que indica qual lado da conexão é responsável por quaisquer problemas observados. Consulte Condição da rede e fonte de degradação para mais detalhes.

O SDK do Vonage Video para iOS envia estatísticas periódicas de áudio, vídeo e links de mídia tanto para editores quanto para assinantes. Essas estatísticas incluem contagem de pacotes, taxas de bits, dados de taxa de quadros, métricas de pausa/congelamento, informações sobre codecs e métricas de rede no nível de transporte, como estimativa de largura de banda e pontuação das condições da rede.

As estatísticas são disponibilizadas por meio de:

  • OTPublisherKitNetworkStatsDelegate — estatísticas do lado do editor (áudio, vídeo)

  • OTSubscriberKitNetworkStatsDelegate — estatísticas do lado do assinante (áudio, vídeo)

Para recebê-los, habilite o delegado apropriado no editor ou no assinante.

Ativação das estatísticas para editores

Anexe uma classe que adote a interface `OTPublisherKitNetworkStatsDelegate`:

@interface MyViewController () <OTPublisherKitDelegate, OTPublisherKitNetworkStatsDelegate>
@end

OTPublisher *publisher = [[OTPublisher alloc] initWithDelegate:self
                                                      settings:settings];
publisher.networkStatsDelegate = self;

Implemente os callbacks:

- (void)publisher:(OTPublisherKit *)publisher
videoNetworkStatsUpdated:(NSArray<OTPublisherKitVideoNetworkStats *> *)statsArray {

    OTPublisherKitVideoNetworkStats *stats = statsArray.firstObject;
    if (!stats) return;

    // For routed sessions, the first element is sufficient.
    // For relayed sessions, iterate all elements if you want per-subscriber stats.
    NSString *connectionId = stats.connectionId ?: @"<none>";
    NSString *subscriberId = stats.subscriberId ?: @"<none>";

    NSLog(@"Publisher Video Stats for connectionId: %@, subscriberId: %@", connectionId, subscriberId);
    NSLog(@"Video bytes sent: %lld", stats.videoBytesSent);
    NSLog(@"Video packets sent: %lld", stats.videoPacketsSent);
    NSLog(@"Video packets lost: %lld", stats.videoPacketsLost);
    NSLog(@"Stats timestamp: %f ms", stats.timestamp);

    for (OTPublisherKitVideoLayerStats *layer in stats.videoLayers) {
        NSLog(@"Layer: %dx%d", layer.width, layer.height);
        NSLog(@"  Encoded FPS: %f", layer.encodedFrameRate);
        NSLog(@"  Bitrate: %lld bps", layer.bitrate);
        NSLog(@"  Total bitrate (incl. RTP overhead): %lld bps", layer.totalBitrate);
        NSLog(@"  Codec: %@", layer.codec ?: @"unknown");
        NSLog(@"  Scalability mode: %@", layer.scalabilityMode ?: @"none");
        NSLog(@"  Quality limitation: %@", @(layer.qualityLimitationReason));
    }
}

- (void)publisher:(OTPublisherKit *)publisher
audioNetworkStatsUpdated:(NSArray<OTPublisherKitAudioNetworkStats *> *)statsArray {

    OTPublisherKitAudioNetworkStats *stats = statsArray.firstObject;
    if (!stats) return;

    // For routed sessions, the first element is sufficient.
    // For relayed sessions, iterate all elements if you want per-subscriber stats.
    NSString *connectionId = stats.connectionId ?: @"<none>";
    NSString *subscriberId = stats.subscriberId ?: @"<none>";

    NSLog(@"Publisher Audio Stats for connectionId: %@, subscriberId: %@", connectionId, subscriberId);
    NSLog(@"Audio bytes sent: %lld", stats.audioBytesSent);
    NSLog(@"Audio packets sent: %lld", stats.audioPacketsSent);
    NSLog(@"Audio packets lost: %lld", stats.audioPacketsLost);
    NSLog(@"Stats timestamp: %f ms", stats.timestamp);
}

- (void)publisher:(OTPublisherKit *)publisher
mediaLinkStatsUpdated:(NSArray<OTPublisherKitMediaLinkStats*>*)mediaLinkStats {
    
    if (mediaLinkStats.count == 0) return;
    OTPublisherKitMediaLinkStats *stats = mediaLinkStats.firstObject;
    
    NSLog(@"Publisher uplink bandwidth: %lld bps", stats.transport.connectionEstimatedBandwidth);
    NSLog(@"Network condition: %ld", (long)stats.transport.networkCondition);
    NSLog(@"Condition reason: %ld", (long)stats.transport.networkConditionReason);
}

Para um editor em uma sessão roteada (aquela que utiliza o Roteador de mídia de vídeo da Vonage), a matriz `stats` inclui um objeto, definindo as estatísticas para o fluxo único de mídia de áudio ou vídeo enviado ao Vonage Video Media Router. Em uma sessão retransmitida, a matriz `stats` inclui um objeto para cada assinante do fluxo publicado.

Recebimento de eventos de qualidade de vídeo nos editores

Se você também estiver interessado em eventos relacionados à qualidade do vídeo, implemente esta função de retorno de chamada:

- (void)publisher:(OTPublisherKit *)publisher
videoQualityChanged:(OTPublisherKitVideoNetworkStats *)stats
           reason:(OTPublisherVideoEventReason)reason {

    NSLog(@"Publisher video quality event: %ld", (long)reason);
}

Recebimento de eventos de condição de rede nos editores

Para receber eventos de alteração nas condições da rede para o editor, implemente o publisher:networkConditionChanged:mediaLinkStats:reason: função de retorno:

- (void)publisher:(OTPublisherKit *)publisher
networkConditionChanged:(OTPublisherKitMediaLinkStats *)mediaLinkStats
             reason:(OTNetworkReason)reason {

    NSLog(@"Publisher network condition changed: %ld", (long)mediaLinkStats.transport.networkCondition);
    NSLog(@"Reason: %ld", (long)mediaLinkStats.transport.networkConditionReason);
}

Essa função de retorno de chamada é acionada quando é detectada uma alteração significativa nas condições de rede do editor. Ela inclui as estatísticas atuais do link de mídia, juntamente com as métricas de transporte. Consulte Condição da rede e fonte de degradação para obter mais detalhes sobre como interpretar as pontuações e os motivos relativos às condições da rede.

Ativação de estatísticas para assinantes

Anexe uma classe que adote OTSubscriberKitNetworkStatsDelegate:

@interface MyViewController () <OTSubscriberKitDelegate, OTSubscriberKitNetworkStatsDelegate>
@end

OTSubscriber *subscriber = [[OTSubscriber alloc] initWithStream:stream
                                                       delegate:self];
subscriber.networkStatsDelegate = self;
[session subscribe:subscriber error:nil];

Implemente os callbacks:

- (void)subscriber:(OTSubscriberKit *)subscriber
videoNetworkStatsUpdated:(OTSubscriberKitVideoNetworkStats *)stats {
    NSLog(@"Video bytes received: %llu", stats.videoBytesReceived);
}

- (void)subscriber:(OTSubscriberKit *)subscriber
audioNetworkStatsUpdated:(OTSubscriberKitAudioNetworkStats *)stats {
    NSLog(@"Audio packets received: %llu", stats.audioPacketsReceived);
}

- (void)subscriber:(OTSubscriberKit *)subscriber
mediaLinkStatsUpdated:(OTSubscriberKitMediaLinkStats *)mediaLinkStats {
    
    NSLog(@"Local downlink bandwidth: %lld bps", mediaLinkStats.transport.connectionEstimatedBandwidth);
    NSLog(@"Remote publisher uplink bandwidth: %lld bps", mediaLinkStats.remotePublisherTransport.connectionEstimatedBandwidth);
    NSLog(@"Degradation source: %ld", (long)mediaLinkStats.networkDegradationSource);
}

Recebimento de eventos de qualidade de vídeo nos assinantes

Além disso, tratar os eventos relacionados à alteração da qualidade de vídeo dos assinantes:

- (void)subscriber:(OTSubscriberKit *)subscriber
videoQualityChanged:(OTSubscriberKitVideoNetworkStats *)stats
            reason:(OTSubscriberVideoEventReason)reason {

    NSLog(@"Subscriber video quality event: %ld", (long)reason);
}

Recebimento de eventos de condição da rede nos assinantes

Para receber eventos de alteração nas condições da rede para o assinante, implemente o subscriber:networkConditionChanged:mediaLinkStats:reason: função de retorno:

- (void)subscriber:(OTSubscriberKit *)subscriber
networkConditionChanged:(OTSubscriberKitMediaLinkStats *)mediaLinkStats
             reason:(OTNetworkReason)reason {

    NSLog(@"Local network condition: %ld", (long)mediaLinkStats.transport.networkCondition);
    NSLog(@"Remote publisher network condition: %ld", (long)mediaLinkStats.remotePublisherTransport.networkCondition);
    NSLog(@"Degradation source: %ld", (long)mediaLinkStats.networkDegradationSource);
}

Essa função de retorno de chamada é acionada quando é detectada uma alteração significativa nas condições da rede para o assinante ou para o editor remoto. Ela inclui as estatísticas atuais do link de mídia, com métricas de transporte locais e remotas e a origem da degradação. Consulte Condição da rede e fonte de degradação para obter mais detalhes sobre como interpretar as pontuações e os motivos relativos às condições da rede.

Estatística e Estruturas de Dados

Esta seção descreve as estruturas e propriedades fornecidas pela API de estatísticas de áudio e vídeo do iOS. Embora todas as plataformas do SDK de vídeo apresentem o mesmo conjunto de estatísticas, pode haver pequenas diferenças na forma como cada plataforma estrutura ou nomeia os campos individuais. Essas variações refletem convenções de design do SDK específicas de cada plataforma, e não diferenças nas métricas subjacentes.

OTTransportStats

Representa métricas compartilhadas no nível do transporte.

  • connectionEstimatedBandwidth – Largura de banda estimada disponível para conexão (bps).
  • networkCondition – Pontuação atual do estado da rede (OTNetworkConditionUnknown, OTNetworkConditionCritical, OTNetworkConditionWarning, OTNetworkConditionFair, OTNetworkConditionGood, ou OTNetworkConditionExcellent).
  • networkConditionReason – Principal motivo que afeta o estado da rede (OTNetworkReasonNone, OTNetworkReasonUnknown, OTNetworkReasonBandwidth, ou OTNetworkReasonPacketLoss).

OTPublisherKitVideoNetworkStats

Fornece estatísticas sobre a trilha de vídeo de um editor. Inclui:

  • connectionId – Em uma sessão retransmitida, o ID de conexão do cliente que está assinando o fluxo. Não definido em uma sessão roteada.
  • subscriberId – Em uma sessão retransmitida, o ID de assinatura do cliente que está assinando o fluxo. Não definido em uma sessão roteada.
  • videoPacketsLost – Estimativa de pacotes de vídeo perdidos.
  • videoPacketsSent – Pacotes de vídeo enviados.
  • videoBytesSent – Bytes de vídeo enviados.
  • timestamp – Carimbo de data/hora do Unix, em milissegundos, no momento em que as estatísticas foram coletadas.
  • startTime – O carimbo de data e hora, em milissegundos desde a época Unix, a partir do qual os totais acumulados começaram a ser calculados.
  • videoLayers – A matriz de estatísticas da camada de vídeo (consulte OTPublisherKitVideoLayerStats).

OTPublisherKitAudioNetworkStats

Fornece estatísticas sobre a faixa de áudio de um editor. Inclui:

  • connectionId – Em uma sessão retransmitida, o ID de conexão do cliente que está assinando o fluxo. Não definido em uma sessão roteada.
  • subscriberId – Em uma sessão retransmitida, o ID de assinatura do cliente que está assinando o fluxo. Não definido em uma sessão roteada.
  • audioPacketsLost – Estimativa de pacotes perdidos.
  • audioPacketsSent – Pacotes de áudio enviados.
  • audioBytesSent – Trechos de áudio enviados.
  • timestamp – Carimbo de data/hora do Unix em milissegundos.
  • startTime – O carimbo de data e hora, em milissegundos desde a época Unix, a partir do qual os totais acumulados começaram a ser calculados.
  • transport – Estatísticas de rede no nível de transporte.

OTPublisherKitVideoLayerStats

Representa uma camada de transmissão simultânea ou uma camada SVC.

  • width – Largura do quadro codificado.
  • height – Altura do quadro codificado.
  • encodedFrameRate – Quadros codificados por segundo.
  • bitrate – Taxa de bits da camada (bps).
  • totalBitrate – Taxa de bits da camada, incluindo a sobrecarga do RTP (bps).
  • scalabilityMode – Descritor SVC/escalabilidade (por exemplo, “L3T3”).
  • qualityLimitationReason – Motivo da limitação de qualidade (largura de banda, CPU, codec, resolução ou mudança de camada).
  • codec – O codec utilizado por essa camada de vídeo.

OTSenderStats

Métricas de estimativa do lado do remetente (aplicadas tanto ao áudio quanto ao vídeo).

  • connectionMaxAllocatedBitrate – Taxa de bits máxima estimada para a conexão do remetente.
  • connectionEstimatedBandwidth – Estimativa da largura de banda atual (bps).

OTSubscriberKitVideoNetworkStats

Fornece estatísticas sobre a trilha de vídeos de um assinante. Inclui:

  • videoPacketsLost – Estimativa de pacotes de vídeo perdidos.
  • videoPacketsReceived – Pacotes de vídeo recebidos.
  • videoBytesReceived – Bytes de vídeo recebidos.
  • timestamp – Carimbo de data/hora do Unix, em milissegundos, no momento em que as estatísticas foram coletadas.
  • senderStats – Métricas do lado do remetente (opcional).
  • width – Largura do quadro decodificado em pixels.
  • height – Altura do quadro decodificado em pixels.
  • decodedFrameRate – Quadros por segundo decodificados.
  • bitrate – Taxa de bits do vídeo (bps).
  • totalBitrate – Taxa de bits, incluindo a sobrecarga do RTP (bps).
  • pauseCount – Número de pausas (mais de 5 s desde o último quadro). Inclui desativações intencionais e casos de recurso alternativo de áudio.
  • totalPausesDuration – Duração total da pausa (ms).
  • freezeCount – Contagem de congelamentos (evento de congelamento definido pelo WebRTC).
  • totalFreezesDuration – Duração total do congelamento (ms).
  • codec – Codec atual do decodificador.

OTSubscriberKitAudioNetworkStats

Fornece estatísticas sobre a trilha de áudio de um assinante. Inclui:

  • audioPacketsLost – Estimativa de pacotes perdidos.
  • audioPacketsReceived – Pacotes recebidos.
  • audioBytesReceived – Bytes recebidos.
  • timestamp – Carimbo de data/hora do Unix em milissegundos.
  • senderStats – Métricas do lado do remetente (opcional).

OTPublisherKitMediaLinkStats

Fornece estatísticas no nível do transporte para a conexão de um editor.

  • transport – Estatísticas de tráfego para esta editora (ver OTTransportStats)

OTSubscriberKitMediaLinkStats

Fornece estatísticas no nível de transporte para as conexões de um assinante, incluindo visibilidade do desempenho da rede do editor remoto. Isso permite que as Applications diagnostiquem se os problemas de conexão se originam do downlink do assinante ou do uplink do editor.

  • transport – Estatísticas de transporte para a conexão de downlink deste assinante (ver OTTransportStats)
  • remotePublisherTransport – Estatísticas de transporte para a conexão de uplink do editor remoto (obtidas por meio de estatísticas do lado do remetente, consulte OTTransportStats). Essas estatísticas podem ser limitadas caso as estatísticas do remetente não estejam ativadas.
  • networkDegradationSource – Indica a origem da degradação da rede (OTNetworkDegradationSourceLocal, OTNetworkDegradationSourceRemote, OTNetworkDegradationSourceBothOrUnclear, ou OTNetworkDegradationSourceUnknown)

Estatísticas do lado do remetente

Veja o Visão geral das estatísticas do lado do remetente.

Ativação das estatísticas do remetente

As estatísticas do remetente são recebidas pelos assinantes. Para receber essas estatísticas, habilite-as para o editor do fluxo definindo o senderStatsTrack propriedade para true para o OTPublisherKitSettings objeto usado para criar o editor.

OTPublisherKitSettings *settings = [[OTPublisherKitSettings alloc] init];
settings.senderStatsTrack = YES;

OTPublisher *publisher = [[OTPublisher alloc] initWithDelegate:self
                                                      settings:settings];

Se senderStatsTrack Se não estiver habilitado, nenhum canal de estatísticas do remetente será publicado para esse editor. O valor padrão é NO.

Inscrição nas estatísticas do remetente

Se o emissor da transmissão tiver ativado as estatísticas do lado do remetente, os assinantes passam a recebê-las automaticamente assim que um ouvinte for registrado para receber estatísticas de vídeo ou áudio, conforme descrito acima.

Implemente o método delegado para as estatísticas de vídeo:

- (void)subscriber:(OTSubscriberKit *)subscriber
videoNetworkStatsUpdated:(OTSubscriberKitVideoNetworkStats *)stats
{
    // The property may be nil if no sender statistics have been received yet.
    if (stats.senderStats) {
        OTSenderStats *sender = stats.senderStats;
        NSLog(@"Connection max allocated bitrate: %lld bps", (long long)sender.connectionMaxAllocatedBitrate);
        NSLog(@"Connection current estimated bandwidth: %lld bps", (long long)sender.connectionEstimatedBandwidth);
    } else {
        NSLog(@"Sender-side stats not available yet.");
    }
}

Da mesma forma, implementar -subscriber:audioNetworkStatsUpdated: para estatísticas de áudio, que também incluem um senderStats propriedade.

Eventos de estatísticas de recepção

As estatísticas do lado do remetente são fornecidas por meio do OTSubscriberKitNetworkStatsDelegate callbacks para vídeo e áudio, conforme mostrado acima. O OTSenderStats, incluído como o senderStats membro em ambos OTSubscriberKitVideoNetworkStats e OTSubscriberKitAudioNetworkStats, oferece duas propriedades:

  • connectionMaxAllocatedBitrate — A taxa de bits máxima que pode ser estimada para a conexão
  • connectionEstimatedBandwidth — A largura de banda estimada atual para a conexão

Essas duas métricas são calculadas por pacote de áudio e vídeo; portanto, os mesmos valores aparecem tanto nas estatísticas de vídeo quanto nas de áudio. Como refletem o transporte, e não faixas individuais, as métricas são compartilhadas entre áudio e vídeo.

Condição da rede e fonte de degradação

O SDK fornece métricas em tempo real sobre as condições da rede tanto para editores quanto para assinantes, incluindo uma pontuação de condição, o motivo por trás dessa pontuação e a origem da degradação para os assinantes. Para obter uma explicação completa sobre o modelo de condições da rede, as pontuações, os motivos e como ativá-lo, consulte o Visão geral da observabilidade do cliente.

Os dados sobre o estado da rede estão disponíveis por meio de dois canais:

  • Estatísticas periódicas: As estatísticas de eventos de links de mídia incluem métricas de transporte com networkCondition e networkConditionReason. Para os assinantes, as estatísticas dos links de mídia também incluem remotePublisherTransport e networkDegradationSource.
  • Eventos relacionados a alterações nas condições da rede: Callbacks específicos, tanto no emissor quanto no assinante, são acionados quando é detectada uma mudança significativa nas condições da rede.

O exemplo a seguir mostra como usar os dados de condição da rede do assinante para identificar a origem da degradação:

- (void)subscriber:(OTSubscriberKit *)subscriber
networkConditionChanged:(OTSubscriberKitMediaLinkStats *)mediaLinkStats
             reason:(OTNetworkReason)reason {

    OTNetworkCondition localCondition = mediaLinkStats.transport.networkCondition;
    OTNetworkCondition remoteCondition = mediaLinkStats.remotePublisherTransport.networkCondition;
    OTNetworkDegradationSource source = mediaLinkStats.networkDegradationSource;

    if (source == OTNetworkDegradationSourceLocal) {
        NSLog(@"Local network is degraded (condition: %ld)", (long)localCondition);
    } else if (source == OTNetworkDegradationSourceRemote) {
        NSLog(@"Remote publisher network is degraded (condition: %ld)", (long)remoteCondition);
    } else if (source == OTNetworkDegradationSourceBothOrUnclear) {
        NSLog(@"Degradation source unclear — local: %ld, remote: %ld", (long)localCondition, (long)remoteCondition);
    }
}

Relatório de Estatísticas da RTC

Para obter estatísticas de conexão entre pares de baixo nível do publisher, use o [OTPublisherKit getRtcStatsReport:] método. Isso fornece relatórios de estatísticas de RTC para o fluxo de mídia.

Esta é uma operação assíncrona. Defina o >[OTPublisherKit rtcStatsReportDelegate]> propriedade e implementar o >[OTPublisherKitRtcStatsReportDelegate publisher:rtcStatsReport:]> método antes de chamar [OTPublisherKit getRtcStatsReport:].

Quando as estatísticas estiverem disponíveis, a implementação do >[OTPublisherKitRtcStatsReportDelegate publisher:rtcStatsReport:]> A mensagem é enviada. A mensagem inclui uma matriz de OTPublisherRtcStats objetos, o que inclui um jsonArrayOfReports propriedade.

Este é um array JSON de relatórios de estatísticas do RTC, cujo formato é semelhante ao do objeto RtcStatsReport implementado nos navegadores da web (consulte esses documentos da Mozilla).

Para obter estatísticas de conexão entre pares de baixo nível dos assinantes, use o [OTSubscriberKit getRtcStatsReport:] método. Isso fornece um relatório de estatísticas RTC para o fluxo de mídia.

Esta é uma operação assíncrona. Defina o [OTSubscriberKit rtcStatsReportDelegate]> propriedade e implementar o >[OTSubscriberKitRtcStatsReportDelegate subscriber:rtcStatsReport:]> método antes de chamar [OTSubscriberKit getRtcStatsReport:].

Quando as estatísticas estiverem disponíveis, a implementação do >[OTSubscriberKitRtcStatsReportDelegate subscriber:rtcStatsReport:]> A mensagem é enviada. A mensagem inclui um a jsonArrayOfReports parâmetro.

Este é um array JSON de relatórios de estatísticas do RTC, cujo formato é semelhante ao do objeto RtcStatsReport implementado nos navegadores da web (consulte esses documentos da Mozilla).

Veja também esta documentação do W3C.

Exemplo

O Aplicativo de exemplo de observabilidade do cliente do Vonage Video Client SDK para iOS demonstra os recursos de observabilidade do cliente em um aplicativo móvel desenvolvido com o Client SDK para iOS.