- การแก้ไขข้อผิดพลาด "ไม่อนุญาตให้มีการรับส่งข้อมูล HTTP แบบข้อความธรรมดา"
- การแก้ไขข้อผิดพลาด "SSLHandshakeException", "CertPathValidatorException" และ "ERR_CERT_AUTHORITY_INVALID"
- เหตุใดไฟล์สื่อบางไฟล์จึงกรอไม่ได้
- เหตุใดการกรอในไฟล์ MP3 บางไฟล์จึงไม่แม่นยำ
- เหตุใดการกรอวิดีโอของฉันจึงช้า
- เหตุใดไฟล์ MPEG-TS บางไฟล์จึงเล่นไม่ได้
- เหตุใดจึงไม่พบคำบรรยายในไฟล์ MPEG-TS บางไฟล์
- เหตุใดไฟล์ MP4/FMP4 บางไฟล์จึงเล่นไม่ถูกต้อง
- เหตุใดสตรีมบางรายการจึงแสดงผลไม่สำเร็จด้วยโค้ดตอบกลับ HTTP 301 หรือ 302
- เหตุใดสตรีมบางรายการจึงแสดงผลไม่สำเร็จด้วย UnrecognizedInputFormatException
- เหตุใด setPlaybackParameters จึงทำงานไม่ถูกต้องในอุปกรณ์บางเครื่อง
- ข้อผิดพลาด "Player is accessed on the wrong thread" หมายความว่าอย่างไร
- ฉันจะแก้ไขข้อผิดพลาด "Unexpected status line: ICY 200 OK" ได้อย่างไร
- ฉันจะค้นหาว่าสตรีมที่กำลังเล่นเป็นสตรีมแบบสดหรือไม่ได้อย่างไร
- ฉันจะเล่นเสียงต่อไปได้อย่างไรเมื่อแอปของฉันทำงานอยู่เบื้องหลัง
- เหตุใด ExoPlayer จึงรองรับเนื้อหาของฉัน แต่ไลบรารี ExoPlayer Cast ไม่รองรับ
- เหตุใดเนื้อหาจึงเล่นไม่สำเร็จ แต่ไม่มีข้อผิดพลาดปรากฏขึ้น
- ฉันจะโหลดไลบรารีการถอดรหัสเพื่อใช้ในการเล่นได้อย่างไร
- ฉันเล่นวิดีโอ YouTube ด้วย ExoPlayer ได้โดยตรงไหม
- การเล่นวิดีโอติดขัด
- ข้อผิดพลาด Lint ของ API ที่ไม่เสถียร
การแก้ไขข้อผิดพลาด "ไม่อนุญาตให้มีการรับส่งข้อมูล HTTP แบบข้อความธรรมดา"
ข้อผิดพลาดนี้จะเกิดขึ้นหากแอปขอการรับส่งข้อมูล HTTP แบบข้อความธรรมดา (นั่นคือ http:// แทนที่จะเป็น https://) เมื่อการกำหนดค่าความปลอดภัยของเครือข่ายไม่อนุญาต หากแอปกำหนดเป้าหมายเป็น Android 9 (ระดับ API 28) ขึ้นไป การรับส่งข้อมูล HTTP แบบข้อความธรรมดาจะถูกปิดใช้ในการกำหนดค่าเริ่มต้น
หากแอปต้องทำงานกับการรับส่งข้อมูล HTTP แบบข้อความธรรมดา คุณจะต้องใช้การกำหนดค่าความปลอดภัยของเครือข่ายที่อนุญาต ดูรายละเอียดได้ในเอกสารประกอบเกี่ยวกับความปลอดภัยของเครือข่ายของ Android
หากต้องการเปิดใช้การรับส่งข้อมูล HTTP แบบข้อความธรรมดาทั้งหมด คุณเพียงแค่เพิ่ม
android:usesCleartextTraffic="true" ลงในองค์ประกอบ application ของ
AndroidManifest.xml ของแอป
แอปเดโม ExoPlayer ใช้การกำหนดค่าความปลอดภัยของเครือข่ายเริ่มต้น จึงไม่อนุญาตให้มีการรับส่งข้อมูล HTTP แบบข้อความธรรมดา คุณเปิดใช้ได้โดยใช้คำแนะนำด้านบน
การแก้ไขข้อผิดพลาด "SSLHandshakeException", "CertPathValidatorException" และ "ERR_CERT_AUTHORITY_INVALID"
SSLHandshakeException, CertPathValidatorException และ ERR_CERT_AUTHORITY_INVALID ทั้งหมดบ่งบอกถึงปัญหาเกี่ยวกับใบรับรอง SSL ของเซิร์ฟเวอร์ ข้อผิดพลาดเหล่านี้ไม่ได้เกิดขึ้นเฉพาะกับ ExoPlayer ดูรายละเอียดเพิ่มเติมได้ใน
เอกสารประกอบเกี่ยวกับ SSL ของ Android
เหตุใดไฟล์สื่อบางไฟล์จึงกรอไม่ได้
โดยค่าเริ่มต้น ExoPlayer ไม่รองรับการกรอในสื่อที่วิธีเดียวในการดำเนินการกรอที่แม่นยำคือให้เพลเยอร์สแกนและจัดทำดัชนีไฟล์ทั้งหมด ExoPlayer ถือว่าไฟล์ดังกล่าวเป็นไฟล์ที่กรอไม่ได้ รูปแบบคอนเทนเนอร์สื่อสมัยใหม่ส่วนใหญ่มีข้อมูลเมตาสำหรับการกรอ (เช่น ดัชนีตัวอย่าง) มีอัลกอริทึมการกรอที่กำหนดไว้อย่างดี (เช่น การค้นหาแบบแบ่งครึ่งที่ประมาณค่าสำหรับ Ogg) หรือระบุว่าเนื้อหามีบิตเรตคงที่ ในกรณีเหล่านี้ ExoPlayer รองรับและดำเนินการกรอได้อย่างมีประสิทธิภาพ
หากคุณต้องการกรอแต่มีสื่อที่กรอไม่ได้ เราขอแนะนำให้แปลงเนื้อหาให้ใช้รูปแบบคอนเทนเนอร์ที่เหมาะสมกว่า สำหรับไฟล์ MP3, ADTS และ AMR คุณยังเปิดใช้การกรอได้โดยถือว่าไฟล์มีอัตราบิต คงที่ตามที่อธิบายไว้ ที่นี่
เหตุใดการกรอในไฟล์ MP3 บางไฟล์จึงไม่แม่นยำ
ไฟล์ MP3 ที่มีบิตเรตผันแปร (VBR) ไม่เหมาะสำหรับกรณีการใช้งานที่ต้องมีการกรอที่แม่นยำ มี 2 เหตุผลดังนี้
- สำหรับการกรอที่แม่นยำ รูปแบบคอนเทนเนอร์ควรระบุการแมปเวลาเป็นไบต์ที่แม่นยำในส่วนหัว การแมปนี้ช่วยให้เพลเยอร์แมปเวลาที่ขอให้กรอเป็นออฟเซ็ตไบต์ที่เกี่ยวข้อง และเริ่มขอ แยกวิเคราะห์ และเล่นสื่อจากออฟเซ็ตนั้น น่าเสียดายที่ส่วนหัวที่ใช้ระบุการแมปนี้ใน MP3 (เช่น ส่วนหัว XING) มักไม่แม่นยำ
- สำหรับรูปแบบคอนเทนเนอร์ที่ไม่มีการแมปเวลาเป็นไบต์ที่แม่นยำ (หรือไม่มีการแมปเวลาเป็นไบต์เลย) คุณยังคงกรอได้อย่างแม่นยำหากคอนเทนเนอร์มีไทม์สแตมป์ตัวอย่างแบบสัมบูรณ์ในสตรีม ในกรณีนี้ เพลเยอร์สามารถแมปเวลาที่ขอให้กรอเป็นออฟเซ็ตไบต์ที่คาดเดาได้ดีที่สุด เริ่มขอสื่อจากออฟเซ็ตนั้น แยกวิเคราะห์ไทม์สแตมป์ตัวอย่างแบบสัมบูรณ์แรก และดำเนินการค้นหาแบบไบนารีแบบมีคำแนะนำในสื่อได้อย่างมีประสิทธิภาพจนกว่าจะพบตัวอย่างที่ถูกต้อง น่าเสียดายที่ MP3 ไม่มีไทม์สแตมป์ตัวอย่างแบบสัมบูรณ์ในสตรีม จึงไม่สามารถใช้วิธีนี้ได้
ด้วยเหตุนี้ วิธีเดียวที่จะกรอไฟล์ MP3 แบบ VBR ได้อย่างแม่นยำคือการสแกนไฟล์ทั้งหมดและสร้างการแมปเวลาเป็นไบต์ในเพลเยอร์ด้วยตนเอง คุณเปิดใช้กลยุทธ์นี้ได้โดยใช้ FLAG_ENABLE_INDEX_SEEKING,
ซึ่งตั้งค่าได้ใน DefaultExtractorsFactory โดยใช้
setMp3ExtractorFlags โปรดทราบว่าวิธีนี้ไม่เหมาะกับไฟล์ MP3 ขนาดใหญ่ โดยเฉพาะอย่างยิ่งหากผู้ใช้พยายามกรอไปใกล้ส่วนท้ายของสตรีมหลังจากเริ่มเล่นได้ไม่นาน ซึ่งกำหนดให้เพลเยอร์ต้องรอจนกว่าจะดาวน์โหลดและจัดทำดัชนีสตรีมทั้งหมดก่อนที่จะกรอ ใน ExoPlayer เรา
ตัดสินใจที่จะเพิ่มประสิทธิภาพความเร็วมากกว่าความแม่นยำในกรณีนี้ และ
FLAG_ENABLE_INDEX_SEEKING จึงปิดใช้งานโดยค่าเริ่มต้น
หากคุณควบคุมสื่อที่กำลังเล่นได้ เราขอแนะนำให้ใช้รูปแบบคอนเทนเนอร์ที่เหมาะสมกว่า เช่น MP4 เราไม่ทราบกรณีการใช้งานที่ MP3 เป็นตัวเลือกที่ดีที่สุดสำหรับรูปแบบสื่อ
เหตุใดการกรอวิดีโอของฉันจึงช้า
เมื่อเพลเยอร์กรอไปยังตำแหน่งการเล่นใหม่ในวิดีโอ เพลเยอร์ต้องทำ 2 สิ่งต่อไปนี้
- โหลดข้อมูลที่ตรงกับตำแหน่งการเล่นใหม่ลงในบัฟเฟอร์ (อาจไม่จำเป็นหากข้อมูลนี้อยู่ในบัฟเฟอร์อยู่แล้ว)
- ล้างตัวถอดรหัสวิดีโอและเริ่มถอดรหัสจาก I-frame (คีย์เฟรม) ก่อน ตำแหน่งการเล่นใหม่ เนื่องจากมีการเข้ารหัสภายในเฟรมที่รูปแบบการบีบอัดวิดีโอส่วนใหญ่ใช้ เพื่อให้การกรอ แม่นยำ (นั่นคือ การเล่นจะเริ่มตรงตำแหน่งที่กรอ) ระบบจะต้องถอดรหัสและทิ้งเฟรมทั้งหมดระหว่าง I-frame ก่อนหน้ากับตำแหน่งที่กรอทันที (โดยไม่แสดงบนหน้าจอ)
คุณสามารถลดเวลาในการตอบสนองที่เกิดจาก (1) ได้โดยการเพิ่มปริมาณ ข้อมูลที่บัฟเฟอร์ไว้ในหน่วยความจำโดยเพลเยอร์ หรือ การแคชล่วงหน้าข้อมูลลงในดิสก์
คุณสามารถลดเวลาในการตอบสนองที่เกิดจาก (2) ได้โดยการลดความแม่นยำ
ของการกรอโดยใช้ ExoPlayer.setSeekParameters หรือเข้ารหัสวิดีโอใหม่
ให้มี I-frame บ่อยขึ้น (ซึ่งจะทำให้ไฟล์เอาต์พุตมีขนาดใหญ่ขึ้น)
เหตุใดไฟล์ MPEG-TS บางไฟล์จึงเล่นไม่ได้
ไฟล์ MPEG-TS บางไฟล์ไม่มีตัวคั่นหน่วยการเข้าถึง (AUD) โดยค่าเริ่มต้น ExoPlayer อาศัย AUD เพื่อตรวจหาขอบเขตเฟรมได้อย่างรวดเร็ว ในทำนองเดียวกัน ไฟล์ MPEG-TS บางไฟล์ไม่มีคีย์เฟรม IDR โดยค่าเริ่มต้น ExoPlayer จะพิจารณาคีย์เฟรมประเภทนี้เท่านั้น
ExoPlayer จะดูเหมือนติดอยู่ในสถานะการบัฟเฟอร์เมื่อได้รับคำขอให้เล่นไฟล์ MPEG-TS ที่ไม่มี AUD หรือคีย์เฟรม IDR หากต้องการเล่นไฟล์ดังกล่าว
คุณสามารถทำได้โดยใช้ FLAG_DETECT_ACCESS_UNITS และ
FLAG_ALLOW_NON_IDR_KEYFRAMES ตามลำดับ คุณตั้งค่าแฟล็กเหล่านี้ได้โดยตั้งค่าใน
DefaultExtractorsFactory โดยใช้ setTsExtractorFlags หรือใน
DefaultHlsExtractorFactory โดยใช้
เครื่องมือสร้าง
การใช้ FLAG_DETECT_ACCESS_UNITS ไม่มีผลข้างเคียงใดๆ นอกเหนือจากต้องใช้การคำนวณมากกว่าการตรวจหาขอบเขตเฟรมตาม AUD การใช้ FLAG_ALLOW_NON_IDR_KEYFRAMES อาจทำให้ภาพเสียหายชั่วคราวเมื่อเริ่มเล่นและหลังจากกรอทันทีเมื่อเล่นไฟล์ MPEG-TS บางไฟล์
เหตุใดจึงไม่พบคำบรรยายในไฟล์ MPEG-TS บางไฟล์
ไฟล์ MPEG-TS บางไฟล์มีแทร็ก CEA-608 แต่ไม่ได้ประกาศแทร็กเหล่านี้ในข้อมูลเมตาของคอนเทนเนอร์ ExoPlayer จึงตรวจหาแทร็กเหล่านี้ไม่ได้ คุณระบุแทร็กคำบรรยายด้วยตนเองได้โดยระบุรายการรูปแบบคำบรรยายที่คาดไว้ให้กับ DefaultExtractorsFactory ซึ่งรวมถึงช่องการช่วยเหลือพิเศษที่ใช้ระบุแทร็กคำบรรยายในสตรีม MPEG-TS ได้
Kotlin
val extractorsFactory = DefaultExtractorsFactory() .setTsSubtitleFormats( listOf( Format.Builder() .setSampleMimeType(MimeTypes.APPLICATION_CEA608) .setAccessibilityChannel(accessibilityChannel) // Set other subtitle format info, such as language. .build() ) ) val player: Player = ExoPlayer.Builder(context, DefaultMediaSourceFactory(context, extractorsFactory)).build()
Java
DefaultExtractorsFactory extractorsFactory = new DefaultExtractorsFactory() .setTsSubtitleFormats( ImmutableList.of( new Format.Builder() .setSampleMimeType(MimeTypes.APPLICATION_CEA608) .setAccessibilityChannel(accessibilityChannel) // Set other subtitle format info, such as language. .build())); Player player = new ExoPlayer.Builder(context, new DefaultMediaSourceFactory(context, extractorsFactory)) .build();
เหตุใดไฟล์ MP4/FMP4 บางไฟล์จึงเล่นไม่ถูกต้อง
ไฟล์ MP4/FMP4 บางไฟล์มีรายการแก้ไขที่เขียนไทม์ไลน์สื่อใหม่โดยข้าม ย้าย หรือทำซ้ำรายการตัวอย่าง ExoPlayer รองรับการใช้รายการแก้ไขบางส่วน เช่น สามารถหน่วงเวลาหรือทำซ้ำกลุ่มตัวอย่างที่เริ่มต้นในตัวอย่างการซิงโครไนซ์ แต่จะไม่ตัดตัวอย่างเสียงหรือสื่อ preroll สำหรับการแก้ไขที่ไม่ได้เริ่มต้นในตัวอย่างการซิงโครไนซ์
หากพบว่าสื่อบางส่วนขาดหายไปหรือทำซ้ำโดยไม่คาดคิด
ให้ลองตั้งค่า Mp4Extractor.FLAG_WORKAROUND_IGNORE_EDIT_LISTS หรือ
FragmentedMp4Extractor.FLAG_WORKAROUND_IGNORE_EDIT_LISTS ซึ่งจะทำให้
ตัวแยกวิเคราะห์ละเว้นรายการแก้ไขทั้งหมด คุณตั้งค่าเหล่านี้ได้ใน โดยใช้ setMp4ExtractorFlags หรือ
setFragmentedMp4ExtractorFlagsDefaultExtractorsFactory
เหตุใดสตรีมบางรายการจึงแสดงผลไม่สำเร็จด้วยโค้ดตอบกลับ HTTP 301 หรือ 302
รหัสการตอบกลับ HTTP 301 และ 302 ทั้งคู่บ่งบอกถึงการเปลี่ยนเส้นทาง ดูคำอธิบายสั้นๆ ได้ใน Wikipedia เมื่อ ExoPlayer ส่งคำขอและได้รับการตอบกลับที่มีรหัสสถานะ 301 หรือ 302 โดยปกติแล้ว ExoPlayer จะเปลี่ยนเส้นทางและเริ่มเล่นตามปกติ กรณีเดียวที่การดำเนินการนี้ไม่เกิดขึ้นโดยค่าเริ่มต้นคือการเปลี่ยนเส้นทางข้ามโปรโตคอล การเปลี่ยนเส้นทางข้ามโปรโตคอลคือการเปลี่ยนเส้นทางจาก HTTPS เป็น HTTP หรือในทางกลับกัน (หรือระหว่างโปรโตคอลคู่อื่นๆ ซึ่งพบได้น้อยกว่า) คุณสามารถทดสอบว่า URL ทำให้เกิดการเปลี่ยนเส้นทางข้ามโปรโตคอลหรือไม่โดยใช้ เครื่องมือบรรทัดคำสั่ง wget ดังนี้
wget "https://yourserver.example.com/test.mp3" 2>&1 | grep Location
เอาต์พุตควรมีลักษณะดังนี้
Location: https://secondserver.example.net/test.mp3 [following]
Location: http://thirdserver.example.org/test.mp3 [following]
ในตัวอย่างนี้มีการเปลี่ยนเส้นทาง 2 รายการ การเปลี่ยนเส้นทางแรกคือจาก https://yourserver.example.com/test.mp3 ไปยัง https://secondserver.example.net/test.mp3 ทั้งคู่เป็น HTTPS จึงไม่ใช่การเปลี่ยนเส้นทางข้ามโปรโตคอล การเปลี่ยนเส้นทางที่ 2 คือจาก https://secondserver.example.net/test.mp3 ไปยัง http://thirdserver.example.org/test.mp3 การเปลี่ยนเส้นทางนี้เป็นการเปลี่ยนเส้นทางจาก HTTPS เป็น HTTP จึงเป็นการเปลี่ยนเส้นทางข้ามโปรโตคอล ExoPlayer จะไม่เปลี่ยนเส้นทางนี้ในการกำหนดค่าเริ่มต้น ซึ่งหมายความว่าการเล่นจะแสดงผลไม่สำเร็จ
หากจำเป็น คุณสามารถกำหนดค่า ExoPlayer ให้เปลี่ยนเส้นทางข้ามโปรโตคอล
เมื่อสร้างอินสแตนซ์ DefaultHttpDataSource.Factory ที่ใช้ในแอปพลิเคชัน
ดูข้อมูลเกี่ยวกับการเลือกและการกำหนดค่าสแต็กเครือข่ายได้ที่นี่
here
เหตุใดสตรีมบางรายการจึงแสดงผลไม่สำเร็จด้วย UnrecognizedInputFormatException
คำถามนี้เกี่ยวข้องกับการเล่นที่แสดงผลไม่สำเร็จในรูปแบบต่อไปนี้
UnrecognizedInputFormatException: None of the available extractors
(MatroskaExtractor, FragmentedMp4Extractor, ...) could read the stream.
ความล้มเหลวนี้อาจเกิดจาก 2 สาเหตุ สาเหตุที่พบบ่อยที่สุดคือคุณพยายามเล่นเนื้อหา DASH (mpd), HLS (m3u8) หรือ SmoothStreaming (ism, isml) แต่เพลเยอร์พยายามเล่นเป็นสตรีมแบบโปรเกรสซีฟ หากต้องการเล่นสตรีมดังกล่าว
คุณต้องขึ้นต่อกันกับโมดูล ExoPlayer ที่เกี่ยวข้อง ในกรณีที่ URI ของสตรีมไม่ลงท้ายด้วยนามสกุลไฟล์มาตรฐาน คุณยังส่ง MimeTypes.APPLICATION_MPD, MimeTypes.APPLICATION_M3U8 หรือ MimeTypes.APPLICATION_SS ไปยัง setMimeType ของ MediaItem.Builder เพื่อระบุประเภทสตรีมอย่างชัดเจนได้ด้วย
สาเหตุที่ 2 ซึ่งพบได้น้อยกว่าคือ ExoPlayer ไม่รองรับรูปแบบคอนเทนเนอร์ของสื่อที่คุณพยายามเล่น ในกรณีนี้ ความล้มเหลวเป็นไปตามที่ตั้งใจไว้ แต่คุณสามารถส่งคำขอฟีเจอร์ไปยังเครื่องมือติดตามปัญหาของเราได้ โดยระบุรายละเอียดของรูปแบบคอนเทนเนอร์และสตรีมทดสอบ โปรดค้นหาคำขอฟีเจอร์ที่มีอยู่ก่อนส่งคำขอใหม่
เหตุใด setPlaybackParameters จึงทำงานไม่ถูกต้องในอุปกรณ์บางเครื่อง
เมื่อเรียกใช้บิลด์การแก้ไขข้อบกพร่องของแอปใน Android M และเวอร์ชันก่อนหน้า คุณอาจพบประสิทธิภาพการทำงานที่ไม่ราบรื่น อาร์ติแฟกต์ที่ได้ยิน และการใช้ CPU สูงเมื่อใช้ API setPlaybackParameters เนื่องจากระบบปิดใช้การเพิ่มประสิทธิภาพที่สำคัญต่อ API นี้สำหรับบิลด์ดีบักที่ทำงานใน Android เวอร์ชันดังกล่าว
โปรดทราบว่าปัญหานี้ส่งผลต่อบิลด์ดีบักเท่านั้น โดย ไม่ ส่งผลต่อบิลด์รีลีส ซึ่งระบบจะเปิดใช้การเพิ่มประสิทธิภาพเสมอ ดังนั้น รีลีสที่คุณมอบให้ผู้ใช้ปลายทางจึงไม่ควรได้รับผลกระทบจากปัญหานี้
ข้อผิดพลาด "Player is accessed on the wrong thread" หมายความว่าอย่างไร
ดูหมายเหตุเกี่ยวกับการทำงานแบบมัลติเธรดในหน้าเริ่มต้นใช้งาน
ฉันจะแก้ไขข้อผิดพลาด "Unexpected status line: ICY 200 OK" ได้อย่างไร
ปัญหานี้อาจเกิดขึ้นหากการตอบกลับของเซิร์ฟเวอร์มีบรรทัดสถานะ ICY แทนที่จะเป็นบรรทัดที่สอดคล้องกับ HTTP บรรทัดสถานะ ICY เลิกใช้งานแล้วและไม่ควรใช้ ดังนั้นหากคุณควบคุมเซิร์ฟเวอร์ได้ คุณควรจะอัปเดตเซิร์ฟเวอร์เพื่อให้การตอบกลับสอดคล้องกับ HTTP หากทำไม่ได้ การใช้ ไลบรารี ExoPlayer OkHttp จะช่วยแก้ปัญหาได้ เนื่องจากไลบรารีนี้จัดการบรรทัดสถานะ ICY ได้อย่างถูกต้อง
ฉันจะค้นหาว่าสตรีมที่กำลังเล่นเป็นสตรีมแบบสดหรือไม่ได้อย่างไร
คุณสามารถค้นหาวิธี isCurrentWindowLive ของเพลเยอร์ นอกจากนี้ คุณ
ยังตรวจสอบ isCurrentWindowDynamic เพื่อดูว่าหน้าต่างเป็นแบบไดนามิก
(นั่นคือ ยังคงอัปเดตอยู่เรื่อยๆ) หรือไม่
ฉันจะเล่นเสียงต่อไปได้อย่างไรเมื่อแอปของฉันทำงานอยู่เบื้องหลัง
ทำตามขั้นตอนต่อไปนี้เพื่อให้แน่ใจว่าเสียงจะเล่นต่อไปเมื่อแอปทำงานอยู่เบื้องหลัง
- คุณต้องมีบริการที่ทำงานอยู่เบื้องหน้า ซึ่งจะป้องกันไม่ให้ระบบหยุดกระบวนการของคุณเพื่อเพิ่มทรัพยากร
- คุณต้องเก็บ
WifiLockและWakeLockไว้ เพื่อให้แน่ใจว่าระบบจะเปิดวิทยุ WiFi และ CPU ไว้ คุณทำได้ง่ายๆ หากใช้ExoPlayerโดยเรียกใช้setWakeModeซึ่งจะรับและปล่อยการล็อกที่จำเป็นโดยอัตโนมัติ ตามเวลาที่เหมาะสม
คุณต้องปล่อยการล็อก (หากไม่ได้ใช้ setWakeMode) และหยุดบริการทันทีที่ไม่มีการเล่นเสียงอีกต่อไป
เหตุใด ExoPlayer จึงรองรับเนื้อหาของฉัน แต่ไลบรารี ExoPlayer Cast ไม่รองรับ
เนื้อหาที่คุณพยายามเล่นอาจไม่ได้ เปิดใช้ CORS เฟรมเวิร์ก Cast กำหนดให้เนื้อหาต้องเปิดใช้ CORS จึงจะเล่นได้
เหตุใดเนื้อหาจึงเล่นไม่สำเร็จ แต่ไม่มีข้อผิดพลาดปรากฏขึ้น
อุปกรณ์ที่คุณเล่นเนื้อหาอาจไม่รองรับรูปแบบตัวอย่างสื่อที่เฉพาะเจาะจง คุณยืนยันได้ง่ายๆ โดยเพิ่ม
EventLogger เป็น Listener ให้กับเพลเยอร์ และมองหาบรรทัด
ที่คล้ายกับบรรทัดต่อไปนี้ใน Logcat
[ ] Track:x, id=x, mimeType=mime/type, ... , supported=NO_UNSUPPORTED_TYPE
NO_UNSUPPORTED_TYPE หมายความว่าอุปกรณ์ไม่สามารถถอดรหัสรูปแบบตัวอย่างสื่อที่ระบุโดย mimeType ได้ ดูข้อมูลเกี่ยวกับรูปแบบตัวอย่างที่รองรับได้ในเอกสารประกอบเกี่ยวกับรูปแบบสื่อของ Android media formats หัวข้อฉันจะโหลดไลบรารีการถอดรหัสเพื่อใช้ในการเล่นได้อย่างไรก็อาจเป็นประโยชน์เช่นกัน
ฉันจะโหลดไลบรารีการถอดรหัสเพื่อใช้ในการเล่นได้อย่างไร
- ไลบรารีตัวถอดรหัสส่วนใหญ่มีขั้นตอนด้วยตนเองในการตรวจสอบและสร้างทรัพยากร Dependency ดังนั้นโปรดตรวจสอบว่าคุณได้ทำตามขั้นตอนใน README ของไลบรารีที่เกี่ยวข้องแล้ว ตัวอย่างเช่น สำหรับไลบรารี ExoPlayer FFmpeg คุณต้องทำตาม คำแนะนำใน libraries/decoder_ffmpeg/README.md ซึ่งรวมถึงการส่ง แฟล็กการกำหนดค่าเพื่อ เปิดใช้ตัวถอดรหัส สำหรับรูปแบบที่ต้องการเล่น
- สำหรับไลบรารีที่มีโค้ดแบบเนทีฟ โปรดตรวจสอบว่าคุณใช้ Android NDK เวอร์ชันที่ถูกต้องตามที่ระบุไว้ใน README และคอยดูข้อผิดพลาดที่ปรากฏขึ้นระหว่างการกำหนดค่าและการสร้าง คุณควรเห็นไฟล์
.soปรากฏในไดเรกทอรีย่อยlibsของเส้นทางไลบรารีสำหรับสถาปัตยกรรมที่รองรับแต่ละรายการหลังจากทำตามขั้นตอนใน README - หากต้องการลองเล่นโดยใช้ไลบรารีในแอปพลิเคชันเดโม โปรดดู การเปิดใช้ตัวถอดรหัสที่รวมไว้ ดูคำแนะนำในการใช้ไลบรารีจากแอปของคุณเองได้ใน README ของไลบรารี
- หากใช้
DefaultRenderersFactoryคุณควรเห็นบรรทัดบันทึกระดับข้อมูล เช่น "Loaded FfmpegAudioRenderer" ใน Logcat เมื่อตัวถอดรหัสโหลด หากไม่เห็นบรรทัดดังกล่าว โปรดตรวจสอบว่าแอปพลิเคชันมีการขึ้นต่อกันกับไลบรารีการถอดรหัส - หากเห็นบันทึกระดับคำเตือนจาก
LibraryLoaderใน Logcat แสดงว่าการโหลดคอมโพเนนต์เนทีฟของไลบรารีล้มเหลว หากเกิดกรณีนี้ขึ้น ให้ตรวจสอบว่าคุณได้ทำตามขั้นตอนใน README ของไลบรารีอย่างถูกต้องและไม่มีข้อผิดพลาดปรากฏขึ้นขณะทำตามคำแนะนำ
หากยังพบปัญหาในการใช้ไลบรารีการถอดรหัส โปรดตรวจสอบ เครื่องมือติดตามปัญหา Media3 เพื่อดูปัญหาล่าสุดที่เกี่ยวข้อง หากคุณต้องรายงานปัญหาใหม่และปัญหาดังกล่าวเกี่ยวข้องกับการสร้างส่วนเนทีฟของไลบรารี โปรดระบุเอาต์พุตบรรทัดคำสั่งทั้งหมดจากการทำตามคำแนะนำใน README เพื่อช่วยเราวินิจฉัยปัญหา
ฉันเล่นวิดีโอ YouTube ด้วย ExoPlayer ได้โดยตรงไหม
ไม่ได้ ExoPlayer เล่นวิดีโอจาก YouTube ไม่ได้ เช่น URL ในรูปแบบ https://www.youtube.com/watch?v=... คุณควรใช้ YouTube
iFrame Player API,
ซึ่งเป็นวิธีอย่างเป็นทางการในการเล่นวิดีโอ YouTube ใน Android
การเล่นวิดีโอติดขัด
อุปกรณ์อาจถอดรหัสเนื้อหาได้ไม่เร็วพอ เช่น หากบิตเรตหรือความละเอียดของเนื้อหาเกินความสามารถของอุปกรณ์ คุณอาจต้องใช้เนื้อหาที่มีคุณภาพต่ำลงเพื่อให้ได้ประสิทธิภาพที่ดีในอุปกรณ์ดังกล่าว
หากวิดีโอติดขัดในอุปกรณ์ที่ใช้ Android เวอร์ชันตั้งแต่ Android 6.0 (ระดับ API 23) ถึง Android 11 (ระดับ API 30) โดยเฉพาะอย่างยิ่งเมื่อเล่นเนื้อหาที่ได้รับการปกป้องด้วย DRM หรือเนื้อหาที่มีอัตราเฟรมสูง คุณสามารถลองเปิดใช้การจัดคิวบัฟเฟอร์แบบไม่พร้อมกัน
ข้อผิดพลาด Lint ของ API ที่ไม่เสถียร
Media3 รับประกันความเข้ากันได้แบบไบนารีสำหรับชุดย่อยของพื้นผิว API ส่วนที่
ไม่ รับประกันความเข้ากันได้แบบไบนารีจะมีเครื่องหมาย
@UnstableApi เพื่อให้เห็นความแตกต่างนี้อย่างชัดเจน การใช้สัญลักษณ์ API ที่ไม่เสถียรจะสร้างข้อผิดพลาด Lint เว้นแต่จะมีการใส่คำอธิบายประกอบด้วย @OptIn
คำอธิบายประกอบ @UnstableApi ไม่ได้บ่งบอกถึงคุณภาพหรือประสิทธิภาพของ API แต่บ่งบอกเพียงว่า API นั้น "ไม่ได้ถูกตรึงไว้"
คุณมี 2 ตัวเลือกในการจัดการข้อผิดพลาด Lint ของ API ที่ไม่เสถียร
- เปลี่ยนไปใช้ API ที่เสถียรซึ่งให้ผลลัพธ์เหมือนกัน
- ใช้ API ที่ไม่เสถียรต่อไปและใส่คำอธิบายประกอบการใช้งานด้วย
@OptInดังที่แสดงไว้ในภายหลัง
เพิ่มคำอธิบายประกอบ @OptIn
Android Studio ช่วยคุณเพิ่มคำอธิบายประกอบได้
นอกจากนี้ คุณยังใส่คำอธิบายประกอบไซต์การใช้งานที่เฉพาะเจาะจงด้วยตนเองได้ด้วย
Kotlin
import androidx.annotation.OptIn
import androidx.media3.common.util.UnstableApi
@OptIn(UnstableApi::class)
fun functionUsingUnstableApi() { ... }
Java
import androidx.annotation.OptIn;
import androidx.media3.common.util.UnstableApi;
@OptIn(markerClass = UnstableApi.class)
private void methodUsingUnstableApis() { ... }
คุณเลือกใช้แพ็กเกจทั้งหมดได้โดยเพิ่มไฟล์ package-info
Kotlin
// In your package-info.kt
@OptIn(UnstableApi::class)
package name.of.your.package
import androidx.annotation.OptIn
import androidx.media3.common.util.UnstableApi
Java
// In your package-info.java
@OptIn(markerClass = UnstableApi.class)
package name.of.your.package;
import androidx.annotation.OptIn;
import androidx.media3.common.util.UnstableApi;
คุณเลือกใช้โปรเจ็กต์ทั้งหมดได้โดยระงับข้อผิดพลาด Lint ที่เฉพาะเจาะจงในไฟล์
lint.xmlของโปรเจ็กต์:
<?xml version="1.0" encoding="utf-8"?>
<lint>
<issue id="UnsafeOptInUsageError">
<option name="opt-in" value="androidx.media3.common.util.UnstableApi" />
</issue>
</lint>
นอกจากนี้ยังมีคำอธิบายประกอบ kotlin.OptIn ซึ่งไม่ควรใช้ คุณต้องใช้คำอธิบายประกอบ androidx.annotation.OptIn