ב-ExoPlayer יש תמיכה ב-HLS במגוון פורמטים של קונטיינרים. את האודיו הכלולים חייבת להיות תמיכה גם בפורמטים של דגימות וידאו (עיינו ב פורמטים לדוגמה לקבלת פרטים). רביעי לעודד מאוד מפיקי תוכן ב-HLS ליצור שידורי HLS באיכות גבוהה, כפי שמתואר כאן.
תכונה | נתמך | תגובות |
---|---|---|
קונטיינרים | ||
MPEG-TS | כן | |
FMP4/CMAF | כן | |
ADTS (AAC) | כן | |
MP3 | כן | |
כתוביות | ||
CEA-608 | כן | |
CEA-708 | כן | |
WebVTT | כן | |
מטא נתונים | ||
ID3 | כן | |
SCTE-35 | לא | |
הגנה על תוכן | ||
AES-128 | כן | |
דוגמה AES-128 | לא | |
Widevine | כן | API 19+ (סכימת cenc) וסכימת 25 + ('cbcs') |
PlayReady SL2000 | כן | Android TV בלבד |
שליטה דרך שרת | ||
עדכוני Delta | כן | |
חסימת הטעינה מחדש של פלייליסט | כן | |
חסימת הטעינה של רמזים לטעינה מראש | כן | מלבד בייטים עם אורכים לא מוגדרים |
הפעלה בשידור חי | ||
הפעלה רגילה של שידור חי | כן | |
HLS עם זמן אחזור קצר (Apple) | כן | |
זמן אחזור קצר של HLS (קהילה) | לא | |
נתוני לקוח מדיה נפוצים (CMCD) | כן | מדריך ההטמעה |
שימוש ב-MediaItem
כדי להפעיל שידור בפורמט HLS, תצטרכו להשתמש במודול ה-HLS.
Kotlin
implementation("androidx.media3:media3-exoplayer-hls:1.4.1")
Groovy
implementation "androidx.media3:media3-exoplayer-hls:1.4.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, צריך להפעיל Cast של האובייקט שהוחזר אל 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 באיכות גבוהה
כדי להפיק את המרב מ-ExpoPlayer, יש מספר הנחיות שניתן כדי לשפר את תוכן ה-HLS. לקריאת הפוסט שלנו ב-Medium בנושא הפעלת HLS ב- ExoPlayer להסבר מלא. הנקודות העיקריות הן:
- משתמשים במשכי זמן מדויקים של מקטעים.
- להשתמש בסטרימינג מדיה רציף. להימנע משינויים במבנה המדיה פלחים.
- משתמשים בתג
#EXT-X-INDEPENDENT-SEGMENTS
. - עדיף להשתמש בשידורים מטושטשים על פני קבצים שכוללים גם וידאו וגם אודיו.
- כלול את כל המידע שניתן להציג בפלייליסט מרובה המשתנים.
ההנחיות הבאות חלות באופן ספציפי על שידורים חיים:
- משתמשים בתג
#EXT-X-PROGRAM-DATE-TIME
. - משתמשים בתג
#EXT-X-DISCONTINUITY-SEQUENCE
. - ליצור חלון זמן ארוך. דקה אחת או יותר זה מעולה.