โดยทั่วไปแล้ว 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 คือโรงงานที่สอดคล้องกับ
Network Stack ที่คุณต้องการ เลเยอร์ 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 (หรือ S
ส่วนขยาย 7) ในกรณีส่วนใหญ่ จะใช้สแต็กเครือข่าย Cronet ภายใน
รองรับโปรโตคอล HTTP, HTTP/2 และ HTTP/3 ผ่านโปรโตคอล QUIC
ExoPlayer รองรับ HttpEngine ด้วย HttpEngineDataSource.Factory คุณสามารถ
แทรก Factory แหล่งข้อมูลนี้ตามที่อธิบายไว้ในการกำหนดค่า ExoPlayer ให้ใช้
สแต็กเครือข่ายที่เฉพาะเจาะจง
Cronet
Cronet คือสแต็กเครือข่าย Chromium ที่พร้อมใช้งานสำหรับแอป Android ในรูปแบบไลบรารี Cronet ใช้ประโยชน์จากเทคโนโลยีหลายอย่างที่ช่วยลดเวลาในการตอบสนองและเพิ่มปริมาณงานของคำขอเครือข่ายที่แอปของคุณต้องใช้ในการทำงาน ซึ่งรวมถึงคำขอที่ ExoPlayer สร้างขึ้น โดยรองรับโปรโตคอล HTTP, HTTP/2 และ HTTP/3 ผ่าน QUIC โดยกำเนิด แอปสตรีมมิงที่ใหญ่ที่สุดในโลกบางแอปใช้ Cronet รวมถึง YouTube
ExoPlayer รองรับ Cronet ผ่านไลบรารี Cronet
ดูวิธีการโดยละเอียดเกี่ยวกับวิธีใช้ได้ที่README.mdของไลบรารี โปรดทราบว่าไลบรารี Cronet สามารถใช้การติดตั้งใช้งาน Cronet พื้นฐาน 3 รายการต่อไปนี้
- บริการ Google Play: เราขอแนะนำให้ใช้การติดตั้งใช้งานนี้ในกรณีส่วนใหญ่
และกลับไปใช้สแต็กเครือข่ายในตัวของ Android
(
DefaultHttpDataSource) หากบริการ Google Play ไม่พร้อมใช้งาน - Cronet แบบฝัง: อาจเป็นตัวเลือกที่ดีหากผู้ใช้ส่วนใหญ่ อยู่ในตลาดที่ Google Play Services ไม่พร้อมให้บริการอย่างแพร่หลาย หรือหากคุณ ต้องการควบคุมเวอร์ชันที่แน่นอนของการติดตั้งใช้งาน Cronet ที่ใช้ ข้อเสียที่สำคัญของ Cronet Embedded คือการเพิ่มขนาดแอปของคุณประมาณ 8 MB
- การสำรองข้อมูล Cronet: การติดตั้งใช้งานสำรองของ Cronet จะใช้ API ของ Cronet เป็น Wrapper รอบสแต็กเครือข่ายในตัวของ Android ไม่ควรใช้กับ ExoPlayer เนื่องจากการใช้สแต็กเครือข่ายในตัวของ Android โดยตรง (โดยใช้
DefaultHttpDataSource) มีประสิทธิภาพมากกว่า
OkHttp
OkHttp เป็นอีกหนึ่งสแต็กเครือข่ายที่ทันสมัยซึ่ง แอป Android ยอดนิยมหลายแอปใช้กันอย่างแพร่หลาย โดยรองรับ HTTP และ HTTP/2 แต่ยังไม่รองรับ HTTP/3 ผ่าน QUIC
ExoPlayer รองรับ OkHttp ผ่านไลบรารี OkHttp
ดูวิธีการโดยละเอียดเกี่ยวกับวิธีใช้ได้ที่README.mdของไลบรารี เมื่อใช้ไลบรารี OkHttp สแต็กเครือข่ายจะฝังอยู่ในแอป ซึ่งคล้ายกับ Cronet Embedded แต่ OkHttp มีขนาดเล็กกว่ามาก โดยจะเพิ่มขนาดแอปไม่ถึง 1 MB
สแต็กเครือข่ายในตัวของ 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 ผ่าน QUIC |
ไม่มี | ใช้ได้เฉพาะใน API 34 หรือ S Extensions 7 |
| Cronet (บริการ Google Play) | HTTP HTTP/2 HTTP/3 ผ่าน QUIC |
เล็ก (<100 KB) |
ต้องใช้บริการ Google Play เวอร์ชัน Cronet ได้รับการอัปเดตโดยอัตโนมัติ |
| Cronet (ฝัง) | HTTP HTTP/2 HTTP/3 ผ่าน QUIC |
ใหญ่ (~8MB) |
นักพัฒนาแอปเป็นผู้ควบคุมเวอร์ชัน Cronet |
| Cronet (สำรอง) | HTTP (แตกต่างกันไปตามอุปกรณ์) |
เล็ก (<100 KB) |
ไม่แนะนำสำหรับ ExoPlayer |
| OkHttp | HTTP HTTP/2 |
เล็ก (น้อยกว่า 1 MB) |
|
| สแต็กเครือข่ายในตัว | HTTP (แตกต่างกันไปตามอุปกรณ์) |
ไม่มี | การใช้งานจะแตกต่างกันไปตามอุปกรณ์ |
โปรโตคอล HTTP/2 และ HTTP/3 ผ่าน QUIC ช่วยปรับปรุงประสิทธิภาพการสตรีมสื่อได้อย่างมาก โดยเฉพาะอย่างยิ่งเมื่อสตรีมสื่อแบบปรับอัตโนมัติที่ จัดจำหน่ายโดยใช้เครือข่ายนำส่งข้อมูล (CDN) มีกรณีที่ การใช้โปรโตคอลเหล่านี้จะช่วยให้ CDN ทำงานได้อย่างมีประสิทธิภาพมากขึ้น ด้วยเหตุนี้ การรองรับทั้ง HTTP/2 และ HTTP/3 ของ HttpEngine และ Cronet ผ่าน QUIC (และการรองรับ HTTP/2 ของ OkHttp) จึงเป็นประโยชน์อย่างมากเมื่อเทียบกับ การใช้สแต็กเครือข่ายในตัวของ Android โดยมีเงื่อนไขว่าเซิร์ฟเวอร์ที่โฮสต์เนื้อหาต้องรองรับโปรโตคอลเหล่านี้ด้วย
เมื่อพิจารณาการสตรีมสื่อแยกกัน เราขอแนะนำให้ใช้ HttpEngine หรือ
Cronet ที่ให้บริการโดย Google Play Services โดยจะกลับไปใช้ DefaultHttpDataSource
หาก Google Play Services ไม่พร้อมใช้งาน คำแนะนำนี้สร้างสมดุลที่ดีระหว่างการเปิดใช้ HTTP/2 และ HTTP/3 ผ่าน QUIC ในอุปกรณ์ส่วนใหญ่ และการหลีกเลี่ยงไม่ให้ขนาด APK เพิ่มขึ้นอย่างมาก คำแนะนำนี้มีข้อยกเว้น
ในกรณีที่บริการ Google Play อาจไม่พร้อมใช้งาน
ในอุปกรณ์ส่วนใหญ่ที่ใช้แอปของคุณ
การใช้ 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();