צמצום גודל קובץ ה-APK הוא היבט חשוב בפיתוח אפליקציה טובה ל-Android. זה נכון במיוחד כשמטרגטים שווקים מתפתחים, וגם כשמפתחים אפליקציה ללא התקנה ל-Android. במקרים כאלה, כדאי לצמצם את הגודל של ספריית ExoPlayer שכלולה בקובץ ה-APK. בדף הזה מפורטים כמה שלבים פשוטים שיעזרו לכם להשיג את המטרה הזו.
שימוש רק ביחסי תלות נדרשים
להסתמך רק על המודולים של הספרייה שבאמת נחוצים לכם. לדוגמה, הקוד הבא יוסיף יחסי תלות במודולים של ExoPlayer, DASH וספריית UI, כפי שעשוי להיות נדרש לאפליקציה שמפעילה רק תוכן DASH:
Kotlin
implementation("androidx.media3:media3-exoplayer:1.4.1") implementation("androidx.media3:media3-exoplayer-dash:1.4.1") implementation("androidx.media3:media3-ui:1.4.1")
Groovy
implementation "androidx.media3:media3-exoplayer:1.4.1" implementation "androidx.media3:media3-exoplayer-dash:1.4.1" implementation "androidx.media3:media3-ui:1.4.1"
הפעלה של כיווץ קוד ומשאבים
מומלץ להפעיל כיווץ קוד ומשאבים ב-builds של הגרסה של האפליקציה. ExoPlayer מובנה כך שאפשר לבצע בו כיווץ קוד כדי להסיר ביעילות פונקציונליות שלא בשימוש. לדוגמה, באפליקציה שמפעילה תוכן DASH, אפשר להקטין את התרומה של ExoPlayer לגודל ה-APK בכ-40% על ידי הפעלת צמצום הקוד.
במאמר כיווץ, ערפול ואופטימיזציה של האפליקציה מוסבר איך מפעילים כיווץ של קוד ומשאבים.
ציון הרסטוררים הנדרשים לאפליקציה
כברירת מחדל, מעבדי הווידאו של הנגן ייוצרו באמצעות DefaultRenderersFactory
. DefaultRenderersFactory
תלויה בכל ההטמעות של Renderer
שסופקו בספריית ExoPlayer, ולכן אף אחת מהן לא תוסר על ידי צמצום הקוד. אם אתם יודעים שהאפליקציה שלכם זקוקה רק לקבוצת משנה של מנועי עיבוד, תוכלו לציין RenderersFactory
משלכם במקום זאת. לדוגמה, אפליקציה שמשמיעה רק אודיו יכולה להגדיר מפעל כזה כשהיא יוצרת מכונות ExoPlayer
:
Kotlin
val audioOnlyRenderersFactory = RenderersFactory { handler: Handler, videoListener: VideoRendererEventListener, audioListener: AudioRendererEventListener, textOutput: TextOutput, metadataOutput: MetadataOutput, -> arrayOf<Renderer>( MediaCodecAudioRenderer(context, MediaCodecSelector.DEFAULT, handler, audioListener) ) } val player = ExoPlayer.Builder(context, audioOnlyRenderersFactory).build()
Java
RenderersFactory audioOnlyRenderersFactory = (handler, videoListener, audioListener, textOutput, metadataOutput) -> new Renderer[] { new MediaCodecAudioRenderer( context, MediaCodecSelector.DEFAULT, handler, audioListener) }; ExoPlayer player = new ExoPlayer.Builder(context, audioOnlyRenderersFactory).build();
כך תוכלו להסיר הטמעות אחרות של Renderer
באמצעות צמצום הקוד. בסרטון לדוגמה הזה, הנגנים של הטקסט והמטא-נתונים הוסרו (כלומר, הנגן לא יעבד או יפיק כתוביות או מטא-נתונים בזמן אמת (למשל ICY)).
ציון הגורמים לחילוץ (extractors) הנדרשים לאפליקציה
כברירת מחדל, הנגן יוצר מכונות Extractor
כדי להפעיל מדיה פרוגרסיבית באמצעות DefaultExtractorsFactory
. DefaultExtractorsFactory
תלויה בכל ההטמעות של Extractor
שסופקו בספריית ExoPlayer, ולכן אף אחת מהן לא תוסר על ידי צמצום הקוד. אם אתם יודעים שהאפליקציה שלכם צריכה להפעיל רק מספר קטן של פורמטים של קונטיינרים, או שהיא לא מפעילה מדיה פרוגרסיבית בכלל, תוכלו לציין ExtractorsFactory
משלכם במקום זאת. לדוגמה, אפליקציה שצריכה רק להפעיל קובצי mp4 יכולה לספק מפעל כמו:
Kotlin
val mp4ExtractorFactory = ExtractorsFactory { arrayOf<Extractor>(Mp4Extractor(DefaultSubtitleParserFactory())) } val player = ExoPlayer.Builder(context, DefaultMediaSourceFactory(context, mp4ExtractorFactory)).build()
Java
ExtractorsFactory mp4ExtractorFactory = () -> new Extractor[] {new Mp4Extractor(new DefaultSubtitleParserFactory())}; ExoPlayer player = new ExoPlayer.Builder(context, new DefaultMediaSourceFactory(context, mp4ExtractorFactory)) .build();
כך תוכלו להסיר הטמעות אחרות של Extractor
על ידי צמצום הקוד, וכתוצאה מכך להפחית את הגודל באופן משמעותי.
אם האפליקציה לא מפעילה בכלל תוכן פרוגרסיבי, צריך להעביר את ExtractorsFactory.EMPTY
למבנה DefaultMediaSourceFactory
ואז להעביר את mediaSourceFactory
למבנה ExoPlayer.Builder
.
Kotlin
val player = ExoPlayer.Builder(context, DefaultMediaSourceFactory(context, ExtractorsFactory.EMPTY)).build()
Java
ExoPlayer player = new ExoPlayer.Builder( context, new DefaultMediaSourceFactory(context, ExtractorsFactory.EMPTY)) .build();
יצירת אובייקט MediaSource בהתאמה אישית
אם האפליקציה שלכם משתמשת ב-MediaSource.Factory
בהתאמה אישית ואתם רוצים שה-DefaultMediaSourceFactory
יוסר על ידי הסרת קוד, עליכם להעביר את ה-MediaSource.Factory
ישירות למבנה ExoPlayer.Builder
.
Kotlin
val player = ExoPlayer.Builder(context, customMediaSourceFactory).build()
Java
ExoPlayer player = new ExoPlayer.Builder(context, mediaSourceFactory).build();
אם האפליקציה משתמשת ב-MediaSource
ישירות במקום ב-MediaItem
, צריך להעביר את MediaSource.Factory.UNSUPPORTED
למבנה ExoPlayer.Builder
כדי לוודא שאפשר יהיה להסיר את DefaultMediaSourceFactory
ואת DefaultExtractorsFactory
באמצעות צמצום קוד.
Kotlin
val player = ExoPlayer.Builder(context, MediaSource.Factory.UNSUPPORTED).build() val mediaSource = ProgressiveMediaSource.Factory(dataSourceFactory, customExtractorsFactory) .createMediaSource(MediaItem.fromUri(uri))
Java
ExoPlayer player = new ExoPlayer.Builder(context, MediaSource.Factory.UNSUPPORTED).build(); ProgressiveMediaSource mediaSource = new ProgressiveMediaSource.Factory(dataSourceFactory, customExtractorsFactory) .createMediaSource(MediaItem.fromUri(uri));