ExoPlayer תומך בפורמטים הבאים של תמונות. במאמר בנושא ספריות לטעינת תמונות מוסבר איך לשלב ספריות חיצוניות שיכולות לספק תמיכה בקבוצה שונה של פורמטים.
| פורמט תמונה | נתמך | פתקים |
|---|---|---|
| BMP | כן | |
| GIF | לא | אין תמיכה ב-Extractor |
| JPEG | כן | |
| תמונה בתנועה בפורמט JPEG | כן | תמונת סטילס וסרטון נתמכים |
| JPEG Ultra HDR | כן | ההמרה חוזרת ל-SDR בגרסאות קודמות ל-Android 14 או במסכים ללא HDR |
| 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עם סוג MIME APPLICATION_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();