HLS

يتوافق تطبيق ExoPlayer مع بروتوكول HLS مع تنسيقات حاويات متعددة. يجب أيضًا توفير تنسيقات الصوت والفيديو المضمّنة في نماذج الصوت (راجِع قسم عيّنات التنسيقات للاطّلاع على التفاصيل). ونحن ننصح بشدّة منتجي محتوى HLS بإنشاء أحداث بث HLS عالية الجودة، كما هو موضّح هنا.

الميزة معلومات معتمَدة التعليقات
الحاويات
تنسيق MPEG-TS نعم
FMP4/CMAF نعم
ADTS (AAC) نعم
MP3 نعم
الترجمة المغلقة
معيار CEA-608 نعم
معيار CEA-708 نعم
WebVTT نعم
البيانات الوصفية
رقم التعريف 3 نعم
معيار SCTE-35 لا
حماية المحتوى
معيار AES-128 نعم
نموذج AES-128 لا
Widevine نعم واجهة برمجة التطبيقات 19+ (مخطط "cenc") و25+ (مخطط "cbcs")
Playجاهز SL2000 نعم Android TV فقط
التحكُّم في الخادم
تعديلات دلتا نعم
حظر إعادة تحميل قائمة التشغيل نعم
حظر تحميل تلميحات التحميل المُسبق نعم باستثناء نطاقات البايت ذات الأطوال غير المحددة
التشغيل المباشر
تشغيل مباشر عادي نعم
بروتوكول HLS في وقت استجابة سريع (تفاح) نعم
بروتوكول HLS في وقت استجابة بطيء (المنتدى) لا
بيانات برنامج الوسائط الشائعة (CMCD) نعم دليل الدمج

استخدام MediaItem

لتشغيل بث HLS، يجب الاعتماد على وحدة HLS.

Kotlin

implementation("androidx.media3:media3-exoplayer-hls:1.3.1")

رائع

implementation "androidx.media3:media3-exoplayer-hls:1.3.1"

يمكنك بعد ذلك إنشاء MediaItem لمعرّف الموارد المنتظم (URI) لقائمة تشغيل HLS، وتمريره إلى المشغّل.

Kotlin

// Create a player instance.
val player = ExoPlayer.Builder(context).build()
// Set the media item to be played.
player.setMediaItem(MediaItem.fromUri(hlsUri))
// Prepare the player.
player.prepare()

Java

// Create a player instance.
ExoPlayer player = new ExoPlayer.Builder(context).build();
// Set the media item to be played.
player.setMediaItem(MediaItem.fromUri(hlsUri));
// Prepare the player.
player.prepare();

إذا كان معرّف الموارد المنتظم (URI) لا ينتهي بـ .m3u8، يمكنك تمرير MimeTypes.APPLICATION_M3U8 إلى setMimeType من MediaItem.Builder للإشارة بشكل صريح إلى نوع المحتوى.

قد يشير معرّف الموارد المنتظم (URI) لعنصر الوسائط إلى قائمة تشغيل وسائط أو قائمة تشغيل متعددة الصِيَغ. إذا كان معرّف الموارد المنتظم (URI) يشير إلى قائمة تشغيل تتضمّن صيغًا متعددة تتضمّن علامات #EXT-X-STREAM-INF متعددة، سيتكيّف ExoPlayer تلقائيًا بين الصيغ، مع مراعاة إمكانات كلّ من معدل نقل البيانات وإمكانات الجهاز المتاحة.

استخدام HlsMediaSource

لمزيد من خيارات التخصيص، يمكنك إنشاء HlsMediaSource وإرساله مباشرةً إلى المشغّل بدلاً من MediaItem.

Kotlin

// Create a data source factory.
val dataSourceFactory: DataSource.Factory = DefaultHttpDataSource.Factory()
// Create a HLS media source pointing to a playlist uri.
val hlsMediaSource =
  HlsMediaSource.Factory(dataSourceFactory).createMediaSource(MediaItem.fromUri(hlsUri))
// Create a player instance.
val player = ExoPlayer.Builder(context).build()
// Set the HLS media source as the playlist with a single media item.
player.setMediaSource(hlsMediaSource)
// Prepare the player.
player.prepare()

Java

// Create a data source factory.
DataSource.Factory dataSourceFactory = new DefaultHttpDataSource.Factory();
// Create a HLS media source pointing to a playlist uri.
HlsMediaSource hlsMediaSource =
    new HlsMediaSource.Factory(dataSourceFactory).createMediaSource(MediaItem.fromUri(hlsUri));
// Create a player instance.
ExoPlayer player = new ExoPlayer.Builder(context).build();
// Set the HLS media source as the playlist with a single media item.
player.setMediaSource(hlsMediaSource);
// Prepare the player.
player.prepare();

الوصول إلى البيان

يمكنك استرداد البيان الحالي من خلال استدعاء Player.getCurrentManifest. بالنسبة إلى بروتوكول HLS، يجب تحويل الكائن المعروض إلى HlsManifest. ويتم أيضًا استدعاء استدعاء onTimelineChanged لـ Player.Listener كلما تم تحميل البيان. ويحدث ذلك مرة واحدة للمحتوى المسجّل وربما عدة مرات للمحتوى المباشر. يوضح مقتطف الرمز التالي كيف يمكن لتطبيق ما القيام بشيء ما كلما تم تحميل البيان.

Kotlin

player.addListener(
  object : Player.Listener {
    override fun onTimelineChanged(timeline: Timeline, @TimelineChangeReason reason: Int) {
      val manifest = player.currentManifest
      if (manifest is HlsManifest) {
        // Do something with the manifest.
      }
    }
  }
)

Java

player.addListener(
    new Player.Listener() {
      @Override
      public void onTimelineChanged(
          Timeline timeline, @Player.TimelineChangeReason int reason) {
        Object manifest = player.getCurrentManifest();
        if (manifest != null) {
          HlsManifest hlsManifest = (HlsManifest) manifest;
          // Do something with the manifest.
        }
      }
    });

تخصيص التشغيل

يوفّر لك ExoPlayer طرقًا متعدّدة لتخصيص تجربة التشغيل بما يتناسب مع احتياجات تطبيقك. يمكنك الاطّلاع على صفحة التخصيص للحصول على أمثلة.

إيقاف الإعداد بدون أقسام

سيستخدم ExoPlayer تلقائيًا عملية إعداد بدون مقاطع. وهذا يعني أنّ ExoPlayer لن تستخدم سوى المعلومات الواردة في قائمة التشغيل المتعدّدة الصِيَغ لإعداد البث، وهذا يعمل إذا كانت علامات #EXT-X-STREAM-INF تحتوي على السمة CODECS.

قد تحتاج إلى إيقاف هذه الميزة إذا كانت مقاطع الوسائط التابعة لك تحتوي على مقاطع ترجمة وشرح مختلطة وغير معرَّفة في قائمة التشغيل المتعدّدة الصِيَغ باستخدام علامة #EXT-X-MEDIA:TYPE=CLOSED-CAPTIONS. وإلا، لن يتم اكتشاف مقاطع الترجمة والشرح هذه وتشغيلها. يمكنك إيقاف عملية الإعداد بدون مقاطع في HlsMediaSource.Factory كما هو موضّح في المقتطف التالي. يُرجى العِلم بأنّ ذلك سيزيد من وقت بدء التشغيل، لأنّ ExoPlayer تحتاج إلى تنزيل مقطع من الوسائط لاكتشاف هذه المقاطع الإضافية، ويُفضَّل تحديد مقاطع الترجمة والشرح في قائمة التشغيل المتعدّدة الصِيَغ بدلاً من ذلك.

Kotlin

val hlsMediaSource =
  HlsMediaSource.Factory(dataSourceFactory)
    .setAllowChunklessPreparation(false)
    .createMediaSource(MediaItem.fromUri(hlsUri))

Java

HlsMediaSource hlsMediaSource =
    new HlsMediaSource.Factory(dataSourceFactory)
        .setAllowChunklessPreparation(false)
        .createMediaSource(MediaItem.fromUri(hlsUri));

إنشاء محتوى HLS عالي الجودة

للاستفادة إلى أقصى حدّ من ExoPlayer، هناك إرشادات معيّنة يمكنك اتّباعها لتحسين محتوى HLS الخاص بك. للحصول على شرح كامل، يُرجى قراءة مشاركتنا على Medium حول تشغيل البث المباشر وفق بروتوكول HTTP (HLS) في ExoPlayer. النقاط الرئيسية هي:

  • استخدِم مُددًا دقيقة للشرائح.
  • استخدام بث وسائط مستمر وتجنُّب التغييرات في بنية الوسائط على مستوى القطاعات
  • استخدام العلامة #EXT-X-INDEPENDENT-SEGMENTS
  • تفضيل مجموعات البث غير المنسّقة، على عكس الملفات التي تتضمّن فيديو وصوتًا معًا.
  • أدرِج كل المعلومات من قائمة التشغيل المتعدّدة الصِيَغ.

تنطبق الإرشادات التالية على أحداث البث المباشر تحديدًا:

  • استخدام العلامة #EXT-X-PROGRAM-DATE-TIME
  • استخدام العلامة #EXT-X-DISCONTINUITY-SEQUENCE
  • قدِّم فترة طويلة الأمد. إن دقيقة واحدة أو أكثر أمر رائع.