يتم استخدام ExoPlayer عادةً لبث الوسائط على الإنترنت. وهي تدعم حزم شبكات متعددة لإجراء طلبات الشبكة الأساسية. الخيار لك من حزم الشبكات التي لها تأثير كبير في أداء البث.
تحدد هذه الصفحة كيفية تهيئة ExoPlayer لاستخدام حزمة الشبكة الاختيار، وتسرد الخيارات المتاحة، وتوفر بعض الإرشادات حول كيفية اختيار حزمة شبكة لتطبيقك، وتشرح كيفية تفعيل التخزين المؤقت للتطبيقات التي يتم بثها الوسائط.
إعداد ExoPlayer لاستخدام حزمة شبكة محدّدة
يحمّل ExoPlayer البيانات من خلال مكوّنات DataSource
التي يحصل عليها من
تم إدخال DataSource.Factory
مثيل من رمز التطبيق.
إذا كان تطبيقك يحتاج إلى تشغيل محتوى http(s) فقط، يُرجى اختيار شبكة.
يمكن بسهولة تحديث أي مثيلات DataSource.Factory
التي
حقن التطبيق ليكون مثيلاً لـ HttpDataSource.Factory
الذي يتجاوب مع مكدس الشبكة الذي ترغب في استخدامه. إذا كان تطبيقك أيضًا
إلى تشغيل محتوى بخلاف http(s) المحتوى، مثل الملفات المحلية، واستخدام
DefaultDataSource.Factory
:
Kotlin
DefaultDataSource.Factory( ... /* baseDataSourceFactory= */ PreferredHttpDataSource.Factory(...))
Java
new DefaultDataSource.Factory( ... /* baseDataSourceFactory= */ new PreferredHttpDataSource.Factory(...));
في هذا المثال، PreferredHttpDataSource.Factory
هو الشركة المصنعة المتوافقة مع
مكدس الشبكة المفضل. تمنح طبقة DefaultDataSource.Factory
الدعم
للمصادر التي ليست http(s) مثل الملفات المحلية.
يوضّح المثال التالي كيفية إنشاء ExoPlayer
يستخدم Cronet.
تكديس الشبكة وأيضًا دعم تشغيل محتوى بخلاف http(s).
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();
حزم الشبكات المتوافقة
توفر ExoPlayer دعمًا مباشرًا لكل من HttpEngine وCronet وOkHttp وتطبيقات Android حزمة شبكة افتراضية مدمجة. يمكن أيضًا توسيع نطاق ExoPlayer لإتاحة استخدام حزمة شبكة أخرى تعمل على نظام Android.
محرّك HttpEngine
HttpEngine هو تكديس الشبكة التلقائي الموصى به على نظام التشغيل Android من واجهة برمجة التطبيقات 34 (أو S) الإضافات 7). في معظم الحالات، يستخدم مكدس شبكة Cronet داخليًا، دعم HTTP وHTTP/2 وHTTP/3 عبر بروتوكولات QUIC.
يدعم ExoPlayer استخدام HttpEngine مع HttpEngineDataSource.Factory
. يمكنك
إدخال مصنع مصدر البيانات هذا كما هو موضح في تهيئة ExoPlayer لاستخدام
حزم الشبكة.
كرونيه
Cronet هي تم توفير حزمة شبكة Chromium لتطبيقات Android كمكتبة. مسافة Cronet تقنيات متعددة تقلل من وقت الاستجابة وتزيد من سرعة معالجة طلبات الشبكة التي يحتاجها تطبيقك للعمل، بما في ذلك تلك التي أنشأها ExoPlayer. وهو يدعم في الأصل HTTP وHTTP/2 وHTTP/3 عبر QUIC والبروتوكولات. يتم استخدام Cronet من قبل بعض من أكبر تطبيقات البث في العالم بما في ذلك YouTube.
ExoPlayer يدعم Cronet من خلال
مكتبة Cronet.
اطّلِع على README.md
في المكتبة للحصول على تعليمات مفصّلة حول كيفية استخدام هذه الصفحة.
بها. تجدر الإشارة إلى أنّ مكتبة Cronet يمكنها استخدام ثلاثة عناصر أساسية من Cronet
عمليات التنفيذ:
- خدمات Google Play: ننصح باستخدام طريقة التنفيذ هذه في معظم
وحالات استخدام حزمة الشبكة المدمَجة في Android
(
DefaultHttpDataSource
) إذا لم تكن "خدمات Google Play" متاحة. - Cronet Embed: قد يكون خيارًا جيدًا إذا كانت هناك نسبة كبيرة من المستخدمين في أسواق لا تتوفر فيها "خدمات Google Play" على نطاق واسع، أو إذا كان نريد التحكم في الإصدار الدقيق لتنفيذ Cronet المستخدَم. تشير رسالة الأشكال البيانية من العيب الرئيسي في Cronet Embed هو أنها تضيف حوالي 8 ميغابايت تطبيقك.
- Cronet Fallback: عملية التنفيذ الاحتياطية التي يتم تنفيذها في Cronet
واجهة برمجة التطبيقات Cronet's كبرنامج تشغيل لحِزم الشبكات المدمجة في Android يجب
لا يتم استخدامها مع ExoPlayer، نظرًا لأن استخدام حزمة الشبكة المدمجة في Android
مباشرةً (باستخدام
DefaultHttpDataSource
) أكثر كفاءة.
OkHttp
تُعد OkHttp مكدس شبكة حديث آخر يُستخدم على نطاق واسع في العديد من تطبيقات Android الرائجة. وهو يدعم HTTP HTTP/2، لكنه لا يدعم حتى الآن HTTP/3 عبر QUIC.
يدعم ExoPlayer استخدام OkHttp من خلال
مكتبة OkHttp.
اطّلِع على README.md
في المكتبة للحصول على تعليمات مفصّلة حول كيفية استخدام هذه الصفحة.
بها. عند استخدام مكتبة OkHttp، يتم تضمين مكدس الشبكة داخل
التطبيق. وهو ما يشبه Cronet Include، إلا أن OkHttp يتم بشكل كبير
أصغر، مع إضافة أقل من 1 ميغابايت إلى التطبيق.
حزمة الشبكة المدمجة في Android
يتيح ExoPlayer استخدام حزمة الشبكة المدمجة في Android مع
DefaultHttpDataSource
وDefaultHttpDataSource.Factory
، وهما جزء من
مكتبة ExoPlayer الأساسية.
يعتمد التنفيذ الدقيق لحزمة الشبكة على البرنامج الذي يعمل على الجهاز الأساسي. في معظم الأجهزة، يتم دعم HTTP فقط (أي HTTP/2 وHTTP/3 عبر QUIC غير متاحين).
حزم الشبكات الأخرى
ويمكن للتطبيقات أيضًا دمج حزم شبكات أخرى مع ExoPlayer.
لإجراء ذلك، يجب تنفيذ HttpDataSource
الذي يلتفّ حزمة الشبكة.
مع HttpDataSource.Factory
مطابق. بطاقات Cronet من ExoPlayer
وتُعد مكتبات OkHttp أمثلة جيدة على كيفية القيام بذلك.
عند الدمج مع مكدس شبكة Java خالص، من الأفضل تنفيذ
DataSourceContractTest
للتحقّق من أنّ عملية تنفيذ HttpDataSource
يتصرف بشكل صحيح. يُعد OkHttpDataSourceContractTest
في مكتبة OkHttp
مثال جيد على كيفية القيام بذلك.
اختيار تكديس شبكة
يوضّح الجدول التالي إيجابيات وسلبيات حِزم الشبكة المتوافقة مع ExoPlayer.
حزم الشبكات | البروتوكولات | تأثير حجم حزمة APK | ملاحظات |
---|---|---|---|
محرّك HttpEngine | HTTP HTTP/2 HTTP/3 عبر QUIC |
بدون تحديد نمط | متوفّرة فقط على واجهة برمجة التطبيقات 34 أو S الإضافات 7 |
Cronet (خدمات Google Play) | HTTP HTTP/2 HTTP/3 عبر QUIC |
صغيرة (<100 كيلوبايت) |
يجب استخدام خدمات Google Play. تم تحديث إصدار Cronet تلقائيًا |
Cronet (مضمّن) | HTTP HTTP/2 HTTP/3 عبر QUIC |
كبير (حوالي 8 ميغابايت) |
إصدار Cronet الذي يتحكّم فيه مطوِّر التطبيقات |
Cronet (الاحتياطي) | HTTP (يختلف حسب الجهاز) |
صغيرة (<100 كيلوبايت) |
لا يُنصح باستخدامه مع ExoPlayer |
OkHttp | HTTP HTTP/2 |
صغيرة (<1 ميغابايت) |
|
حزمة شبكة مدمجة | HTTP (يختلف حسب الجهاز) |
بدون تحديد نمط | تختلف خطوات التنفيذ حسب الجهاز. |
يمكن لبروتوكول HTTP/2 وHTTP/3 عبر بروتوكولات QUIC تحسين الوسائط بشكل كبير. أداء البث. وعلى وجه الخصوص، عند بث الوسائط التكيُّفية ذات باستخدام شبكة توزيع المحتوى (CDN)، فهناك حالات التي تتيح استخدام هذه البروتوكولات لشبكات توصيل المحتوى (CDN) بالعمل بكفاءة أكبر. لهذا السبب، يدعم كل من HttpEngine وCronet كلاً من HTTP/2 وHTTP/3 عبر QUIC (ودعم OkHttp لبروتوكول HTTP/2)، يعد فائدة كبيرة مقارنةً باستخدام مكدس الشبكة المدمج في Android، شريطة أن يتم توفير الخوادم المحتوى المستضاف أيضًا تدعم هذه البروتوكولات.
عند التفكير في بث الوسائط بشكل منفصل، نوصي باستخدام HttpEngine أو
إصدار Cronet المقدَّم من "خدمات Google Play" بدءًا من DefaultHttpDataSource
إذا كانت "خدمات Google Play" غير متاحة يحقق هذا الاقتراح فائدة
التوازن بين تفعيل استخدام HTTP/2 وHTTP/3 عبر QUIC على معظم الأجهزة،
مع تجنُّب حدوث زيادة كبيرة في حجم حِزم APK. هناك استثناءات لذلك
والتوصية بها. للحالات التي يُحتمل عدم توفّر "خدمات Google Play" فيها
على عدد كبير من الأجهزة التي ستشغّل تطبيقك
باستخدام Cronet Embed أو OkHttp. استخدام الميزات المدمجة
قد يكون استخدام حزمة الشبكة مقبولاً إذا كان حجم حزمة APK مصدر قلق كبير أو إذا كان الوسائط
فإن البث ليس سوى جزء بسيط من وظائف التطبيق.
بالإضافة إلى الوسائط فقط، من الأفضل اختيار حزمة شبكة واحدة لجميع الشبكات التي يؤديها تطبيقك. يتيح ذلك استخدام الموارد (مثل المقابس) ليتم تجميعها ومشاركتها بكفاءة بين ExoPlayer وغيرها من مكونات التطبيق.
لأنّ تطبيقك سيحتاج على الأرجح إلى إجراء اتصال بالشبكة لتشغيل الوسائط، فإن اختيارك لحزمة الشبكة يجب أن يكون العامل الأساسي في الواردة أعلاه لبث الوسائط بمعزل عن غيرها، ومتطلبات والمكونات الأخرى التي تؤدي الشبكات، وأهميتها النسبية التطبيق.
تخزين الوسائط في ذاكرة التخزين المؤقت
يدعم ExoPlayer التخزين المؤقت لوحدات البايت المحمَّلة على القرص لمنع تكرار التحميل. وحدات البايت نفسها من الشبكة. ويكون هذا مفيدًا عند إرجاع الفيديو في الوقت الحالي. الوسائط أو تكرار العنصر ذاته.
يتطلّب التخزين المؤقت توفّر مثيل SimpleCache
يشير إلى ذاكرة تخزين مؤقت مخصَّصة.
الدليل و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();