Publisher Preferred Video Codec API

A practical guide for setting per-publisher codec preferences, understanding how those preferences interact with negotiation, and confirming the codec that is actually in use during a live session.

This topic includes the following sections:

Prerequisites

Before using the Preferred Video Codec API through the SDK, you must enable it in your project settings:

  1. Go to the Vonage API Dashboard and select your project.
  2. In the project settings, select the project-level preferred video codec.
  3. Apply the required settings to enable SDK-level codec preferences.

Note: Your selection only affects the selected project. Learn more about supported codecs in the Video codecs guide.

Overview

The Publisher Preferred Video Codec API lets each publisher declare its own codec priority, independent of the project-level preferred codec configured in the Vonage Dashboard. You can either supply an explicit ordered list of codecs or delegate the decision to the SDK in automatic mode.

Important: This API sets a preference, not a restriction. Other codecs can still be negotiated if the preferred ones are unavailable. The preference influences the order in which codecs appear in the SDP offer, giving them higher priority during negotiation.

Use this API when the project-level setting is not specific enough for your needs. Common scenarios include:

  • Mixed-device sessions. Different publishers in the same session benefit from different codecs. With per-publisher preferences, each device can express the codec order that suits it best.

  • Feature-specific publishers. A screen-sharing publisher may benefit from VP9, while a camera publisher in the same session prefers VP8 for broader compatibility.

  • Letting the SDK decide. If you don't want to hard-code a list, automatic mode delegates the choice to the SDK.

If every publisher in your application should use the same codec, and the project-level setting already reflects that choice, you do not need this API.

VP8 is a mandatory-to-implement codec supported across all endpoints. Since all supported codecs are automatically appended as fallbacks, VP8 is always available as the ultimate fallback even if you don't include it explicitly in your list.

For background on the VP8, H.264, and VP9 codecs themselves, codec coverage tables, and the project-level preferred codec setting, see the Video codecs guide.

Choosing a mode

Automatic

Pass the string 'automatic' (Web, React Native) or call the corresponding factory method on native SDKs. The SDK evaluates the local environment and determines an appropriate codec priority order.

Use automatic mode when:

  • You want the SDK to adapt to different browsers and devices without maintaining your own per-device logic.
  • You prefer a forward-compatible approach. Automatic mode will incorporate more sophisticated selection heuristics in future SDK releases, so applications that adopt it today will benefit from improvements without code changes.

Note: The heuristics used by automatic mode will evolve over time. Early releases apply a baseline selection strategy. Future SDK versions may factor in additional signals such as hardware capabilities, network conditions, and session topology. Treat automatic mode as the recommended default unless you have a specific reason to hard-code a list.

Manual

Supply an ordered array of codecs. The first element has the highest priority:

Use manual mode when you know exactly which codec order is best for a given publisher or device. This setting overrides the project-level preferred codec configured in the dashboard.

Note: The codecs you specify define the priority order, but all remaining supported codecs are always appended as fallbacks. For example, setting ['vp9'] means VP9 is preferred, but VP8 and H.264 remain available for negotiation if VP9 is unavailable.

Default

If you do not set preferredVideoCodecs at all, the publisher uses the project-level preferred codec configured in the dashboard. This is the same behavior as before this API existed.

Comparison

Mode When to use Future-proof?
Automatic You want the SDK to choose the best order Yes, benefits from SDK updates
Manual list You know the exact codec order for this publisher No, you manage the list
Default Project-level setting is sufficient N/A, uses project setting

When using manual mode, the codec order you supply depends on the session type, audience, and use case. The table below lists common scenarios with a suggested preferredVideoCodecs value and the reasoning behind it.

Scenario Suggested order Why
Large session / webinar (routed) ['vp9', 'vp8'] Both VP9 and VP8 support Scalable Video, which is essential for sessions with many subscribers. VP9 offers better compression, requiring less bandwidth for equivalent quality. VP8 is the fallback for endpoints where VP9 scalable video is not available (see the codec coverage tables). H.264 with Scalable Video is not supported by the platform, so H.264 should be avoided for large sessions and VP8 or VP9 used instead.
Small session, iOS-only devices ['h264', 'vp8'] iOS devices have hardware-accelerated H.264, which reduces CPU load and improves battery life. VP8 remains as a safe fallback.
Small session, bandwidth-constrained ['vp9', 'vp8'] VP9 achieves better quality than VP8 at the same bitrate. VP8 is the fallback for endpoints that do not support VP9 (e.g. older Safari versions).
Screen-sharing publisher ['vp9', 'vp8'] Screen content compresses very efficiently with VP9 due to its superior handling of sharp edges and static regions. VP8 is the fallback.
Screen-sharing with best compression ['vp9'] Prefer VP9 for its superior handling of sharp edges and static regions. Other supported codecs are still negotiated with lower priority as fallbacks.
Maximum compatibility (must reach all devices) ['vp8'] VP8 is the only codec supported across every OpenTok endpoint, including the Linux SDK (which does not support H.264) and older Safari (which may lack VP9).

Tip: If none of the scenarios above match your use case, consider using automatic mode instead. It lets the SDK pick the best order based on the local environment and will incorporate improved heuristics in future releases.

How codec negotiation works

Setting a preferred codec does not guarantee that the codec will be used. The final codec is determined by a negotiation process that depends on the session type.

Routed sessions (Media Router)

In a routed session, the publisher negotiates with the Media Router:

  1. The publisher sends an SDP offer with codecs ordered according to the preference (the preferred codec appears first).
  2. The Media Router considers the offer and selects a codec it supports.
  3. If the preferred codec is supported, it is used. Otherwise the Media Router falls back to the next codec in the offer.

Because the Media Router handles media distribution, all subscribers in a routed session receive video encoded with the same codec the publisher negotiated.

Relayed sessions (peer-to-peer)

In a relayed session, there is no Media Router. Each publisher-subscriber pair negotiates independently:

  1. The publisher sends an SDP offer with codecs ordered by preference.
  2. The subscriber responds with an SDP answer listing the codecs it supports.
  3. The pair selects the highest-priority codec that both endpoints support.

This means different subscriber pairs in the same relayed session could end up using different codecs, depending on each subscriber's capabilities.

What can cause a fallback?

A fallback means the preferred codec was not used and a different codec was selected for publishing instead. This can happen when:

  • The preferred codec is not supported by the remote endpoint (in relayed sessions) or the Media Router (in routed sessions).
  • The browser or device does not support encoding with the preferred codec (e.g. H.264 on some Android devices, VP9 on older Safari versions).

Because fallbacks can occur, always verify the codec in use rather than assuming the preference was honored. Knowing the active codec helps you:

  • Debug and monitor quality. Log which codec is in use for diagnostics and quality analysis via Insights.
  • Adapt at runtime. Adjust resolution or bitrate settings based on the negotiated codec's strengths (e.g., VP9 can achieve the same quality at a lower bitrate than VP8).
  • Ensure session consistency. Confirm that all publishers in a session are using the expected codec, especially in routed sessions where the Media Router distributes a single codec per publisher to all subscribers.

See Verifying the codec in use for platform-specific instructions.

Setting preferences by platform

Web SDK

Passing an empty array or invalid codec string causes the publisher to fail with an OT_INVALID_PARAMETER error.

iOS SDK

Android SDK

Passing a null or empty list to manual() throws IllegalArgumentException.

Windows SDK

Passing an empty list throws ArgumentException.

Linux SDK

React Native SDK

Verifying the codec in use

After a publisher starts streaming, use the SDK statistics APIs to confirm which codec was actually negotiated. Do not assume the preference was honored.

Checking supported codecs before publishing

You can proactively check which codecs a client supports before setting a preference.

Web SDK:

Android SDK:

Linux SDK:

Reading the active codec from SDK statistics

Note: Reading the active codec from SDK statistics requires Web SDK 2.33 or later, which introduced the Client Observability API that exposes codec information in the stats object.

Web SDK

Publisher:

Subscriber:

For lower-level WebRTC information, use getRtcStatsReport():

Android SDK

iOS SDK

React Native SDK

Using Insights and Video Inspector

The Video Inspector tool displays codec, resolution, and frame rate in the Quality Metrics module. Mouse over any point on a plotted line to see the codec in use at that moment.

You can also filter stream statistics by codec in Insights GraphQL queries:

Best practices

  1. Consider session type. In routed sessions all subscribers share one codec per publisher. In relayed sessions each pair negotiates independently, so the same publisher could use different codecs with different subscribers.

  2. Align per-publisher and project-level settings. The project-level preferred codec still applies to publishers that do not set their own preference. Make sure both levels are consistent to avoid surprises.

  3. Check codec support on the client. Before setting a manual preference, use OT.getSupportedCodecs() (Web) or MediaUtils.SupportedCodecs (Android) to confirm the preferred codec is available locally.

  4. Start with automatic mode. Unless you have a specific codec requirement, use automatic mode and let the SDK choose. Future SDK releases will refine the automatic selection heuristics, and your application will benefit without code changes.

  5. Verify the negotiated codec. Use getStats() or getRtcStatsReport() to confirm the codec after publishing begins.

  6. Test across target devices. Codec support varies across browsers and platforms. See the codec coverage tables for details. Test your preference configuration on the devices your users actually use.