تقليص حزمة APK

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

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

تعتمد فقط على وحدات المكتبة التي تحتاج إليها فعلاً. على سبيل المثال، سيضيف ما يلي تبعيات على وحدات مكتبة ExoPlayer وDASH وواجهة المستخدم، كما قد يكون مطلوبًا لتطبيق يشغِّل محتوى DASH فقط:

Kotlin

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

رائع

implementation "androidx.media3:media3-exoplayer:1.3.1"
implementation "androidx.media3:media3-exoplayer-dash:1.3.1"
implementation "androidx.media3:media3-ui:1.3.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.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));