پشته های شبکه

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

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

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

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

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

کاتلین

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

جاوا

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

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

مثال زیر نحوه ساخت یک 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 و پشته شبکه پیش فرض داخلی اندروید را ارائه می دهد. ExoPlayer همچنین می تواند برای پشتیبانی از هر پشته شبکه دیگری که در Android کار می کند گسترش یابد.

HttpEngine

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

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

کرونت

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

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

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

OkHttp

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

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

پشته شبکه داخلی اندروید

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

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

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

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

هنگام ادغام با یک پشته شبکه جاوا خالص، ایده خوبی است که یک 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
کوچک
(<100KB)
به خدمات Google Play نیاز دارد. نسخه کرونت به طور خودکار به روز شد
کرونت (جاسازی شده) HTTP
HTTP/2
HTTP/3 از طریق QUIC
بزرگ
(~8 مگابایت)
نسخه Cronet توسط توسعه دهنده برنامه کنترل می شود
کرونت (بازگشت) HTTP
(بر اساس دستگاه متفاوت است)
کوچک
(<100KB)
برای ExoPlayer توصیه نمی شود
OkHttp HTTP
HTTP/2
کوچک
(<1 مگابایت)
پشته شبکه داخلی HTTP
(بر اساس دستگاه متفاوت است)
هیچ کدام پیاده سازی بر اساس دستگاه متفاوت است

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

هنگامی که جریان رسانه را به صورت مجزا در نظر می گیریم، توصیه می کنیم در صورت در دسترس نبودن سرویس های Google Play، از HttpEngine یا Cronet ارائه شده توسط Google Play Services استفاده کنید که به 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();