پشته‌های شبکه

ExoPlayer معمولاً برای جاری‌سازی رسانه ازطریق اینترنت استفاده می‌شود. این مرورگر از پشته‌های شبکه متعدد برای ایجاد درخواست‌های شبکه اساسی خود پشتیبانی می‌کند. انتخاب شما از پشته شبکه می‌تواند تأثیر قابل‌توجهی بر عملکرد جاری‌سازی داشته باشد.

این صفحه نحوه پیکربندی ExoPlayer را برای استفاده از پشته شبکه انتخابی شما شرح می‌دهد، گزینه‌های دردسترس را فهرست می‌کند، راهنمایی‌هایی درباره نحوه انتخاب پشته شبکه برای برنامه‌تان ارائه می‌دهد، و نحوه فعال کردن ذخیره‌سازی مؤقت برای رسانه جاری را توضیح می‌دهد.

پیکربندی ExoPlayer برای استفاده از پشته شبکه خاص

ExoPlayer داده‌ها را ازطریق مؤلفه‌های DataSource بار می‌کند که آن‌ها را از نمونه‌های DataSource.Factory که از کد برنامه تزریق شده‌اند دریافت می‌کند.

اگر برنامه‌تان فقط نیاز به پخش محتوای http(s) دارد، انتخاب پشته شبکه به سادگی به‌روزرسانی هر نمونه DataSource.Factory است که برنامه‌تان تزریق می‌کند تا نمونه‌هایی از HttpDataSource.Factory باشد که با پشته شبکه‌ای که می‌خواهید استفاده کنید مطابقت دارد. اگر برنامه‌تان همچنین نیاز به پخش محتوای غیر http(s) دارد، مثل فایل‌های محلی، از DefaultDataSource.Factory استفاده کنید:

کاتلین

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

جاوا

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

در این مثال، PreferredHttpDataSource.Factory کارخانه مربوط به پشته شبکه ترجیحی شما است. لایه DefaultDataSource.Factory پشتیبانی از منابع غیر http(s) مانند فایل‌های محلی را اضافه می‌کند.

مثال زیر نحوه ساختن ExoPlayer را نشان می‌دهد که از پشته شبکه Cronet استفاده می‌کند و همچنین از بازپخش محتوای غیر http(s) پشتیبانی می‌کند.

کاتلین

// 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()

جاوا

// 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();

پشته‌های شبکه پشتیبانی‌شده

ExoPlayer پشتیبانی مستقیم از HttpEngine،‏ Cronet،‏ OkHttp، و پشته شبکه پیش‌فرض داخلی Android ارائه می‌دهد. ExoPlayer را می‌توان برای پشتیبانی از هر پشته شبکه دیگری که در Android کار می‌کند نیز گسترش داد.

HttpEngine

HttpEngine پشته شبکه پیش‌فرض توصیه‌شده در Android از میانای برنامه‌سازی کاربردی ۳۴ (یا S افزونه‌های ۷) است. در بیشتر موارد، از پشته شبکه Cronet به‌طور داخلی استفاده می‌کند، و از پروتکل‌های HTTP،‏ HTTP/2، و HTTP/3 روی QUIC پشتیبانی می‌کند.

ExoPlayer از HttpEngine با HttpEngineDataSource.Factory خود پشتیبانی می‌کند. می‌توانید این کارخانه منبع داده را همان‌طور که در پیکربندی ExoPlayer برای استفاده از پشته شبکه خاص شرح داده شده است تزریق کنید.

Cronet

Cronet پشته شبکه Chromium است که به‌عنوان کتابخانه برای برنامه‌های Android دردسترس قرار گرفته است. Cronet از چندین فناوری بهره می‌برد که تأخیر را کاهش می‌دهند و توان عملیاتی درخواست‌های شبکه را که برنامه‌تان برای کار کردن نیاز دارد افزایش می‌دهند، ازجمله درخواست‌هایی که توسط ExoPlayer انجام می‌شود. این کتابخانه به‌طور پیش‌فرض از پروتکل‌های HTTP،‏ HTTP/2، و HTTP/3 روی QUIC پشتیبانی می‌کند. برخی‌از بزرگ‌ترین برنامه‌های جاری‌سازی در جهان، ازجمله YouTube، از Cronet استفاده می‌کنند.

ExoPlayer از Cronet ازطریق کتابخانه Cronet خود پشتیبانی می‌کند. برای دستورالعمل‌های دقیق درباره نحوه استفاده از کتابخانه، به README.md آن مراجعه کنید. توجه داشته باشید که کتابخانه Cronet می‌تواند از سه پیاده‌سازی Cronet زیربنایی استفاده کند:

  1. خدمات Google Play: توصیه می‌کنیم در اکثر موارد از این پیاده‌سازی استفاده کنید و اگر «خدمات Google Play» دردسترس نبود، به پشته شبکه داخلی Android (DefaultHttpDataSource) برگردید.
  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. عیب بزرگ Cronet Embedded این است که حدود ۸ مگابایت به برنامه شما اضافه می‌کند.
  3. Cronet Fallback: پیاده‌سازی بازگشتی Cronet، میانای برنامه‌سازی کاربردی Cronet را به‌عنوان پوششی در اطراف پشته شبکه داخلی Android پیاده‌سازی می‌کند. نباید با ExoPlayer استفاده شود، زیرا استفاده مستقیم از پشته شبکه داخلی Android (بااستفاده از DefaultHttpDataSource) کارآمدتر است.

OkHttp

OkHttp پشته شبکه مدرن دیگری است که به‌طور گسترده توسط بسیاری از برنامه‌های محبوب Android استفاده می‌شود. این ابزار از HTTP و HTTP/2 پشتیبانی می‌کند، اما هنوز از HTTP/3 روی QUIC پشتیبانی نمی‌کند.

ExoPlayer ازطریق کتابخانه OkHttp خود از OkHttp پشتیبانی می‌کند. برای دستورالعمل‌های دقیق درباره نحوه استفاده از کتابخانه، به README.md آن مراجعه کنید. هنگام استفاده از کتابخانه OkHttp، پشته شبکه در برنامه جاسازی می‌شود. این شبیه به Cronet Embedded است، اما OkHttp به‌طور قابل‌توجهی کوچک‌تر است و کمتر از ۱ مگابایت به برنامه شما اضافه می‌کند.

پشته شبکه داخلی Android

ExoPlayer از استفاده از پشته شبکه داخلی Android با DefaultHttpDataSource و DefaultHttpDataSource.Factory که بخشی از کتابخانه اصلی ExoPlayer هستند پشتیبانی می‌کند.

پیاده‌سازی دقیق پشته شبکه به نرم‌افزاری بستگی دارد که در دستگاه زیربنایی اجرا می‌شود. در اکثر دستگاه‌ها فقط HTTP پشتیبانی می‌شود (یعنی HTTP/2 و HTTP/3 ازطریق QUIC پشتیبانی نمی‌شوند).

پشته‌های شبکه دیگر

برنامه‌ها همچنین می‌توانند پشته‌های شبکه دیگر را با ExoPlayer ادغام کنند. برای انجام این کار، HttpDataSource را که پشته شبکه را دربرمی‌گیرد، همراه با HttpDataSource.Factory مربوطه پیاده‌سازی کنید. کتابخانه‌های Cronet و OkHttp در ExoPlayer نمونه‌های خوبی از نحوه انجام این کار هستند.

هنگام ادغام با پشته شبکه Java خالص، ایده خوبی است که یک DataSourceContractTest را پیاده‌سازی کنید تا بررسی کنید که پیاده‌سازی HttpDataSource شما به‌درستی رفتار می‌کند. OkHttpDataSourceContractTest در کتابخانه OkHttp نمونه خوبی از نحوه انجام این کار است.

انتخاب پشته شبکه

جدول زیر مزایا و معایب پشته‌های شبکه پشتیبانی‌شده توسط ExoPlayer را نشان می‌دهد.

پشته شبکه پروتکل‌ها تأثیر اندازه APK یادداشت‌ها
HttpEngine HTTP
HTTP/2
HTTP/3 over QUIC
هیچ‌کدام فقط در API 34 یا S Extensions 7 دردسترس است
Cronet (خدمات Google Play) ‫HTTP
HTTP/2
HTTP/3 over QUIC
کوچک
(<۱۰۰ کیلوبایت)
به «خدمات Google Play» نیاز دارد. نسخه Cronet به‌طور خودکار به‌روز شد
Cronet (جاسازی‌شده) ‫HTTP
HTTP/2
HTTP/3 over QUIC
بزرگ
(~۸ مگابایت)
نسخه Cronet تحت کنترل توسعه‌دهنده نرم‌افزار است
Cronet (جایگزین) HTTP
(بسته به دستگاه متفاوت است)
کوچک
(<۱۰۰ کیلوبایت)
برای ExoPlayer توصیه نمی‌شود
OkHttp HTTP
HTTP/2
کوچک
(<۱ مگابایت)
پشته شبکه داخلی HTTP
(بسته به دستگاه متفاوت است)
هیچ‌کدام پیاده‌سازی بسته به دستگاه متفاوت است

پروتکل‌های HTTP/2 و HTTP/3 روی QUIC می‌توانند عملکرد جاری‌سازی رسانه را به‌طور قابل‌توجهی بهبود بخشند. به‌ویژه، هنگام جاری‌سازی رسانه تطبیقی که بااستفاده از شبکه توزیع محتوا (CDN) توزیع می‌شود، مواردی وجود دارد که استفاده از این پروتکل‌ها می‌تواند به CDNها اجازه دهد بسیار کارآمدتر عمل کنند. به همین دلیل، پشتیبانی HttpEngine و Cronet از HTTP/2 و HTTP/3 ازطریق QUIC (و پشتیبانی OkHttp از HTTP/2) مزیت بزرگی نسبت‌به استفاده از پشته شبکه داخلی Android است، به‌شرطی که سرورهایی که محتوا در آن‌ها میزبانی می‌شود نیز از این پروتکل‌ها پشتیبانی کنند.

هنگام درنظر گرفتن جاری‌سازی رسانه به‌صورت مجزا، توصیه می‌کنیم از HttpEngine یا Cronet ارائه‌شده توسط «خدمات Google Play» استفاده کنید و درصورت دردسترس نبودن «خدمات Google Play»، به DefaultHttpDataSource برگردید. این توصیه تعادل خوبی بین فعال کردن استفاده از HTTP/2 و HTTP/3 روی QUIC در اکثر دستگاه‌ها و جلوگیری از افزایش قابل‌توجه اندازه APK برقرار می‌کند. این توصیه استثناهایی دارد. در مواردی که احتمالاً «خدمات Google Play» در بخش قابل‌توجهی از دستگاه‌هایی که برنامه شما را اجرا می‌کنند دردسترس نباشد، استفاده از Cronet Embedded یا OkHttp ممکن است مناسب‌تر باشد. اگر اندازه APK نگرانی مهمی باشد یا اگر جاری‌سازی رسانه فقط بخش کوچکی از عملکرد برنامه‌تان باشد، استفاده از پشته شبکه داخلی ممکن است قابل‌قبول باشد.

فراتر از رسانه، معمولاً ایده خوبی است که یک پشته شبکه واحد را برای تمام شبکه‌سازی‌های انجام‌شده توسط برنامه‌تان انتخاب کنید. این کار به منابع (مانند سوکت‌ها) اجازه می‌دهد به‌طور کارآمدی بین ExoPlayer و دیگر مؤلفه‌های برنامه جمع‌آوری و هم‌رسانی شوند.

ازآنجاکه برنامه شما به‌احتمال زیاد نیاز به انجام شبکه‌سازی غیرمرتبط با بازپخش رسانه دارد، انتخاب پشته شبکه شما درنهایت باید توصیه‌های ما در بالا را برای جاری‌سازی رسانه به‌صورت مجزا، الزامات هر مؤلفه دیگری که شبکه‌سازی را انجام می‌دهد، و اهمیت نسبی آن‌ها برای برنامه شما درنظر بگیرد.

درحال ذخیره کردن رسانه در حافظه نهان

ExoPlayer از ذخیره کردن بایت‌های بارشده در حافظه پنهان دیسک پشتیبانی می‌کند تا از بار شدن مکرر همان بایت‌ها از شبکه جلوگیری کند. این کار هنگام جستجوی عقب در رسانه فعلی یا تکرار همان مورد مفید است.

ذخیره در حافظه پنهان به نمونه SimpleCache نیاز دارد که به دایرکتوری حافظه پنهان اختصاصی و CacheDataSource.Factory اشاره می‌کند:

کاتلین

// 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()

جاوا

// 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();