پشته های شبکه

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

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

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

ExoPlayer داده‌ها را از طریق کامپوننت‌های DataSource بارگذاری می‌کند، که از نمونه‌های DataSource.Factory که از کد برنامه تزریق شده‌اند، به دست می‌آورد.

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

کاتلین

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

جاوا

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

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

موتور Http

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

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

کرونت

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

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

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

اوکی‌اچ‌تی‌پی

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

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

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

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

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

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

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

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

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

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

پشته شبکه پروتکل‌ها تأثیر حجم APK یادداشت‌ها
موتور Http اچ‌تی‌پی
HTTP/2
HTTP/3 روی QIC
هیچکدام فقط در API 34 یا S Extensions 7 موجود است
کرونت (خدمات گوگل پلی) اچ‌تی‌پی
HTTP/2
HTTP/3 روی QIC
کوچک
(<100 کیلوبایت)
به خدمات گوگل پلی نیاز دارد. نسخه کرونت به صورت خودکار به‌روزرسانی می‌شود.
کرونت (جاسازی شده) اچ‌تی‌پی
HTTP/2
HTTP/3 روی QIC
بزرگ
(~۸ مگابایت)
نسخه Cronet توسط توسعه‌دهنده برنامه کنترل می‌شود
کرونت (جایگزین) اچ‌تی‌پی
(بسته به دستگاه متفاوت است)
کوچک
(<100 کیلوبایت)
برای ExoPlayer توصیه نمی‌شود
اوکی‌اچ‌تی‌پی اچ‌تی‌پی
HTTP/2
کوچک
(کمتر از ۱ مگابایت)
پشته شبکه داخلی اچ‌تی‌پی
(بسته به دستگاه متفاوت است)
هیچکدام پیاده‌سازی بر اساس دستگاه متفاوت است

پروتکل‌های 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 از ذخیره بایت‌های بارگذاری شده در دیسک پشتیبانی می‌کند تا از بارگذاری مکرر بایت‌های مشابه از شبکه جلوگیری شود. این قابلیت هنگام جستجوی مجدد در رسانه فعلی یا تکرار یک آیتم مشابه مفید است.

ذخیره سازی داده (caching) نیاز به یک نمونه SimpleCache دارد که به یک دایرکتوری cache اختصاصی و یک 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();