يتوافق ExoPlayer مع تنسيقات الصور التالية. راجِع مكتبات تحميل الصور لمعرفة كيفية الدمج مع المكتبات الخارجية التي قد توفّر إمكانية استخدام مجموعة مختلفة من التنسيقات.
| تنسيق الصورة | متاح | الملاحظات |
|---|---|---|
| BMP | نعم | |
| ملف GIF | لا | لا تتوفّر أداة الاستخراج |
| JPEG | نعم | |
| صورة Motion JPEG | نعم | صور ثابتة وفيديوهات متوافقة |
| JPEG Ultra HDR | نعم | الرجوع إلى النطاق الديناميكي العادي (SDR) قبل Android 14 أو على شاشات غير متوافقة مع النطاق العالي الديناميكية |
| PNG | نعم | |
| WebP | نعم | |
| HEIF/HEIC | نعم | |
| صورة حيّة بتنسيق HEIC | جزئيًا | الصور الثابتة فقط هي المتوافقة* |
| AVIF (المرجع) | نعم | يمكن فك ترميزها على أجهزة Android 14 والإصدارات الأحدث فقط |
* يمكن الحصول على جزء الفيديو من الصور الحية بتنسيق HEIC باستخدام MetadataRetriever وتشغيله كملف مستقل.
استخدام MediaItem
لتشغيل صورة كجزء من قائمة تشغيل، أنشئ MediaItem باستخدام معرّف الموارد المنتظم (URI) الخاص بالصورة
وقدّمه إلى المشغّل. يجب أن يتضمّن MediaItem imageDurationMs لتحديد مدة عرض الصورة.
Kotlin
// Create a player instance. val player = ExoPlayer.Builder(context).build() // Set the media item to be played with the desired duration. player.setMediaItem( MediaItem.Builder().setUri(imageUri).setImageDurationMs(2000).build()) // Prepare the player. player.prepare()
Java
// Create a player instance. ExoPlayer player = new ExoPlayer.Builder(context).build(); // Set the media item to be played with the desired duration. player.setMediaItem( new MediaItem.Builder().setUri(imageUri).setImageDurationMs(2000).build()); // Prepare the player. player.prepare();
الصور الحيّة
الصور المتحركة هي ملفات تجمع بين صورة ثابتة وفيديو قصير.
- إذا تم تحديد مدة الصورة باستخدام
setImageDuration، سيتم عرض الصورة الحية لمدة محددة كصورة ثابتة. - إذا كانت مدة الصورة غير محدّدة، يتم تشغيل الصورة الحيّة كفيديو.
استخدام ProgressiveMediaSource
لمزيد من خيارات التخصيص، يمكنك إنشاء ProgressiveMediaSource وتمريره مباشرةً إلى المشغّل بدلاً من MediaItem.
Kotlin
// Create a data source factory. val dataSourceFactory = DefaultHttpDataSource.Factory() // Create a media item with the image URI and the desired duration. val mediaItem = MediaItem.Builder().setUri(imageUri).setImageDurationMs(2000).build() // Create a progressive media source for this media item. val mediaSource = ProgressiveMediaSource.Factory(dataSourceFactory) .createMediaSource(mediaItem) // Create a player instance. val player = ExoPlayer.Builder(context).build() // Set the media source to be played. player.setMediaSource(mediaSource) // Prepare the player. player.prepare()
Java
// Create a data source factory. DataSource.Factory dataSourceFactory = new DefaultHttpDataSource.Factory(); // Create a media item with the image URI and the desired duration. MediaItem mediaItem = new MediaItem.Builder().setUri(imageUri).setImageDurationMs(2000).build(); // Create a progressive media source for this media item. MediaSource mediaSource = new ProgressiveMediaSource.Factory(dataSourceFactory) .createMediaSource(mediaItem); // Create a player instance. ExoPlayer player = new ExoPlayer.Builder(context).build(); // Set the media source to be played. player.setMediaSource(mediaSource); // Prepare the player. player.prepare();
تخصيص التشغيل
توفّر ExoPlayer طرقًا متعدّدة لتخصيص تجربة التشغيل بما يتناسب مع احتياجات تطبيقك. يمكنك الاطّلاع على صفحة التخصيص للحصول على أمثلة.
مكتبات تحميل الصور
غالبًا ما تتم إدارة الصور باستخدام مكتبات خارجية لتحميل الصور، مثل Glide أو Coil.
يتطلّب دمج هذه المكتبات في مسار التشغيل 3 خطوات:
- حدِّد
MediaItemباستخدام نوع MIMEAPPLICATION_EXTERNALLY_LOADED_IMAGE. - قدِّم أداة فك ترميز الصور لاسترداد
Bitmapمن مكتبة تحميل الصور. - توفير أداة تحميل خارجية لتفعيل التخزين المؤقت والتحميل المُسبَق
MediaItem مع نوع MIME للصورة المحمَّلة خارجيًا
يجب أن يحدّد MediaItem المضاف إلى Player نوع MIME الخاص بـ APPLICATION_EXTERNALLY_LOADED_IMAGE بشكل صريح لاستخدام مسارات رموز مكتبة تحميل الصور:
Kotlin
val mediaItem = MediaItem.Builder() .setUri(imageUri) .setMimeType(MimeTypes.APPLICATION_EXTERNALLY_LOADED_IMAGE) .build()
Java
MediaItem mediaItem = new MediaItem.Builder() .setUri(imageUri) .setMimeType(MimeTypes.APPLICATION_EXTERNALLY_LOADED_IMAGE) .build();
أداة فك ترميز الصور باستخدام مكتبة تحميل الصور
يحتاج عارض الصور إلى ExternallyLoadedImageDecoder لاسترداد
Bitmap من Uri. يمكن توفير أداة فك الترميز هذه من خلال إلغاء DefaultRenderersFactory.getImageDecoderFactory.
يستخدم المثال التالي Glide لتحميل صورة، مع حصر الناتج على حجم الشاشة لتجنُّب إنشاء عناصر Bitmap كبيرة جدًا:
Kotlin
val glideImageDecoderFactory: ImageDecoder.Factory = ExternallyLoadedImageDecoder.Factory { request: ExternalImageRequest -> val displaySize = Util.getCurrentDisplayModeSize(context) GlideFutures.submit( Glide.with(context) .asBitmap() .load(request.uri) .override(max(displaySize.x, displaySize.y))) } val player: Player = ExoPlayer.Builder(context) .setRenderersFactory( object : DefaultRenderersFactory(context) { override fun getImageDecoderFactory(context: Context): ImageDecoder.Factory { return glideImageDecoderFactory } } ) .build()
Java
ImageDecoder.Factory glideImageDecoderFactory = new ExternallyLoadedImageDecoder.Factory( request -> { Point displaySize = Util.getCurrentDisplayModeSize(context); return GlideFutures.submit( Glide.with(context) .asBitmap() .load(request.uri) .override(max(displaySize.x, displaySize.y))); }); Player player = new ExoPlayer.Builder(context) .setRenderersFactory( new DefaultRenderersFactory(context) { @Override protected ImageDecoder.Factory getImageDecoderFactory(Context context) { return glideImageDecoderFactory; } }) .build();
التحميل المُسبَق للصور باستخدام مكتبة تحميل الصور
أثناء التشغيل، يطلب المشغّل التحميل المُسبَق للصورة التالية بعد تحميل العنصر السابق في قائمة التشغيل بالكامل. عند استخدام مكتبة خارجية لتحميل الصور، يجب تحديد ExternalLoader لتفعيل عملية التحميل المسبق هذه. إذا لم يكن من الممكن أو المطلوب إجراء أي تحميل مسبق، يجب توفير أداة التحميل هذه، ولكن يمكن ألا تفعل شيئًا.
يستخدم المثال التالي Glide لضمان التحميل المُسبَق للصورة المطلوبة إلى القرص:
Kotlin
val glidePreloader = ExternalLoader { request: LoadRequest -> GlideFutures.submit( Glide.with(context) .asFile() .apply( RequestOptions.diskCacheStrategyOf(DiskCacheStrategy.DATA) .priority(Priority.HIGH) .skipMemoryCache(true) ) .load(request.uri) ) } val player = ExoPlayer.Builder(context) .setMediaSourceFactory(DefaultMediaSourceFactory(context) .setExternalImageLoader(glidePreloader)) .build()
Java
ExternalLoader glidePreloader = request -> GlideFutures.submit( Glide.with(context) .asFile() .apply( diskCacheStrategyOf(DiskCacheStrategy.DATA) .priority(Priority.HIGH) .skipMemoryCache(true)) .load(request.uri)); Player player = new ExoPlayer.Builder(context) .setMediaSourceFactory(new DefaultMediaSourceFactory(context) .setExternalImageLoader(glidePreloader)) .build();