Stack jaringan

ExoPlayer biasanya digunakan untuk streaming media melalui internet. Mendukung beberapa tumpukan jaringan untuk membuat permintaan jaringan yang mendasarinya. Pilihanmu dari tumpukan jaringan dapat berdampak signifikan terhadap performa streaming.

Halaman ini menguraikan cara mengonfigurasi ExoPlayer untuk menggunakan stack jaringan Anda pilihan, mencantumkan opsi yang tersedia, memberikan beberapa panduan tentang cara memilih stack jaringan untuk aplikasi Anda, dan menjelaskan cara mengaktifkan caching untuk streaming lainnya.

Mengonfigurasi ExoPlayer untuk menggunakan stack jaringan tertentu

ExoPlayer memuat data melalui komponen DataSource, yang diperoleh dari Instance DataSource.Factory yang dimasukkan dari kode aplikasi.

Jika aplikasi Anda hanya perlu memutar konten http(s), memilih jaringan itu semudah memperbarui instance DataSource.Factory yang aplikasi yang diinjeksikan menjadi instance HttpDataSource.Factory yang sesuai dengan tumpukan jaringan yang ingin Anda gunakan. Jika aplikasi Anda juga perlu memutar konten non-http, seperti file lokal, gunakan DefaultDataSource.Factory:

Kotlin

DefaultDataSource.Factory(
  ...
  /* baseDataSourceFactory= */ PreferredHttpDataSource.Factory(...))

Java

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

Dalam contoh ini, PreferredHttpDataSource.Factory adalah factory yang sesuai dengan tumpukan jaringan pilihan Anda. Lapisan DefaultDataSource.Factory menambahkan dukungan untuk sumber non-http seperti file lokal.

Contoh berikut menunjukkan cara membuat ExoPlayer yang akan menggunakan Cronet tumpukan jaringan dan juga mendukung pemutaran konten non-http.

Kotlin

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

// Wrap the CronetDataSource.Factory in a DefaultDataSource.Factory, which adds
// in support for requesting data from other sources (such as files, resources,
// etc).
val dataSourceFactory =
  DefaultDataSource.Factory(context, /* baseDataSourceFactory= */ cronetDataSourceFactory)

// Inject the DefaultDataSource.Factory when creating the player.
val player =
  ExoPlayer.Builder(context)
    .setMediaSourceFactory(
      DefaultMediaSourceFactory(context).setDataSourceFactory(dataSourceFactory)
    )
    .build()

Java

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

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

// Inject the DefaultDataSource.Factory when creating the player.
ExoPlayer player =
    new ExoPlayer.Builder(context)
        .setMediaSourceFactory(
            new DefaultMediaSourceFactory(context).setDataSourceFactory(dataSourceFactory))
        .build();

Stack jaringan yang didukung

ExoPlayer memberikan dukungan langsung untuk HttpEngine, Cronet, OkHttp, dan Android {i>built-in <i}jaringan secara {i> default<i}. ExoPlayer juga dapat diperluas untuk mendukung tumpukan jaringan lain yang bekerja di Android.

HTTPEngine

HttpEngine adalah stack jaringan default yang direkomendasikan di Android dari API 34 (atau S ekstensi 7). Dalam kebanyakan kasus, ia menggunakan tumpukan jaringan Cronet secara internal, mendukung HTTP, HTTP/2, dan HTTP/3 melalui protokol QUIC.

ExoPlayer mendukung HttpEngine dengan HttpEngineDataSource.Factory-nya. Anda dapat menginjeksikan factory sumber data ini seperti yang dijelaskan dalam Mengonfigurasi ExoPlayer untuk menggunakan di stack jaringan tertentu.

Cronet

Cronet adalah Stack jaringan Chromium disediakan untuk aplikasi Android sebagai library. Cronet mengambil keunggulan multi-teknologi yang mengurangi latensi dan meningkatkan yang diperlukan aplikasi Anda agar berfungsi, termasuk permintaan yang dibuat oleh ExoPlayer. Secara native mendukung HTTP, HTTP/2, dan HTTP/3 melalui QUIC protokol yang sama. Cronet digunakan oleh beberapa aplikasi {i>streaming <i}terbesar di dunia, termasuk YouTube.

ExoPlayer mendukung Cronet melalui Library Crnet. Lihat README.md library untuk petunjuk mendetail tentang cara menggunakan anotasi. Perlu diketahui bahwa library Cronet dapat menggunakan tiga fungsi Cronet yang mendasarinya, implementasi:

  1. Layanan Google Play: Sebaiknya gunakan penerapan ini di sebagian besar aplikasi kasus, dan penggantian ke stack jaringan bawaan Android (DefaultHttpDataSource) jika Layanan Google Play tidak tersedia.
  2. Cronet Embedded: Mungkin merupakan pilihan yang bagus jika sejumlah besar pengguna Anda berada di pasar tempat Layanan Google Play tidak tersedia secara luas, atau jika Anda ingin mengontrol versi implementasi Cronet yang digunakan. Tujuan kelemahan utama dari Cronet Embedded adalah penggunaannya kurang lebih 8 MB untuk aplikasi Anda.
  3. Penggantian Cronet: Penerapan penggantian Cronet API Cronet sebagai wrapper di sekitar stack jaringan bawaan Android. Seharusnya tidak digunakan dengan ExoPlayer, karena menggunakan stack jaringan bawaan Android secara langsung (dengan menggunakan DefaultHttpDataSource) menjadi lebih efisien.

OkHttp

OkHttp adalah stack jaringan modern lainnya yang banyak digunakan oleh banyak aplikasi Android populer. OpenVPN mendukung HTTP dan HTTP/2, tetapi belum mendukung HTTP/3 melalui QUIC.

ExoPlayer mendukung OkHttp melalui Library OkHttp. Lihat README.md library untuk petunjuk mendetail tentang cara menggunakan anotasi. Saat menggunakan library OkHttp, tumpukan jaringan disematkan dalam . Ini mirip dengan Cronet Embedded, tetapi OkHttp secara signifikan lebih kecil, dengan menambah kurang dari 1 MB ke aplikasi Anda.

Stack jaringan bawaan Android

ExoPlayer mendukung penggunaan stack jaringan bawaan Android dengan DefaultHttpDataSource dan DefaultHttpDataSource.Factory, yang merupakan bagian dari library inti ExoPlayer.

Implementasi tumpukan jaringan yang tepat tergantung pada perangkat lunak yang berjalan pada perangkat dasar. Pada sebagian besar perangkat, hanya HTTP yang didukung (yaitu, HTTP/2 dan HTTP/3 melalui QUIC tidak didukung).

Stack jaringan lainnya

Aplikasi juga dapat mengintegrasikan stack jaringan lain dengan ExoPlayer. Untuk melakukannya, implementasikan HttpDataSource yang menggabungkan stack jaringan, bersama dengan HttpDataSource.Factory yang sesuai. Cronet dan ExoPlayer Library OkHttp adalah contoh yang baik tentang cara melakukan ini.

Saat mengintegrasikan dengan tumpukan jaringan Java murni, sebaiknya implementasikan DataSourceContractTest untuk memeriksa apakah implementasi HttpDataSource Anda berperilaku dengan benar. OkHttpDataSourceContractTest di library OkHttp adalah contoh yang baik tentang bagaimana melakukan ini.

Memilih {i>stack <i}jaringan

Tabel berikut menguraikan pro dan kontra dari tumpukan jaringan yang didukung oleh ExoPlayer.

Stack jaringan Protokol Dampak ukuran APK Catatan
HTTPEngine HTTP
HTTP/2
HTTP/3 melalui QUIC
Tidak ada Hanya tersedia di API 34 atau Ekstensi S 7
Cronet (Layanan Google Play) HTTP
HTTP/2
HTTP/3 melalui QUIC
Kecil
(<100 KB)
Memerlukan Layanan Google Play. Versi Cronet diupdate secara otomatis
Cronet (Tersemat) HTTP
HTTP/2
HTTP/3 melalui QUIC
Besar
(~8 MB)
Versi Cronet yang dikontrol oleh developer aplikasi
Cronet (Penggantian) HTTP
(bervariasi menurut perangkat)
Kecil
(<100 KB)
Tidak direkomendasikan untuk ExoPlayer
OkHttp HTTP
HTTP/2
Kecil
(<1 MB)
Stack jaringan bawaan HTTP
(bervariasi menurut perangkat)
Tidak ada Penerapan bervariasi menurut perangkat

Protokol HTTP/2 dan HTTP/3 melalui QUIC dapat meningkatkan performa media secara signifikan performa streaming. Khususnya, saat melakukan streaming media adaptif didistribusikan menggunakan jaringan distribusi konten (CDN), ada kasus yang menggunakan protokol ini yang dapat membuat CDN beroperasi jauh lebih efisien. Untuk alasan ini, dukungan HttpEngine dan Cronet untuk HTTP/2 dan HTTP/3 melalui QUIC (dan dukungan OkHttp untuk HTTP/2), adalah manfaat utama dibandingkan dengan menggunakan tumpukan jaringan bawaan Android, menyediakan server tempat disini juga mendukung protokol ini.

Saat mempertimbangkan streaming media secara terpisah, sebaiknya gunakan HttpEngine atau Cronet yang disediakan oleh Layanan Google Play akan kembali ke DefaultHttpDataSource jika Layanan Google Play tidak tersedia. Rekomendasi ini memberikan teguran keseimbangan antara mengaktifkan penggunaan HTTP/2 dan HTTP/3 melalui QUIC di sebagian besar perangkat, dan agar tidak terjadi peningkatan ukuran APK yang signifikan. Ada pengecualian untuk rekomendasi. Untuk kasus saat Layanan Google Play kemungkinan tidak tersedia pada sebagian besar perangkat yang akan menjalankan aplikasi Anda, menggunakan Cronet Embedded atau OkHttp mungkin lebih tepat. Penggunaan layanan bawaan tumpukan jaringan mungkin dapat diterima jika ukuran APK menjadi masalah penting, atau jika jenis streaming hanyalah sebagian kecil dari fungsi aplikasi Anda.

Selain media, sebaiknya pilih satu stack jaringan untuk semua jaringan yang dilakukan oleh aplikasi Anda. Hal ini memungkinkan resource (seperti soket) untuk digabungkan dan dibagikan secara efisien antara ExoPlayer dan komponen aplikasi.

Karena aplikasi Anda kemungkinan besar perlu menjalankan jaringan yang tidak terkait ke pemutaran media, pilihan tumpukan jaringan Anda pada akhirnya harus mempertimbangkan rekomendasi di atas untuk streaming media secara terpisah, persyaratan dari komponen lain yang menjalankan jaringan, dan kepentingan relatifnya terhadap .

Menyimpan media dalam cache

ExoPlayer mendukung cache byte yang dimuat ke disk untuk mencegah pemuatan berulang byte yang sama dari jaringan. Ini berguna saat mencari kembali data saat ini media atau mengulangi item yang sama.

Menyimpan ke cache memerlukan instance SimpleCache yang mengarah ke cache khusus dan CacheDataSource.Factory.

Kotlin

// Note: This should be a singleton in your app.
val databaseProvider = StandaloneDatabaseProvider(context)

// An on-the-fly cache should evict media when reaching a maximum disk space limit.
val cache =
    SimpleCache(
        downloadDirectory, LeastRecentlyUsedCacheEvictor(maxBytes), databaseProvider)

// Configure the DataSource.Factory with the cache and factory for the desired HTTP stack.
val cacheDataSourceFactory =
    CacheDataSource.Factory()
        .setCache(cache)
        .setUpstreamDataSourceFactory(httpDataSourceFactory)

// Inject the DefaultDataSource.Factory when creating the player.
val player =
    ExoPlayer.Builder(context)
        .setMediaSourceFactory(
            DefaultMediaSourceFactory(context).setDataSourceFactory(cacheDataSourceFactory))
        .build()

Java

// Note: This should be a singleton in your app.
DatabaseProvider databaseProvider = new StandaloneDatabaseProvider(context);

// An on-the-fly cache should evict media when reaching a maximum disk space limit.
Cache cache =
    new SimpleCache(
        downloadDirectory, new LeastRecentlyUsedCacheEvictor(maxBytes), databaseProvider);

// Configure the DataSource.Factory with the cache and factory for the desired HTTP stack.
DataSource.Factory cacheDataSourceFactory =
    new CacheDataSource.Factory()
        .setCache(cache)
        .setUpstreamDataSourceFactory(httpDataSourceFactory);

// Inject the DefaultDataSource.Factory when creating the player.
ExoPlayer player =
    new ExoPlayer.Builder(context)
        .setMediaSourceFactory(
            new DefaultMediaSourceFactory(context).setDataSourceFactory(cacheDataSourceFactory))
        .build();