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