צמצום הגודל של קובץ ה-APK הוא היבט חשוב בפיתוח אפליקציה טובה ל-Android. זה נכון במיוחד כשמטרגטים שווקים מתפתחים, וגם כשמפתחים אפליקציה ללא התקנה ל-Android. במקרים כאלה, יכול להיות שתרצו לצמצם את הגודל של ספריית ExoPlayer שכלולה ב-APK. בדף הזה מפורטים כמה שלבים פשוטים שיכולים לעזור לכם לעשות את זה.
שימוש רק ביחסי תלות נדרשים
הסתמכו רק על המודולים של הספרייה שאתם באמת צריכים. לדוגמה, הקוד הבא יוסיף יחסי תלות במודולים של ExoPlayer, DASH וספריית ממשק המשתמש, כפי שנדרש לאפליקציה שמפעילה רק תוכן DASH:
Kotlin
implementation("androidx.media3:media3-exoplayer:1.11.1")
implementation("androidx.media3:media3-exoplayer-dash:1.11.1")
implementation("androidx.media3:media3-ui:1.11.1")
מגניב
implementation "androidx.media3:media3-exoplayer:1.11.1"
implementation "androidx.media3:media3-exoplayer-dash:1.11.1"
implementation "androidx.media3:media3-ui:1.11.1"
הפעלת כיווץ של קוד ומשאבים
מומלץ להפעיל כיווץ של קוד ומשאבים בגרסאות ה-build להפצה של האפליקציה. 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).
ציינו אילו מחלצים נדרשים לאפליקציה שלכם
כברירת מחדל, הנגן יוצר מכונות של Extractor כדי להפעיל מדיה פרוגרסיבית באמצעות DefaultExtractorsFactory. DefaultExtractorsFactory תלוי בכל ההטמעות של Extractor שסופקו בספריית ExoPlayer, ולכן אף אחת מהן לא תוסר על ידי כיווץ הקוד. אם אתם יודעים שהאפליקציה צריכה להפעיל רק מספר קטן של פורמטים של קונטיינרים, או שהיא לא מפעילה מדיה פרוגרסיבית בכלל, אתם יכולים לציין ExtractorsFactory משלכם. לדוגמה, אפליקציה שצריכה להפעיל רק קובצי MP4 יכולה לספק פונקציית factory כמו:
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 ל-constructor של DefaultMediaSourceFactory, ואז להעביר את הערך mediaSourceFactory ל-constructor של 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 ישירות ל-constructor של ExoPlayer.Builder.
Kotlin
val player = ExoPlayer.Builder(context, customMediaSourceFactory).build()
Java
ExoPlayer player = new ExoPlayer.Builder(context, mediaSourceFactory).build();
אם האפליקציה משתמשת ישירות ב-MediaSource במקום ב-MediaItem, צריך להעביר את MediaSource.Factory.UNSUPPORTED ל-constructor של 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));