API de códecs de vídeo preferidos por los editores

Una guía práctica para establecer las preferencias de códec por editor, comprender cómo interactúan esas preferencias con la negociación y confirmar el códec que se está utilizando realmente durante una sesión en directo.

Este tema incluye las siguientes secciones:

Requisitos previos

Antes de utilizar la API Preferred Video Codec a través del SDK, debe activarla en la configuración de su proyecto:

  1. Ve a la Account de la Video API y selecciona tu proyecto.
  2. En la configuración del proyecto, selecciona el códec de vídeo preferido a nivel de proyecto.
  3. Aplique los ajustes necesarios para activar las preferencias de códecs a nivel del SDK.

Nota: Su selección sólo afecta al proyecto seleccionado. Más información sobre los códecs compatibles en Códecs de vídeo guía.

Visión general

La API del códec de vídeo preferido por el editor permite a cada editor declarar su propia prioridad de códec, independientemente del códec preferido a nivel de proyecto configurado en la aplicación Account de la Video API. Puede proporcionar una lista ordenada explícita de códecs o delegar la decisión en el SDK en modo automático.

Importante: Esta API establece un preferenciano es una restricción. Se pueden seguir negociando otros códecs si los preferidos no están disponibles. La preferencia influye en el orden en que los códecs aparecen en la oferta SDP, dándoles mayor prioridad durante la negociación.

Utilice esta API cuando la configuración a nivel de proyecto no sea lo suficientemente específica para sus necesidades. Los escenarios comunes incluyen:

  • Sesiones mixtas. Los distintos emisores de una misma sesión se benefician de distintos códecs. Gracias a las preferencias específicas para cada emisor, cada dispositivo puede indicar el orden de códecs que más le convenga.

  • Editores con funciones específicas. Un editor de pantalla compartida puede beneficiarse de VP9, mientras que un editor de cámara en la misma sesión prefiere VP8 por su mayor compatibilidad.

  • Dejar que el SDK decida. Si no quieres introducir una lista de forma estática, el modo automático delega la elección al SDK.

Si todos los editores de su aplicación deben utilizar el mismo códec, y la configuración a nivel de proyecto ya refleja esa elección, no necesita esta API.

VP8 es un códec de implementación obligatoria compatible con todos los dispositivos. Dado que todos los códecs compatibles se añaden automáticamente como opciones alternativas, VP8 siempre está disponible como opción alternativa definitiva, incluso si no lo incluyes explícitamente en tu lista.

Para obtener más información sobre los códecs VP8, H.264 y VP9, las tablas de cobertura de códecs y la configuración del códec preferido a nivel de proyecto, consulte la página Códecs de vídeo guía.

Elegir un modo

Automático

Pasar la cadena 'automatic' (Web, React Native) o llamar al método de fábrica correspondiente en los SDK nativos. El SDK evalúa el entorno local y determina un orden de prioridad de códecs adecuado.

Utilice el modo automático cuando:

  • Quieres que el SDK se adapte a diferentes navegadores y dispositivos sin tener que gestionar tu propia lógica para cada dispositivo.
  • Prefieres un enfoque compatible con futuras versiones. El modo automático incorporará heurísticas de selección más sofisticadas en futuras versiones del SDK, por lo que las aplicaciones que lo adopten hoy se beneficiarán de las mejoras sin necesidad de modificar el código.

Nota: La heurística utilizada por el modo automático evolucionará con el tiempo. Las primeras versiones aplican una estrategia de selección básica. Las futuras versiones del SDK pueden tener en cuenta señales adicionales como las capacidades del hardware, las condiciones de la red y la topología de la sesión. Trate el modo automático como el predeterminado recomendado a menos que tenga una razón específica para codificar una lista.

Manual

Proporciona una matriz ordenada de códecs. El primer elemento tiene la prioridad más alta:

['vp9', 'vp8']          prefer VP9, fall back to VP8, then remaining codecs
['h264']                 prefer H.264; remaining codecs (VP8, VP9) are appended automatically as fallbacks
['vp8', 'h264', 'vp9']  explicit full ordering: VP8 first, then H.264, then VP9

Utilice el modo manual cuando sepa exactamente qué orden de códec es el mejor para un editor o dispositivo determinado. Este ajuste anula el códec preferido a nivel de proyecto configurado en el panel.

Nota: Los códecs que especifiques definen el orden de prioridad, pero el resto de códecs compatibles se añaden siempre como "fallbacks". Por ejemplo, si se define ['vp9'] significa que se da preferencia al VP9, pero el VP8 y el H.264 siguen estando disponibles para su negociación en caso de que el VP9 no esté disponible.

Por defecto

Si no configuras preferredVideoCodecs el editor utiliza el códec preferido a nivel de proyecto configurado en el panel de control. Este es el mismo comportamiento que antes de que existiera esta API.

Comparación

Modo Cuándo utilizarlo ¿Preparado para el futuro?
Automático Quieres que el SDK elija el mejor orden Sí, ventajas de las actualizaciones del SDK
Lista manual ¿Conoces el orden exacto de los códecs para este editor? No, tú te encargas de la lista
Por defecto Basta con configurarlo a nivel de proyecto N/A, utiliza la configuración del proyecto

Orden recomendada de los códecs para situaciones habituales

Cuando se utiliza el modo manual, el orden de los códecs depende del tipo de sesión, el público y el caso de uso. En la tabla siguiente se enumeran los escenarios más habituales con una preferredVideoCodecs y el razonamiento en que se basa.

Escenario Orden recomendado ¿Por qué?
Sesión o seminario web de gran envergadura (enrutado) ['vp9', 'vp8'] Tanto VP9 como VP8 son compatibles con Vídeo escalable, lo cual es esencial para las sesiones con muchos suscriptores. VP9 ofrece una mejor compresión, por lo que requiere menos ancho de banda para obtener una calidad equivalente. VP8 es la opción alternativa para los terminales en los que no está disponible el vídeo escalable VP9 (véase el tablas de cobertura de códecs). La plataforma no es compatible con H.264 con vídeo escalable, por lo que se debe evitar el uso de H.264 en sesiones de gran tamaño y utilizar en su lugar VP8 o VP9.
Sesión pequeña, dispositivos solo con iOS ['h264', 'vp8'] Los dispositivos iOS cuentan con aceleración por hardware para H.264, lo que reduce la carga de la CPU y mejora la duración de la batería. VP8 sigue siendo una opción alternativa segura.
Sesión pequeña, ancho de banda limitado ['vp9', 'vp8'] VP9 consigue mejor calidad que VP8 con la misma tasa de bits. VP8 es la alternativa para los terminales que no admiten VP9 (por ejemplo, versiones antiguas de Safari).
Editor de pantallas compartidas ['vp9', 'vp8'] El contenido de pantalla se comprime muy eficazmente con VP9 debido a su mejor gestión de los bordes afilados y las regiones estáticas. VP8 es la alternativa.
Compartir pantalla con la mejor compresión ['vp9'] Prefiera VP9 por su manejo superior de bordes afilados y regiones estáticas. Otros códecs compatibles se siguen negociando con menor prioridad como fallbacks.
Máxima compatibilidad (debe llegar a todos los dispositivos) ['vp8'] VP8 es el único códec compatible con todos los puntos finales de OpenTok, incluido el SDK de Linux (que no admite H.264) y Safari más antiguo (que puede carecer de VP9).

Consejo: Si ninguno de los escenarios anteriores se ajusta a su caso de uso, considere la posibilidad de utilizar modo automático En su lugar, permite que el SDK elija el mejor orden en función del entorno local e incorporará heurísticas mejoradas en futuras versiones.

Cómo funciona la negociación de códecs

Establecer un códec predeterminado hace que no garantizar que se utilice ese códec. El códec definitivo se determina mediante un proceso de negociación que depende del tipo de sesión.

Sesiones enrutadas (Media Router)

En un sesión enrutada, el editor se comunica con el OpenTok Media Router:

  1. El editor envía una oferta SDP con los códecs ordenados según la preferencia (el códec preferido aparece en primer lugar).
  2. El Media Router considera la oferta y selecciona un códec compatible.
  3. Si se admite el códec preferido, se utiliza. De lo contrario, el Media Router pasa al siguiente códec de la oferta.

Dado que el Media Router se encarga de la distribución de contenidos multimedia, todos los suscriptores de una sesión enrutada reciben vídeo codificado con el mismo códec que ha negociado el emisor.

Sesiones retransmitidas (peer-to-peer)

En un sesión retransmitida, no hay ningún enrutador de medios. Cada par editor-suscriptor negocia de forma independiente:

  1. El editor envía una oferta SDP con los códecs ordenados por preferencia.
  2. El abonado responde con una respuesta SDP que enumera los códecs que admite.
  3. El par selecciona el códec de mayor prioridad que ambos extremos admiten.

Esto significa que distintos pares de abonados en la misma sesión retransmitida podrían acabar utilizando distintos códecs, en función de las capacidades de cada abonado.

¿Qué puede provocar un «fallback»?

Un «fallback» significa que no se ha utilizado el códec preferido y que, en su lugar, se ha seleccionado otro códec para la publicación. Esto puede ocurrir cuando:

  • El extremo remoto (en sesiones retransmitidas) o el enrutador de medios (en sesiones enrutadas) no admiten el códec preferido.
  • El navegador o dispositivo no admite la codificación con el códec preferido (por ejemplo, H.264 en algunos dispositivos Android, VP9 en versiones antiguas de Safari).

Dado que pueden producirse retrocesos, verifique siempre el códec en uso en lugar de asumir que se ha respetado la preferencia. Conocer el códec activo te ayudará:

  • Depurar y controlar la calidad. Registra qué códec está en uso para diagnósticos y análisis de calidad a través de Insights.
  • Adaptarse en tiempo de ejecución. Ajuste la resolución o la tasa de bits en función de los puntos fuertes del códec negociado (por ejemplo, VP9 puede lograr la misma calidad a una tasa de bits inferior que VP8).
  • Garantizar la coherencia de la sesión. Confirme que todos los editores de una sesión utilizan el códec esperado, especialmente en sesiones enrutadas en las que el Media Router distribuye un único códec por editor a todos los abonados.

Véase Verificación del códec en uso para obtener instrucciones específicas para cada plataforma.

Configuración de preferencias por plataforma

SDK web


export type VideoCodec = 'vp8' | 'vp9' | 'h264';
export type PreferredVideoCodecs = 'automatic' | [VideoCodec, ...VideoCodec[]];

// Automatic mode
const publisher = OT.initPublisher('publisherContainer', {
  preferredVideoCodecs: 'automatic'
});

// Manual mode
const publisher = OT.initPublisher('publisherContainer', {
  preferredVideoCodecs: ['vp9', 'vp8']
});

// Default (uses project-level preferred codec)
const publisher = OT.initPublisher('publisherContainer', {});

Si se pasa una matriz vacía o una cadena de códec no válida, la publicación falla con un OT_INVALID_PARAMETER error.

SDK para iOS


// Automatic mode
OTVideoCodecPreference *pref = [OTVideoCodecPreference automatic];
OTPublisherKitSettings *settings = [[OTPublisherKitSettings alloc] init];
settings.videoCodecPreference = pref;
OTPublisherKit *publisher = [[OTPublisherKit alloc] initWithDelegate:self
                                                            settings:settings];

// Manual mode
OTVideoCodecPreference *pref = [OTVideoCodecPreference manualWithCodecs:@[
    @(OTVideoCodecTypeVP9),
    @(OTVideoCodecTypeH264),
    @(OTVideoCodecTypeVP8)
]];
OTPublisherKitSettings *settings = [[OTPublisherKitSettings alloc] init];
settings.videoCodecPreference = pref;

SDK de Android


// Automatic mode
PublisherKit.PreferredVideoCodecs preferredVideoCodecs =
    PublisherKit.PreferredVideoCodecs.automatic();

Publisher publisher = new Publisher.Builder(context)
    .preferredVideoCodecs(preferredVideoCodecs)
    .build();

// Manual mode
PublisherKit.PreferredVideoCodecs preferredVideoCodecs =
    PublisherKit.PreferredVideoCodecs.manual(
        new ArrayList<PublisherKit.PreferredVideoCodecs.Codec>(
            List.of(PublisherKit.PreferredVideoCodecs.Codec.VP9,
                    PublisherKit.PreferredVideoCodecs.Codec.H264)));

Publisher publisher = new Publisher.Builder(context)
    .preferredVideoCodecs(preferredVideoCodecs)
    .build();

Pasar un null o lista vacía a manual() lanza IllegalArgumentException.

SDK de Windows


// Automatic mode
builder.PreferredVideoCodecs = PreferredVideoCodecs.Automatic();

// Manual mode
builder.PreferredVideoCodecs = new PreferredVideoCodecs(
    new List<PreferredVideoCodecs.Codec> {
        PreferredVideoCodecs.Codec.VP9,
        PreferredVideoCodecs.Codec.H264,
        PreferredVideoCodecs.Codec.VP8
    });

// Default (uses project-level setting)
builder.PreferredVideoCodecs = null;

Si se pasa una lista vacía, se produce un error ArgumentException.

SDK para Linux


// Automatic mode
otc_publisher_settings* settings = otc_publisher_settings_new();
otc_publisher_settings_set_preferred_video_codecs_automatic(settings);

otc_publisher_callbacks callbacks = {0};
struct otc_publisher* publisher =
    otc_publisher_new_with_settings(&callbacks, settings);
otc_publisher_settings_delete(settings);

// Manual mode
otc_publisher_settings* settings = otc_publisher_settings_new();

otc_video_codec_type codecs[] = {
    OTC_VIDEO_CODEC_VP9,
    OTC_VIDEO_CODEC_H264,
    OTC_VIDEO_CODEC_VP8
};

otc_publisher_settings_set_preferred_video_codecs(
    settings, codecs, sizeof(codecs) / sizeof(codecs[0]));

otc_publisher_callbacks callbacks = {0};
struct otc_publisher* publisher =
    otc_publisher_new_with_settings(&callbacks, settings);
otc_publisher_settings_delete(settings);

SDK de React Native


// Automatic mode
<OTPublisher properties={{ preferredVideoCodecs: 'automatic' }} />

// Manual mode
<OTPublisher properties={{ preferredVideoCodecs: ['vp9', 'vp8'] }} />

Verificación del códec en uso

Una vez que el editor haya iniciado la transmisión, utiliza las API de estadísticas del SDK para confirmar qué códec se ha negociado realmente. No des por sentado que se ha respetado la preferencia.

Comprobación de los códecs compatibles antes de publicar

Puede comprobar proactivamente qué códecs admite un cliente antes de establecer una preferencia.

SDK web:


const supportedCodecs = await OT.getSupportedCodecs();
console.log('Encoders:', supportedCodecs.videoEncoders);
console.log('Decoders:', supportedCodecs.videoDecoders);

SDK para Android:


MediaUtils.SupportedCodecs supported =
    MediaUtils.SupportedCodecs.getSupportedCodecs(context);
Log.d("Codecs", "Encoders: " + supported.videoEncoders);
Log.d("Codecs", "Decoders: " + supported.videoDecoders);

SDK para Linux:


otc_media_utils_codecs* supported_codecs = NULL;
otc_status status = otc_media_utils_get_supported_codecs(&supported_codecs);
if (status == OTC_SUCCESS) {
  for (size_t i = 0; i < supported_codecs->number_encoder_video_codecs; i++) {
    printf("Encoder: %d\n", supported_codecs->encoder_video_codecs[i]);
  }
  for (size_t i = 0; i < supported_codecs->number_decoder_video_codecs; i++) {
    printf("Decoder: %d\n", supported_codecs->decoder_video_codecs[i]);
  }
  otc_media_utils_codecs_delete(supported_codecs);
}

Lectura del códec activo en las estadísticas del SDK

Nota: La lectura del códec activo desde las estadísticas del SDK requiere Web SDK 2.33 o posterior, que introdujo la API Client Observability que expone la información del códec en el objeto stats.

SDK web

Editorial:


setInterval(() => {
  publisher.getStats((error, statsArray) => {
    if (error) return;
    statsArray.forEach(({ stats }) => {
      if (stats.video && stats.video.layers) {
        stats.video.layers.forEach((layer) => {
          console.log('Publisher video codec:', layer.codec);
        });
      }
    });
  });
}, 5000);

Abonado:


setInterval(() => {
  subscriber.getStats((error, stats) => {
    if (error) return;
    if (stats.video) {
      console.log('Subscriber video codec:', stats.video.codec);
    }
  });
}, 5000);

Para obtener información sobre WebRTC de nivel inferior, utilice getRtcStatsReport():


publisher.getRtcStatsReport()
  .then(statsArray => {
    // Each entry contains a standard RTCStatsReport.
    // Look for type "codec" entries with mimeType.
    statsArray.forEach(console.log);
  });

SDK de Android


publisher.setNetworkStatsListener(new PublisherKit.NetworkStatsListener() {
    @Override
    public void onVideoStats(PublisherKit publisher,
                             PublisherKit.PublisherVideoStats[] statsArray) {
        if (statsArray != null && statsArray.length > 0) {
            for (PublisherKit.VideoLayerStats layer : statsArray[0].videoLayers) {
                Log.d("Codec", "Publisher codec: " + layer.codec);
            }
        }
    }
});

SDK para iOS


- (void)publisher:(OTPublisherKit *)publisher
videoNetworkStatsUpdated:(NSArray<OTPublisherKitVideoNetworkStats *> *)statsArray {
    OTPublisherKitVideoNetworkStats *stats = statsArray.firstObject;
    for (OTPublisherKitVideoLayerStats *layer in stats.videoLayers) {
        NSLog(@"Publisher codec: %@", layer.codec ?: @"unknown");
    }
}

SDK de React Native


// Publisher
OTPublisher.getRtcStatsReport();

// Subscriber
OTSubscriber.getRtcStatsReport(streamId);

Uso de Insights y Video Inspector

La herramienta Inspector de vídeo muestra el códec, la resolución y la frecuencia de imagen en el módulo Métricas de calidad. Pase el ratón sobre cualquier punto de una línea trazada para ver el códec en uso en ese momento.

También puede filtrar las estadísticas de flujo por códec en Perspectivas Consultas GraphQL:


{
  project(projectId: YOUR_PROJECT_ID) {
    sessionData {
      sessions(start: START_TIME, end: END_TIME) {
        resources {
          streamStatsCollection(filters: { videoCodec: VP9 }) {
            resources {
              createdAt
              videoBitrateKbps
            }
          }
        }
      }
    }
  }
}

Buenas prácticas

  1. Tenga en cuenta el tipo de sesión. En las sesiones enrutadas, todos los suscriptores comparten un mismo códec por emisor. En las sesiones retransmitidas, cada par negocia de forma independiente, por lo que un mismo emisor podría utilizar códecs diferentes con distintos suscriptores.

  2. Ajusta la configuración por editorial y por proyecto. El códec preferido a nivel de proyecto sigue siendo válido para los editores que no establezcan su propia preferencia. Asegúrate de que ambos niveles sean coherentes para evitar sorpresas.

  3. Compruebe la compatibilidad de códecs en el cliente. Antes de establecer una preferencia manual, utilice OT.getSupportedCodecs() (Web) o MediaUtils.SupportedCodecs (Android) para confirmar que el códec preferido está disponible localmente.

  4. Comience con el modo automático. A menos que tengas algún requisito específico en cuanto a códecs, utiliza el modo automático y deja que el SDK elija. Las futuras versiones del SDK perfeccionarán los algoritmos de selección automática, y tu aplicación se beneficiará de ello sin necesidad de modificar el código.

  5. Verify the negotiated codec. Utilice getStats() o getRtcStatsReport() para confirmar el códec una vez iniciada la publicación.

  6. Pruebas en todos los dispositivos de destino. La compatibilidad con los códecs varía según el navegador y la plataforma. Consulta la tablas de cobertura de códecs para más detalles. Pruebe su configuración de preferencias en los dispositivos que utilizan realmente sus usuarios.