أخبار المنتجات

‫Media3 1.9.0 - الميزات الجديدة

قراءة لمدة 6 دقائق
عرض الملف الشخصي لـ Kristina Simakova
Kristina Simakova مديرة هندسة

الإصدار 1.9.0 من Media3 متاح الآن. بالإضافة إلى إصلاحات الأخطاء المعتادة والتحسينات في الأداء، يحتوي أحدث إصدار أيضًا على أربع وحدات جديدة أو معاد كتابتها إلى حد كبير:

  • media3-inspector : لاستخراج البيانات الوصفية والإطارات خارج التشغيل
  • media3-ui-compose-material3 : لإنشاء واجهة مستخدِم أساسية للوسائط في Compose مستندة إلى Material3 في بضع خطوات فقط
  • media3-cast : للتعامل تلقائيًا مع عمليات الانتقال بين عمليات التشغيل على Cast وعمليات التشغيل المحلية
  • media3-decoder-av1 : لتشغيل فيديوهات AV1 بشكل متّسق باستخدام وحدة فك الترميز للإضافة المعاد كتابتها استنادًا إلى مكتبة dav1d

أضفنا أيضًا تحسينات على التخزين المؤقت وإدارة الذاكرة إلى PreloadManager، وقدّمنا العديد من التبسيطات الجديدة في ExoPlayer وTransformer وMediaSession

يمنحك هذا الإصدار أيضًا أول وصول تجريبي إلى CompositionPlayer لمعاينة تعديلات الوسائط.  


ننصحك بمواصلة القراءة لمعرفة المزيد، وكما هو الحال دائمًا، يُرجى الاطّلاع على ملاحظات الإصدار الكاملة للحصول على نظرة عامة شاملة على التغييرات في هذا الإصدار.

استخراج البيانات الوصفية والإطارات خارج التشغيل

هناك العديد من الحالات التي تريد فيها فحص الوسائط بدون بدء التشغيل. على سبيل المثال، قد تريد رصد التنسيقات التي تحتوي عليها أو مدتها، أو استرداد الصور المصغّرة.

تجمع وحدة media3-inspector الجديدة جميع الأدوات لفحص الوسائط بدون تشغيلها في مكان واحد:

  • MetadataRetriever لقراءة المدة والتنسيق والبيانات الوصفية الثابتة من MediaItem
  • FrameExtractor للحصول على الإطارات أو الصور المصغّرة من عنصر
  • MediaExtractorCompat كبديل مباشر لفئة MediaExtractor على نظام Android الأساسي، للحصول على معلومات مفصّلة عن النماذج في الملف

يتّبع كل من MetadataRetriever وFrameExtractor نمط AutoCloseable بسيطًا. يُرجى الاطّلاع على صفحات الدليل الجديدة لمزيد من التفاصيل.

suspend fun extractThumbnail(mediaItem: MediaItem) {

  FrameExtractor.Builder(context, mediaItem).build().use {

    val thumbnail = frameExtractor.getThumbnail().await()

  } 

}

إنشاء واجهة مستخدِم أساسية للوسائط في Compose مستندة إلى Material3 في بضع خطوات فقط

في الإصدارات السابقة، بدأنا في توفير رمز موصِّل بين عناصر واجهة مستخدِم Compose ومثيل المشغّل. في الإصدار 1.9.0 من Media3، أضفنا وحدة جديدة هي media3-ui-compose-material3 تتضمّن أزرارًا وعناصر محتوى مستندة إلى Material3 ومصمّمة بالكامل. تتيح لك هذه الوحدة إنشاء واجهة مستخدِم للوسائط في بضع خطوات فقط، مع توفير كل المرونة لتخصيص النمط. إذا كنت تفضّل إنشاء نمط واجهة المستخدِم الخاص بك، يمكنك استخدام اللبنات الأساسية التي تتولى جميع منطق التحديث والربط، لذا ما عليك سوى التركيز على تصميم عنصر في واجهة المستخدم. يُرجى الاطّلاع على صفحات الدليل الموسّعة لوحدات واجهة مستخدِم Compose.

ما زلنا نعمل أيضًا على المزيد من مكوّنات Compose، مثل شريط البحث المُنشأ مسبقًا وبديل كامل وجاهز للاستخدام لـ PlayerView، بالإضافة إلى دمج الترجمة والشعارات.

@Composable
fun SimplePlayerUI(player: Player, modifier: Modifier = Modifier) {
  Column(modifier) {
    ContentFrame(player)  // Video surface and shutter logic
    Row (Modifier.align(Alignment.CenterHorizontally)) {                 
      SeekBackButton(player)   // Simple controls
      PlayPauseButton(player)
      SeekForwardButton(player)
    }
  }
}

 

image.png

واجهة مستخدِم بسيطة لمشغّل Compose تتضمّن عناصر جاهزة للاستخدام

التعامل تلقائيًا مع عمليات الانتقال بين عمليات التشغيل على Cast وعمليات التشغيل المحلية

تمت إعادة كتابة CastPlayer في وحدة media3-cast للتعامل تلقائيًا مع عمليات الانتقال بين التشغيل المحلي (على سبيل المثال، باستخدام ExoPlayer) والتشغيل على Cast عن بُعد.

عند إعداد MediaSession، ما عليك سوى إنشاء CastPlayer حول ExoPlayer وإضافة MediaRouteButton إلى واجهة المستخدِم، وبذلك تكون قد انتهيت.

// MediaSession setup with CastPlayer 

val exoPlayer = ExoPlayer.Builder(context).build()

val castPlayer = CastPlayer.Builder(context).setLocalPlayer(exoPlayer).build()

val session = MediaSession.Builder(context, castPlayer).build()

// MediaRouteButton in UI 

@Composable fun UIWithMediaRouteButton() {

  MediaRouteButton()

}
image.png

دمج CastPlayer الجديد في تطبيق Media3 التجريبي لعرض جلسة

تشغيل فيديوهات AV1 بشكل متّسق باستخدام وحدة فك الترميز للإضافة المعاد كتابتها استنادًا إلى dav1d

يحتوي الإصدار 1.9.0 على وحدة فك ترميز لإضافة AV1 معاد كتابتها بالكامل استنادًا إلى مكتبة dav1d الشائعة. 

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

دمج التخزين المؤقت وإدارة الذاكرة في PreloadManager

لقد حسّنّا أيضًا PreloadManager بشكل أكبر. لقد أتاحت لك هذه الوحدة سابقًا تحميل الوسائط مسبقًا في الذاكرة خارج التشغيل ثم تسليمها بسلاسة إلى مشغّل عند الحاجة. على الرغم من أنّ الأداء كان جيدًا جدًا، كان عليك توخي الحذر لعدم تجاوز حدود الذاكرة من خلال التحميل المسبق للكثير من المحتوى عن طريق الخطأ. لذا، في الإصدار 1.9.0 من Media3، أضفنا ميزتَين تجعلان هذه العملية أسهل وأكثر استقرارًا بكثير:

  1. دعم التخزين المؤقت : عند تحديد مدى التحميل المسبق، يمكنك الآن اختيار PreloadStatus.specifiedRangeCached(0, 5000) كحالة مستهدَفة للعناصر التي تم تحميلها مسبقًا. سيؤدي ذلك إلى إضافة النطاق المحدّد إلى ذاكرة التخزين المؤقت على القرص بدلاً من تحميل البيانات إلى الذاكرة. باستخدام هذه الميزة، يمكنك توفير نطاق أكبر بكثير من العناصر للتحميل المسبق لأنّ العناصر الأبعد عن العنصر الحالي لم تعُد بحاجة إلى شغل الذاكرة. يُرجى العِلم أنّ ذلك يتطلب ضبط Cache في DefaultPreloadManager.Builder.
  2. إدارة الذاكرة تلقائيًا : عدّلنا أيضًا واجهة LoadControl للتعامل بشكل أفضل مع حالة التحميل المسبق، لذا يمكنك الآن ضبط حدّ أقصى صريح للذاكرة لجميع العناصر التي تم تحميلها مسبقًا في الذاكرة. الحدّ الأقصى هو 144 ميغابايت تلقائيًا، ويمكنك ضبطه في DefaultLoadControl.Builder. سيتوقف DefaultPreloadManager تلقائيًا عن التحميل المسبق عند الوصول إلى الحدّ الأقصى، وسيحرّر تلقائيًا ذاكرة العناصر ذات الأولوية الأقل إذا لزم الأمر.

الاعتماد على السلوكيات التلقائية الجديدة والمبسّطة في ExoPlayer

كما هو الحال دائمًا، أضفنا الكثير من التحسينات التدريجية إلى ExoPlayer أيضًا. في ما يلي بعض الأمثلة:

  • كتم الصوت وإلغاء كتمه : كان لدينا سابقًا طريقة setVolume، ولكننا أضفنا الآن الطريقتَين الملائمتَين mute وunmute لاستعادة مستوى الصوت السابق بسهولة بدون تتبُّعه بنفسك.
  • رصد المشغّل المتوقف : في بعض الحالات النادرة، يمكن أن يتوقف المشغّل في حالة التخزين المؤقت أو التشغيل بدون إحراز أي تقدّم، على سبيل المثال، بسبب مشاكل في برامج الترميز أو الإعدادات غير الصحيحة. سيشعر المستخدمون بالانزعاج، ولكن لن تظهر لك هذه المشاكل في "إحصاءات Google". لجعل هذه المشكلة أكثر وضوحًا، يعرض المشغّل الآن StuckPlayerException عند رصد حالة توقف.
  • قفل التنشيط تلقائيًا : كانت إدارة قفل التنشيط اختيارية سابقًا، ما أدّى إلى صعوبة العثور على الحالات القصوى التي يمكن أن يتأخر فيها تقدّم التشغيل كثيرًا عند التشغيل في الخلفية. أصبحت هذه الميزة الآن غير مفعّلة تلقائيًا، لذا ما عليك سوى إيقافها إذا أردت، ويمكنك أيضًا إزالة جميع عمليات معالجة ميزة "قفل التنشيط" اليدوية حول التشغيل.
  • إعداد مبسّط لمنطق زر الترجمة والشرح : كان من الصعب بشكل مفاجئ ضبط TrackSelectionParameters على "تفعيل الترجمة والشرح أو إيقافهما"، لذا أضفنا خيارًا بسيطًا من نوع boolean هو selectTextByDefault لحالة الاستخدام هذه.

تبسيط الإعدادات المفضّلة لأزرار الوسائط في MediaSession

حتى الآن، كان تحديد الإعدادات المفضّلة للأزرار التي يجب أن تظهر في درج إشعارات الوسائط على Android Auto أو WearOS يتطلب تحديد أوامر وأزرار مخصّصة، حتى إذا كنت تريد ببساطة تشغيل طريقة مشغّل عادية.

يحتوي الإصدار 1.9.0 من Media3 على وظيفة جديدة تجعل هذه العملية أبسط بكثير، إذ يمكنك الآن تحديد الإعدادات المفضّلة لأزرار الوسائط باستخدام أمر مشغّل عادي، بدون الحاجة إلى معالجة أي أوامر مخصّصة على الإطلاق.

session.setMediaButtonPreferences(listOf(
    CommandButton.Builder(CommandButton.ICON_FAST_FORWARD) // choose an icon
      .setDisplayName(R.string.skip_forward)
      .setPlayerCommand(Player.COMMAND_SEEK_FORWARD) // choose an action 
      .build()
))
image.png

الإعدادات المفضّلة لأزرار الوسائط مع زر التقديم السريع

‫CompositionPlayer للمعاينة في الوقت الفعلي

يطرح الإصدار 1.9.0 مكوّن CompositionPlayer ضمن تعليق توضيحي جديد هو @ExperimentalApi. يشير التعليق التوضيحي إلى أنّ المكوّن متاح للتجربة، ولكنّه لا يزال قيد التطوير. 

CompositionPlayer هو مكوّن جديد في واجهات برمجة تطبيقات التعديل في Media3 مصمّم للمعاينة في الوقت الفعلي لتعديلات الوسائط. يستند إلى واجهة Media3 Player المألوفة، ويسمح CompositionPlayer للمستخدمين بالاطّلاع على التغييرات التي أجروها قبل الالتزام بعملية التصدير. يستخدم هذا المكوّن كائن Composition نفسه الذي ستمرّره إلى Transformer للتصدير، ما يؤدي إلى تبسيط عملية التعديل من خلال توحيد نموذج البيانات للمعاينة والتصدير.

ننصحك بالبدء في استخدام CompositionPlayer ومشاركة ملاحظاتك، ومتابعة المنشورات والتحديثات القادمة في المستندات لمزيد من التفاصيل.

‫InAppMuxer كأداة تجميع تلقائية في Transformer

يستخدم Transformer الآن InAppMp4Muxer كأداة تجميع تلقائية لكتابة ملفات حاوية الوسائط. داخليًا، يعتمد InAppMp4Muxer على وحدة تجميع Media3 Muxer، ما يوفّر سلوكًا متّسقًا على جميع إصدارات واجهة برمجة التطبيقات. 

يُرجى العِلم أنّه على الرغم من أنّ Transformer لم يعُد يستخدم MediaMuxer على منصة Android تلقائيًا، يمكنك مع ذلك توفير FrameworkMuxer.Factory من خلال setMuxerFactory إذا كانت حالة الاستخدام تتطلب ذلك.

واجهات برمجة تطبيقات جديدة لضبط السرعة

يبسّط الإصدار 1.9.0 واجهات برمجة تطبيقات ضبط السرعة لتعديل الوسائط. لقد قدّمنا طرقًا جديدة مباشرةً في EditedMediaItem.Builder للتحكّم في السرعة، ما يجعل واجهة برمجة التطبيقات أكثر سهولة. يمكنك الآن تغيير سرعة مقطع من خلال استدعاء setSpeed(SpeedProvider provider) على EditedMediaItem.Builder:

val speedProvider = object : SpeedProvider {
    override fun getSpeed(presentationTimeUs: Long): Float {
        return speed
    }

    override fun getNextSpeedChangeTimeUs(timeUs: Long): Long {
        return C.TIME_UNSET
    }
}

EditedMediaItem speedEffectItem = EditedMediaItem.Builder(mediaItem)
    .setSpeed(speedProvider)
    .build()

يحلّ هذا النهج الجديد محلّ الطريقة السابقة لاستخدام Effects#createExperimentalSpeedChangingEffects()، التي أوقفنا استخدامها وستتم إزالتها في إصدار مستقبلي.

تقديم أنواع المسارات لـ EditedMediaItemSequence

في الإصدار 1.9.0، يتطلب EditedMediaItemSequence تحديد أنواع مسارات الإخراج المطلوبة أثناء إنشاء التسلسل. يضمن هذا التغيير أن تكون معالجة المسارات أكثر وضوحًا وثباتًا في جميع أنحاء Composition. 

يتم ذلك من خلال منشئ EditedMediaItemSequence.Builder جديد يقبل مجموعة من أنواع المسارات (على سبيل المثال، C.TRACK_TYPE_AUDIO, C.TRACK_TYPE_VIDEO).

لتبسيط عملية الإنشاء، أضفنا طرقًا ملائمة ثابتة جديدة:

  • ‫EditedMediaItemSequence.withAudioFrom(List<EditedMediaItem>)
  • ‫EditedMediaItemSequence.withVideoFrom(List<EditedMediaItem>)
  • ‫EditedMediaItemSequence.withAudioAndVideoFrom(List<EditedMediaItem>)

ننصحك بنقل البيانات إلى المنشئ الجديد أو الطرق الملائمة لتعريفات تسلسل أكثر وضوحًا وموثوقية.

في ما يلي مثال على إنشاء تسلسل للفيديو فقط:

EditedMediaItemSequence videoOnlySequence =
    EditedMediaItemSequence.Builder(setOf(C.TRACK_TYPE_VIDEO))
        .addItem(editedMediaItem)
        .build()

يُرجى التواصل معنا من خلال أداة تتبُّع المشاكل في Media3 إذا واجهت أي أخطاء، أو إذا كانت لديك أسئلة أو طلبات ميزات. نتطلّع إلى سماع رأيك.

مواصلة القراءة