בדרך כלל משתמשים ב-ExoPlayer להזרמת מדיה באינטרנט. הוא תומך בכמה מחסניות רשת לשליחת בקשות הרשת הבסיסיות שלו. לבחירה שלכם במערך פרוטוקולים יכולה להיות השפעה משמעותית על ביצועי הסטרימינג.
בדף הזה מוסבר איך להגדיר את ExoPlayer לשימוש במערך הרשת שבחרתם, מפורטות האפשרויות הזמינות, יש הנחיות לבחירת מערך רשת לאפליקציה שלכם ומוסבר איך להפעיל שמירה במטמון של מדיה שמוזרמת.
הגדרת ExoPlayer לשימוש במערך רשת ספציפי
ExoPlayer טוען נתונים דרך רכיבי DataSource, שהוא מקבל ממופעים של DataSource.Factory שמוזרקים מקוד האפליקציה.
אם האפליקציה שלכם צריכה רק להפעיל תוכן http(s), כדי לבחור מחסנית רשת צריך רק לעדכן את כל המקרים של DataSource.Factory שהאפליקציה מוסיפה כך שיהיו מקרים של HttpDataSource.Factory שתואמים למחסנית הרשת שבה רוצים להשתמש. אם האפליקציה שלך צריכה גם להפעיל תוכן שאינו בפורמט http(s), כמו קבצים מקומיים, צריך להשתמש ב-DefaultDataSource.Factory:
Kotlin
DefaultDataSource.Factory( ... /* baseDataSourceFactory= */ PreferredHttpDataSource.Factory(...))
Java
new DefaultDataSource.Factory( ... /* baseDataSourceFactory= */ new PreferredHttpDataSource.Factory(...));
בדוגמה הזו, PreferredHttpDataSource.Factory הוא המפעל שמתאים למערך הרשת המועדף שלכם. שכבת DefaultDataSource.Factory מוסיפה תמיכה במקורות שאינם http(s), כמו קבצים מקומיים.
בדוגמה הבאה מוצג אופן הפיתוח של ExoPlayer שישתמש במערך פרוטוקולי הרשת של Cronet וגם יתמוך בהפעלה של תוכן שאינו http(s).
Kotlin
// Given a CronetEngine and Executor, build a CronetDataSource.Factory. val cronetDataSourceFactory = CronetDataSource.Factory(cronetEngine, executor) // Wrap the CronetDataSource.Factory in a DefaultDataSource.Factory, which adds // in support for requesting data from other sources (such as files, resources, // etc). val dataSourceFactory = DefaultDataSource.Factory(context, /* baseDataSourceFactory= */ cronetDataSourceFactory) // Inject the DefaultDataSource.Factory when creating the player. val player = ExoPlayer.Builder(context) .setMediaSourceFactory( DefaultMediaSourceFactory(context).setDataSourceFactory(dataSourceFactory) ) .build()
Java
// Given a CronetEngine and Executor, build a CronetDataSource.Factory. CronetDataSource.Factory cronetDataSourceFactory = new CronetDataSource.Factory(cronetEngine, executor); // Wrap the CronetDataSource.Factory in a DefaultDataSource.Factory, which adds // in support for requesting data from other sources (such as files, resources, // etc). DefaultDataSource.Factory dataSourceFactory = new DefaultDataSource.Factory( context, /* baseDataSourceFactory= */ cronetDataSourceFactory); // Inject the DefaultDataSource.Factory when creating the player. ExoPlayer player = new ExoPlayer.Builder(context) .setMediaSourceFactory( new DefaultMediaSourceFactory(context).setDataSourceFactory(dataSourceFactory)) .build();
מערכי רשת נתמכים
ExoPlayer מספק תמיכה ישירה ב-HttpEngine, ב-Cronet, ב-OkHttp ובמערך ברירת המחדל המובנה של Android לניהול רשת. אפשר גם להרחיב את ExoPlayer כדי לתמוך בכל מחסנית רשת אחרת שפועלת ב-Android.
HttpEngine
HttpEngine היא מחסנית הרשת המומלצת כברירת מחדל ב-Android מ-API 34 (או מתוספים 7 של S). ברוב המקרים, הוא משתמש באופן פנימי במערך רשת Cronet, שתומך בפרוטוקולים HTTP, HTTP/2 ו-HTTP/3 דרך פרוטוקולי QUIC.
ExoPlayer תומך ב-HttpEngine באמצעות HttpEngineDataSource.Factory. אפשר להוסיף את המפעל הזה של מקורות נתונים כמו שמתואר במאמר הגדרת ExoPlayer לשימוש במערך ספציפי של פרוטוקולי רשת.
Cronet
Cronet היא חבילה של פרוטוקולי רשת של Chromium שזמינה לאפליקציות ל-Android כספרייה. Cronet משתמש בכמה טכנולוגיות שמפחיתות את זמן האחזור ומגדילות את קצב העברת הנתונים של בקשות הרשת שהאפליקציה צריכה כדי לפעול, כולל בקשות שנוצרות על ידי ExoPlayer. הוא תומך באופן מובנה בפרוטוקולים HTTP, HTTP/2 ו-HTTP/3 over QUIC. חלק מאפליקציות הסטרימינג הגדולות בעולם, כולל YouTube, משתמשות ב-Cronet.
ExoPlayer תומך ב-Cronet דרך ספריית Cronet.
הוראות מפורטות לשימוש בספרייה זמינות ב-README.md. הערה: לספריית Cronet יש אפשרות להשתמש בשלושה יישומי Cronet בסיסיים:
- Google Play Services: אנחנו ממליצים להשתמש בהטמעה הזו ברוב המקרים, ולחזור לסטטוס ברירת המחדל של Android (
DefaultHttpDataSource) אם Google Play Services לא זמין. - Cronet Embedded: יכול להיות שזו תהיה בחירה טובה אם אחוז גדול מהמשתמשים שלכם נמצאים בשווקים שבהם שירותי Google Play לא זמינים באופן נרחב, או אם אתם רוצים לשלוט בגרסה המדויקת של הטמעת Cronet שבה נעשה שימוש. החיסרון העיקרי של Cronet Embedded הוא שהוא מוסיף כ-8MB לאפליקציה.
- Cronet Fallback: הטמעת ה-fallback של Cronet מטמיעה את ה-API של Cronet כעטיפה סביב מחסנית הרשת המובנית של Android. אין להשתמש בו עם ExoPlayer, כי שימוש ישיר במערך הרשת המובנה של Android (באמצעות
DefaultHttpDataSource) יעיל יותר.
OkHttp
OkHttp היא עוד מחסנית רשת מודרנית שנמצאת בשימוש נרחב באפליקציות פופולריות רבות ל-Android. הוא תומך ב-HTTP וב-HTTP/2, אבל עדיין לא תומך ב-HTTP/3 דרך QUIC.
ExoPlayer תומך ב-OkHttp דרך ספריית OkHttp.
הוראות מפורטות לשימוש בספרייה זמינות ב-README.md. כשמשתמשים בספריית OkHttp, מחסנית הרשת מוטמעת באפליקציה. זה דומה ל-Cronet Embedded, אבל OkHttp קטנה משמעותית, והיא מוסיפה פחות מ-1MB לאפליקציה.
מערך הרשת המובנה של Android
ExoPlayer תומך בשימוש במערך הרשת המובנה של Android עם DefaultHttpDataSource ו-DefaultHttpDataSource.Factory, שהם חלק מספריית הליבה של ExoPlayer.
היישום המדויק של מחסנית הרשת תלוי בתוכנה שפועלת במכשיר הבסיסי. ברוב המכשירים יש תמיכה רק ב-HTTP (כלומר, אין תמיכה ב-HTTP/2 וב-HTTP/3 באמצעות QUIC).
מערכות אחרות של רשתות
אפשר גם לשלב באפליקציות מחסניות אחרות של פרוטוקולי רשת עם ExoPlayer.
כדי לעשות זאת, מטמיעים HttpDataSource שעוטף את מחסנית הרשת,
יחד עם HttpDataSource.Factory תואם. ספריות Cronet ו-OkHttp של ExoPlayer הן דוגמאות טובות לאופן שבו אפשר לעשות זאת.
כשמשלבים עם מחסנית רשת של Java בלבד, מומלץ להטמיע DataSourceContractTest כדי לבדוק שההטמעה של HttpDataSource פועלת בצורה תקינה. OkHttpDataSourceContractTest בספריית OkHttp היא דוגמה טובה לאופן שבו עושים זאת.
בחירת מחסנית רשת
בטבלה הבאה מפורטים היתרונות והחסרונות של מחסניות הרשת שנתמכות על ידי ExoPlayer.
| מחסנית רשת | פרוטוקולים | השפעה על גודל ה-APK | פתקים |
|---|---|---|---|
| HttpEngine | HTTP HTTP/2 HTTP/3 over QUIC |
ללא | זמין רק ב-API 34 או ב-S Extensions 7 |
| Cronet (Google Play Services) | HTTP HTTP/2 HTTP/3 over QUIC |
קטן (<100KB) |
נדרש Google Play Services. הגרסה של Cronet מתעדכנת אוטומטית |
| Cronet (Embedded) | HTTP HTTP/2 HTTP/3 over QUIC |
גדול (~8MB) |
גרסת Cronet נשלטת על ידי מפתח האפליקציה |
| Cronet (חלופה) | HTTP (משתנה בהתאם למכשיר) |
קטן (<100KB) |
לא מומלץ לשימוש ב-ExoPlayer |
| OkHttp | HTTP HTTP/2 |
קטן (פחות מ-1MB) |
|
| ערימת רשת מובנית | HTTP (משתנה בהתאם למכשיר) |
ללא | ההטמעה משתנה בהתאם למכשיר |
הפרוטוקולים HTTP/2 ו-HTTP/3 over QUIC יכולים לשפר משמעותית את הביצועים של סטרימינג של מדיה. בפרט, כשמבצעים סטרימינג של מדיה מותאמת שמופצת באמצעות רשת להפצת תוכן (CDN), יש מקרים שבהם שימוש בפרוטוקולים האלה יכול לאפשר לרשתות להפצת תוכן לפעול בצורה יעילה הרבה יותר. לכן, התמיכה של HttpEngine ו-Cronet גם ב-HTTP/2 וגם ב-HTTP/3 דרך QUIC (והתמיכה של OkHttp ב-HTTP/2) היא יתרון משמעותי בהשוואה לשימוש במערך הרשת המובנה של Android, בתנאי שהשרתים שבהם התוכן מתארח תומכים גם בפרוטוקולים האלה.
כשמדובר בהזרמת מדיה בלבד, מומלץ להשתמש ב-HttpEngine או ב-Cronet שמוצעים על ידי Google Play Services, ולחזור ל-DefaultHttpDataSource אם Google Play Services לא זמין. ההמלצה הזו מאזנת בין האפשרות להשתמש ב-HTTP/2 וב-HTTP/3 באמצעות QUIC ברוב המכשירים, לבין הימנעות מהגדלה משמעותית של גודל ה-APK. יש חריגים להמלצה הזו. במקרים שבהם סביר להניח ש-Google Play Services לא תהיה זמינה בחלק משמעותי מהמכשירים שבהם האפליקציה תפעל, יכול להיות שיהיה מתאים יותר להשתמש ב-Cronet Embedded או ב-OkHttp. השימוש במערך הפרוטוקולים המובנה עשוי להיות מקובל אם גודל ה-APK הוא שיקול קריטי, או אם סטרימינג של מדיה הוא רק חלק קטן מהפונקציונליות של האפליקציה.
בנוסף למדיה, בדרך כלל מומלץ לבחור מחסנית רשת אחת לכל פעולות הרשת שמבצעת האפליקציה. כך אפשר לשתף משאבים (כמו שקעים) בין ExoPlayer לרכיבים אחרים באפליקציה, ולנהל אותם בצורה יעילה.
האפליקציה שלכם כנראה תצטרך לבצע פעולות ברשת שלא קשורות להפעלת מדיה, ולכן הבחירה שלכם במערכת הרשת צריכה להתבסס על ההמלצות שלמעלה לגבי סטרימינג של מדיה בנפרד, על הדרישות של רכיבים אחרים שמבצעים פעולות ברשת ועל החשיבות היחסית שלהם לאפליקציה.
שמירת מדיה במטמון
ExoPlayer תומך בשמירת בייטים שנטענו במטמון בדיסק, כדי למנוע טעינה חוזרת של אותם בייטים מהרשת. האפשרות הזו שימושית כשרוצים לחזור אחורה במדיה הנוכחית או לחזור על אותו פריט.
כדי להשתמש במטמון, צריך מופע SimpleCache שמפנה לספריית מטמון ייעודית ו-CacheDataSource.Factory:
Kotlin
// Note: This should be a singleton in your app. val databaseProvider = StandaloneDatabaseProvider(context) // An on-the-fly cache should evict media when reaching a maximum disk space limit. val cache = SimpleCache( downloadDirectory, LeastRecentlyUsedCacheEvictor(maxBytes), databaseProvider) // Configure the DataSource.Factory with the cache and factory for the desired HTTP stack. val cacheDataSourceFactory = CacheDataSource.Factory() .setCache(cache) .setUpstreamDataSourceFactory(httpDataSourceFactory) // Inject the DefaultDataSource.Factory when creating the player. val player = ExoPlayer.Builder(context) .setMediaSourceFactory( DefaultMediaSourceFactory(context).setDataSourceFactory(cacheDataSourceFactory)) .build()
Java
// Note: This should be a singleton in your app. DatabaseProvider databaseProvider = new StandaloneDatabaseProvider(context); // An on-the-fly cache should evict media when reaching a maximum disk space limit. Cache cache = new SimpleCache( downloadDirectory, new LeastRecentlyUsedCacheEvictor(maxBytes), databaseProvider); // Configure the DataSource.Factory with the cache and factory for the desired HTTP stack. DataSource.Factory cacheDataSourceFactory = new CacheDataSource.Factory() .setCache(cache) .setUpstreamDataSourceFactory(httpDataSourceFactory); // Inject the DefaultDataSource.Factory when creating the player. ExoPlayer player = new ExoPlayer.Builder(context) .setMediaSourceFactory( new DefaultMediaSourceFactory(context).setDataSourceFactory(cacheDataSourceFactory)) .build();