כיווץ APK

צמצום גודל ה-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 באמצעות צמצום הקוד. בדוגמה הספציפית הזו כלי לעיבוד טקסט, טקסט ומטא-נתונים הוסר (כלומר, כל כתוביות או מטא-נתונים של מודעת וידאו In-stream (למשל, ICY) לא יעובד או יישלח על ידי ).

לציין אילו כלי חילוץ דרושים לאפליקציה שלך

כברירת מחדל, הנגן יוצר מכונות 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 ישירות ל-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 למבנה 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));