การย่อ APK

การลดขนาด APK เป็นสิ่งสำคัญในการพัฒนาแอป Android ที่ดี โดยเฉพาะอย่างยิ่งเมื่อกำหนดเป้าหมายเป็นตลาดที่กำลังพัฒนา และเมื่อพัฒนาแอป Android Instant App ในกรณีดังกล่าว คุณอาจต้องการลดขนาดไลบรารี ExoPlayer ที่รวมอยู่ใน APK หน้านี้สรุปขั้นตอนง่ายๆ ที่จะช่วยให้คุณทำเช่นนั้นได้

ใช้เฉพาะทรัพยากร Dependency ที่จำเป็น

ใช้เฉพาะโมดูลไลบรารีที่คุณต้องการจริงๆ ตัวอย่างเช่น โค้ดต่อไปนี้จะเพิ่มทรัพยากร Dependency ในโมดูลไลบรารี ExoPlayer, DASH และ UI ตามที่อาจจำเป็นสำหรับแอปที่เล่นเฉพาะเนื้อหา DASH

Kotlin

implementation("androidx.media3:media3-exoplayer:1.10.1")
implementation("androidx.media3:media3-exoplayer-dash:1.10.1")
implementation("androidx.media3:media3-ui:1.10.1")

ดึงดูด

implementation "androidx.media3:media3-exoplayer:1.10.1"
implementation "androidx.media3:media3-exoplayer-dash:1.10.1"
implementation "androidx.media3:media3-ui:1.10.1"

เปิดใช้การย่อโค้ดและการลดขนาดทรัพยากร

คุณควรเปิดใช้การย่อโค้ดและการลดขนาดทรัพยากรสำหรับบิลด์ที่เผยแพร่ของแอป ExoPlayer มีโครงสร้างที่ช่วยให้การลดขนาดโค้ดนำฟังก์ชันการทำงานที่ไม่ได้ใช้ออกได้อย่างมีประสิทธิภาพ ตัวอย่างเช่น สำหรับแอปที่เล่นเนื้อหา DASH การเปิดใช้การลดขนาดโค้ดจะช่วยลดขนาด APK ที่ ExoPlayer มีส่วนร่วมได้ประมาณ 40%

อ่าน การย่อ การปรับให้ยากต่อการอ่าน (Obfuscation) และการเพิ่มประสิทธิภาพแอป เพื่อดูวิธีเปิดใช้ การย่อโค้ดและการลดขนาดทรัพยากร

ระบุ Renderer ที่แอปของคุณต้องการ

โดยค่าเริ่มต้น ระบบจะสร้าง Renderer ของเพลเยอร์โดยใช้ DefaultRenderersFactory DefaultRenderersFactory ขึ้นอยู่กับการใช้งาน Renderer ทั้งหมดที่ให้ไว้ในไลบรารี ExoPlayer และด้วยเหตุนี้ การลดขนาดโค้ดจึงจะไม่นำ Renderer ใดๆ ออก หากทราบว่าแอปของคุณต้องการเพียงชุดย่อยของ Renderer คุณสามารถระบุ RenderersFactory ของคุณเองแทนได้ ตัวอย่างเช่น แอปที่เล่นเฉพาะเสียงสามารถกำหนด Factory ได้ดังนี้เมื่อสร้างอินสแตนซ์ 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 อื่นๆ ออกได้ ในวิดีโอตัวอย่างนี้ ระบบจะนำ Renderer ของข้อความและข้อมูลเมตาออก (ซึ่งหมายความว่าเพลเยอร์จะไม่ประมวลผลหรือแสดงคำบรรยายหรือข้อมูลเมตาในสตรีม (เช่น ICY))

ระบุ Extractor ที่แอปของคุณต้องการ

โดยค่าเริ่มต้น เพลเยอร์จะสร้างอินสแตนซ์ Extractor เพื่อเล่นสื่อแบบโปรเกรสซีฟโดยใช้ DefaultExtractorsFactory DefaultExtractorsFactory ขึ้นอยู่กับการใช้งาน Extractor ทั้งหมดที่ให้ไว้ในไลบรารี ExoPlayer และด้วยเหตุนี้ การลดขนาดโค้ดจึงจะไม่นำ Extractor ใดๆ ออก หากทราบว่าแอปของคุณต้องการเล่นเพียงรูปแบบคอนเทนเนอร์จำนวนเล็กน้อย หรือไม่เล่นสื่อแบบโปรเกรสซีฟเลย คุณสามารถระบุ 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 ไปยังเครื่องมือสร้าง 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));