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

‫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 7) است. در اکثر موارد، به‌صورت داخلی از پشته شبکه Cronet استفاده می‌کند و از پروتکل‌های HTTP،‏ HTTP/2، و HTTP/3 روی QUIC پشتیبانی می‌کند.

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

Cronet

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

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

  1. خدمات Google Play: توصیه می‌کنیم در اکثر موارد از این پیاده‌سازی استفاده کنید و اگر «خدمات Google Play» دردسترس نبود، به پشته شبکه داخلی Android (DefaultHttpDataSource) برگردید.
  2. Cronet جاسازی‌شده: اگر درصد بالایی از کاربران شما در بازارهایی باشند که «خدمات Google Play» در آن‌ها به‌طور گسترده دردسترس نیست، یا اگر می‌خواهید نسخه دقیق پیاده‌سازی Cronet مورداستفاده را کنترل کنید، ممکن است انتخاب خوبی باشد. عیب اصلی Cronet Embedded این است که تقریباً ۸ مگابایت به برنامه شما اضافه می‌کند.
  3. Cronet Fallback: پیاده‌سازی بازگشتی Cronet،‏ API‏ Cronet را به‌عنوان بسته‌بندی پیرامون پشته شبکه داخلی Android پیاده‌سازی می‌کند. نباید با ExoPlayer استفاده شود، زیرا استفاده مستقیم از پشته شبکه داخلی Android (بااستفاده از DefaultHttpDataSource) کارآمدتر است.

OkHttp

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

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

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

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

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

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

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

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

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

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

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