ExoPlayer มักใช้สำหรับการสตรีมสื่อผ่านอินเทอร์เน็ต โดยรองรับสแต็กเครือข่ายหลายรายการสำหรับการส่งคำขอเครือข่ายที่เกี่ยวข้อง ตัวเลือกสแต็กเครือข่ายอาจส่งผลต่อประสิทธิภาพการสตรีมอย่างมาก
หน้านี้จะอธิบายวิธีกำหนดค่า ExoPlayer ให้ใช้สแต็กเครือข่ายที่คุณเลือก แสดงรายการตัวเลือกที่ใช้ได้ ให้คำแนะนำเกี่ยวกับวิธีเลือกสแต็กเครือข่ายสำหรับแอป และอธิบายวิธีเปิดใช้การแคชสำหรับสื่อที่สตรีม
การกำหนดค่า ExoPlayer ให้ใช้สแต็กเครือข่ายที่เฉพาะเจาะจง
ExoPlayer โหลดข้อมูลผ่านคอมโพเนนต์ DataSource ซึ่งได้มาจากอินสแตนซ์ DataSource.Factory ที่แทรกจากโค้ดแอป
หากแอปของคุณต้องการเล่นเฉพาะเนื้อหา http(s) การเลือกสแต็กเครือข่ายจะทำได้ง่ายๆ เพียงอัปเดตอินสแตนซ์ DataSource.Factory ที่แอปของคุณแทรกให้เป็นอินสแตนซ์ของ HttpDataSource.Factory ที่สอดคล้องกับสแต็กเครือข่ายที่คุณต้องการใช้ หากแอปของคุณต้องเล่นเนื้อหาที่ไม่ใช่ http(s) ด้วย เช่น ไฟล์ในเครื่อง ให้ใช้ DefaultDataSource.Factory ดังนี้
Kotlin
DefaultDataSource.Factory( context, /* baseDataSourceFactory= */ PreferredHttpDataSource.Factory(context), )
Java
new DefaultDataSource.Factory( context, /* baseDataSourceFactory= */ new PreferredHttpDataSource.Factory(context));
ในตัวอย่างนี้ 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 (หรือ S Extensions 7) ในกรณีส่วนใหญ่ ระบบจะใช้สแต็กเครือข่าย Cronet ภายใน ซึ่งรองรับโปรโตคอล HTTP, HTTP/2 และ HTTP/3 ผ่าน QUIC
ExoPlayer รองรับ HttpEngine ด้วย HttpEngineDataSource.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 Embedded: อาจเป็นตัวเลือกที่ดีหากผู้ใช้ส่วนใหญ่อยู่ในตลาดที่บริการ Google Play ไม่พร้อมให้บริการอย่างแพร่หลาย หรือหากคุณต้องการควบคุมเวอร์ชันที่แน่นอนของการติดตั้งใช้งาน Cronet ที่ใช้ ข้อเสียหลักของ Cronet Embedded คือจะเพิ่มขนาดแอปประมาณ 8 MB
- Cronet Fallback: การใช้งาน Cronet Fallback จะใช้ 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 |
เล็ก (<100KB) |
ต้องใช้บริการ Google Play เวอร์ชัน Cronet จะอัปเดตโดยอัตโนมัติ |
| Cronet (แบบฝัง) | HTTP HTTP/2 HTTP/3 ผ่าน QUIC |
ใหญ่ (~8MB) |
เวอร์ชัน Cronet ที่ควบคุมโดยนักพัฒนาแอป |
| Cronet (สำรอง) | HTTP (แตกต่างกันไปตามอุปกรณ์) |
เล็ก (<100KB) |
ไม่แนะนำสำหรับ ExoPlayer |
| OkHttp | HTTP HTTP/2 |
เล็ก (<1 MB) |
|
| สแต็กเครือข่ายในตัว | HTTP (แตกต่างกันไปตามอุปกรณ์) |
ไม่มี | การติดตั้งใช้งานจะแตกต่างกันไปตามอุปกรณ์ |
โปรโตคอล HTTP/2 และ HTTP/3 ผ่าน QUIC ช่วยปรับปรุงประสิทธิภาพการสตรีมสื่อได้อย่างมาก โดยเฉพาะอย่างยิ่งเมื่อสตรีมสื่อแบบปรับอัตโนมัติที่เผยแพร่โดยใช้เครือข่ายเผยแพร่เนื้อหา (CDN) มีบางกรณีที่การใช้โปรโตคอลเหล่านี้ช่วยให้ CDN ทำงานได้อย่างมีประสิทธิภาพมากขึ้น ด้วยเหตุนี้ การรองรับทั้ง HTTP/2 และ HTTP/3 ผ่าน QUIC ของ HttpEngine และ Cronet (และการรองรับ HTTP/2 ของ OkHttp) จึงเป็นข้อได้เปรียบที่สำคัญเมื่อเทียบกับการใช้สแต็กเครือข่ายในตัวของ Android หากเซิร์ฟเวอร์ที่โฮสต์เนื้อหารองรับโปรโตคอลเหล่านี้ด้วย
เมื่อพิจารณาการสตรีมสื่อแยกต่างหาก เราขอแนะนำให้ใช้ HttpEngine หรือ Cronet ที่บริการ Google Play มีให้ โดยเปลี่ยนไปใช้ DefaultHttpDataSource หากบริการ Google Play ไม่พร้อมใช้งาน คำแนะนำนี้สร้างสมดุลที่ดีระหว่างการเปิดใช้ 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();