يُستخدَم 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
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 المضمّنة: قد تكون خيارًا جيدًا إذا كانت نسبة كبيرة من المستخدمين تقيم في أسواق لا تتوفّر فيها "خدمات Google Play" على نطاق واسع، أو إذا كنت تريد التحكّم في الإصدار الدقيق لتنفيذ Cronet المستخدَم. تشير رسالة الأشكال البيانية من العيب الرئيسي في Cronet inline هو أنه يضيف حوالي 8 ميغابايت إلى تطبيقك.
- الطريقة الاحتياطية لاستخدام Cronet: تُنفِّذ الطريقة الاحتياطية لاستخدام Cronet
واجهة برمجة التطبيقات الخاصة بخدمة Cronet كحزمة حول حِزمة الشبكة المضمّنة في 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 و
OkHttp في ExoPlayer مثالَين جيدَين على كيفية إجراء ذلك.
عند الدمج مع مكدس شبكة Java خالص، من الأفضل تنفيذ
DataSourceContractTest
للتحقّق من أنّ عملية تنفيذ HttpDataSource
يتصرف بشكل صحيح. يُعدّ OkHttpDataSourceContractTest
في مكتبة OkHttp مثالاً جيدًا على كيفية تنفيذ ذلك.
اختيار تكديس شبكة
يوضّح الجدول التالي إيجابيات وسلبيات حِزم الشبكة المتوافقة مع ExoPlayer.
حزم الشبكات | البروتوكولات | تأثير حجم حزمة APK | ملاحظات |
---|---|---|---|
محرّك HttpEngine | بروتوكول HTTP HTTP/2 HTTP/3 عبر QUIC |
بدون تحديد نمط | لا تتوفّر إلا في واجهة برمجة التطبيقات 34 أو S Extensions 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 Embedded أو 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();