تقليص حزمة APK

يُعد تقليل حجم حزمة APK جانبًا مهمًا في تطوير تطبيق Android جيد. وينطبق ذلك بشكل خاص عند استهداف الأسواق النامية، وأيضًا عند تطوير تطبيق Android فوري. في هذه الحالات، قد يكون من المستحسن تقليل حجم مكتبة ExoPlayer المضمّنة في حزمة APK. توضّح هذه الصفحة بعض الخطوات البسيطة التي يمكن أن تساعد في تحقيق ذلك.

استخدام التبعيات المطلوبة فقط

يجب الاعتماد فقط على وحدات المكتبة التي تحتاج إليها فعلاً. على سبيل المثال، ستضيف التعليمات البرمجية التالية تبعيات على وحدات مكتبة ExoPlayer وDASH وواجهة المستخدم، كما قد يكون مطلوبًا لتطبيق لا يعرض إلا محتوى 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، يمكن تقليل مساهمة 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 توفير مصنع على النحو التالي:

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));