Network stacks

ExoPlayer is commonly used for streaming media over the internet. It supports multiple network stacks for making its underlying network requests. Your choice of network stack can have a significant impact on streaming performance.

This page outlines how to configure ExoPlayer to use your network stack of choice, lists the available options, and provides some guidance on how to choose a network stack for your application.

Configuring ExoPlayer to use a specific network stack

ExoPlayer loads data through DataSource components, which it obtains from DataSource.Factory instances that are injected from application code.

If your application only needs to play http(s) content, selecting a network stack is as simple as updating any DataSource.Factory instances that your application injects to be instances of the HttpDataSource.Factory that corresponds to the network stack you wish to use. If your application also needs to play non-http(s) content such as local files, use

new DefaultDataSourceFactory(
    ...
    /* baseDataSourceFactory= */ new PreferredHttpDataSource.Factory(...));

where PreferredHttpDataSource.Factory is the factory corresponding to your preferred network stack. The DefaultDataSourceFactory layer adds in support for non-http(s) sources such as local files.

The example below shows how to build a SimpleExoPlayer that will use the Cronet network stack and also support playback of non-http(s) content.

// Given a CronetEngine and Executor, build a CronetDataSource.Factory.
CronetDataSource.Factory cronetDataSourceFactory =
    new CronetDataSource.Factory(cronetEngine, executor);

// Wrap the CronetDataSource.Factory in a DefaultDataSourceFactory, which adds
// in support for requesting data from other sources (e.g., files, resources,
// etc).
DefaultDataSourceFactory dataSourceFactory =
    new DefaultDataSourceFactory(
        context,
        /* baseDataSourceFactory= */ cronetDataSourceFactory);

// Inject the DefaultDataSourceFactory when creating the player.
SimpleExoPlayer player =
    new SimpleExoPlayer.Builder(context)
        .setMediaSourceFactory(new DefaultMediaSourceFactory(dataSourceFactory))
        .build();

Supported network stacks

ExoPlayer provides direct support for Cronet, OkHttp and Android’s built-in network stack. It can also be extended to support any other network stack that works on Android.

Cronet

Cronet is the Chromium network stack made available to Android apps as a library. It takes advantage of multiple technologies that reduce the latency and increase the throughput of the network requests that your app needs to work, including those made by ExoPlayer. It natively supports the HTTP, HTTP/2, and HTTP/3 over QUIC protocols. Cronet is used by some of the world’s biggest streaming applications, including YouTube.

ExoPlayer supports Cronet via its Cronet extension. Please see the extension’s README.md for detailed instructions on how to use it. Note that the Cronet extension is able to use three underlying Cronet implementations:

  1. Google Play Services: We recommend using this implementation in most cases, and falling back to Android’s built-in network stack (i.e., DefaultHttpDataSource) if Google Play Services is not available.
  2. Cronet Embedded: May be a good choice if a large percentage of your users are in markets where Google Play Services is not widely available, or if you want to control the exact version of the Cronet implementation being used. The major disadvantage of Cronet Embedded is that it adds approximately 8MB to your application.
  3. Cronet Fallback: The fallback implementation of Cronet implements Cronet’s API as a wrapper around Android’s built-in network stack. It should not be used with ExoPlayer, since using Android’s built-in network stack directly (i.e., by using DefaultHttpDataSource) is more efficient.

OkHttp

OkHttp is another modern network stack that is widely used by many popular Android applications. It supports HTTP and HTTP/2, but does not yet support HTTP/3 over QUIC.

ExoPlayer supports OkHttp via its OkHttp extension. Please see the extension’s README.md for detailed instructions on how to use it. When using the OkHttp extension, the network stack is embedded within the application. This is similar to Cronet Embedded, however OkHttp is significantly smaller, adding under 1MB to your application.

Android’s built-in network stack

ExoPlayer supports use of Android’s built-in network stack with DefaultHttpDataSource and DefaultHttpDataSource.Factory, which are part of the core ExoPlayer library.

The exact network stack implementation depends on the software running on the underlying device. On most devices (as of 2021) only HTTP is supported (i.e., HTTP/2 and HTTP/3 over QUIC are not supported).

Other network stacks

It’s possible for applications to integrate other network stacks with ExoPlayer. To do this, implement an HttpDataSource that wraps the network stack, together with a corresponding HttpDataSource.Factory. ExoPlayer’s Cronet and OkHttp extensions are good examples of how to do this.

When integrating with a pure Java network stack, it’s a good idea to implement a DataSourceContractTest to check that your HttpDataSource implementation behaves correctly. OkHttpDataSourceContractTest in the OkHttp extension is a good example of how to do this.

Choosing a network stack

The table below outlines the pros and cons of the network stacks supported by ExoPlayer.

Network stack Protocols APK size impact Notes
Cronet (Google Play Services) HTTP
HTTP/2
HTTP/3 over QUIC
Small
(<100KB)
Requires Google Play Services. Cronet version updated automatically
Cronet (Embedded) HTTP
HTTP/2
HTTP/3 over QUIC
Large
(~8MB)
Cronet version controlled by app developer
Cronet (Fallback) HTTP
(varies by device)
Small
(<100KB)
Not recommended for ExoPlayer
OkHttp HTTP
HTTP/2
Small
(<1MB)
Requires Kotlin runtime
Built-in network stack HTTP
(varies by device)
None Implementation varies by device

The HTTP/2 and HTTP/3 over QUIC protocols can significantly improve media streaming performance. In particular when streaming adaptive media distributed via a content distribution network (CDN), there are cases for which use of these protocols can allow CDNs to operate much more efficiently. For this reason, Cronet’s support for both HTTP/2 and HTTP/3 over QUIC (and OkHttp’s support for HTTP/2), is a major benefit compared to using Android’s built-in network stack, provided the servers on which the content is hosted also support these protocols.

When considering media streaming in isolation, we recommend use of Cronet provided by Google Play Services, falling back to DefaultHttpDataSource if Google Play Services is unavailable. This recommendation strikes a good balance between enabling use of HTTP/2 and HTTP/3 over QUIC on most devices, and avoiding a significant increase in APK size. There are exceptions to this recommendation. For cases where Google Play Services is likely to be unavailable on a significant fraction of devices that will be running your application, using Cronet Embedded or OkHttp may be more appropriate. Use of the built-in network stack may be acceptable if APK size is a critical concern, or if media streaming is only a minor part of your application’s functionality.

Beyond just media, it’s normally a good idea to choose a single network stack for all of the networking performed by your application. This allows resources (e.g., sockets) to be efficiently pooled and shared between ExoPlayer and other application components.

To assist with resource sharing, it’s recommended to use a single CronetEngine or OkHttpClient instance throughout your application, when using Cronet or OkHttp respectively.

Since your application will most likely need to perform networking not related to media playback, your choice of network stack should ultimately factor in our recommendations above for media streaming in isolation, the requirements of any other components that perform networking, and their relative importance to your application.