การแก้ปัญหา


การแก้ไขข้อผิดพลาด "ไม่อนุญาตการรับส่งข้อมูล HTTP แบบข้อความธรรมดา"

ข้อผิดพลาดนี้จะเกิดขึ้นหากแอปขอการเข้าชม HTTP แบบข้อความธรรมดา (Cleartext) (นั่นคือ http:// แทน https://) เมื่อการกำหนดค่าความปลอดภัยของเครือข่ายไม่อนุญาต หากแอปกำหนดเป้าหมายเป็น Android 9 (API ระดับ 28) ขึ้นไป การกำหนดค่าเริ่มต้นจะปิดใช้การรับส่งข้อมูล HTTP ที่เป็นข้อความธรรมดา

หากแอปต้องทำงานกับการเข้าชม HTTP แบบข้อความธรรมดา คุณจะต้องใช้ การกำหนดค่าความปลอดภัยของเครือข่ายที่อนุญาต ดูรายละเอียดได้ในเอกสารประกอบด้านความปลอดภัยของเครือข่าย ของ Android หากต้องการเปิดใช้การเข้าชม HTTP แบบข้อความธรรมดาทั้งหมด คุณเพียงแค่เพิ่ม android:usesCleartextTraffic="true" ลงในองค์ประกอบ application ของ AndroidManifest.xml ของแอป

แอปตัวอย่าง ExoPlayer ใช้การกำหนดค่าความปลอดภัยของเครือข่ายเริ่มต้น จึงไม่อนุญาตการเข้าชมแบบ HTTP ที่เป็นข้อความธรรมดา (Cleartext) คุณเปิดใช้ได้โดยทำตามวิธีการ ด้านบน

การแก้ไขข้อผิดพลาด "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 ประการดังนี้

  1. สำหรับการกรออย่างละเอียด รูปแบบคอนเทนเนอร์ควรมีการแมปเวลาต่อไบต์ที่แม่นยำ ในส่วนหัว การแมปนี้ช่วยให้เพลเยอร์แมป เวลาค้นหาที่ขอไปยังออฟเซ็ตไบต์ที่เกี่ยวข้อง และเริ่มขอ แยกวิเคราะห์และเล่นสื่อจากออฟเซ็ตนั้นได้ น่าเสียดายที่ส่วนหัวที่ใช้ได้สำหรับการระบุการแมปนี้ใน MP3 (เช่น ส่วนหัว XING) มักจะไม่แม่นยำ
  2. สำหรับรูปแบบคอนเทนเนอร์ที่ไม่ได้ให้การแมปเวลาต่อไบต์ที่แม่นยำ (หรือการแมปเวลาต่อไบต์ใดๆ เลย) คุณยังคงสามารถดำเนินการค้นหาที่แน่นอนได้หากคอนเทนเนอร์มีไทม์สแตมป์ตัวอย่างที่แน่นอนในสตรีม ใน กรณีนี้ ผู้เล่นสามารถแมปเวลาค้นหาไปยังการคาดเดาที่ดีที่สุดของออฟเซ็ตไบต์ที่เกี่ยวข้อง เริ่มขอสื่อจากออฟเซ็ตนั้น แยกวิเคราะห์การประทับเวลาตัวอย่างสัมบูรณ์แรก และทำการค้นหาแบบไบนารีที่มีคำแนะนำในสื่ออย่างมีประสิทธิภาพ จนกว่าจะพบตัวอย่างที่ถูกต้อง ขออภัย MP3 ไม่มี การประทับเวลาตัวอย่างที่แน่นอนในสตรีม จึงไม่สามารถใช้วิธีนี้ได้

ด้วยเหตุนี้ วิธีเดียวที่จะค้นหาตำแหน่งที่แน่นอนในไฟล์ MP3 แบบ VBR คือ การสแกนทั้งไฟล์และสร้างการแมปเวลาต่อไบต์ใน เพลเยอร์ด้วยตนเอง คุณเปิดใช้กลยุทธ์นี้ได้โดยใช้ FLAG_ENABLE_INDEX_SEEKING ซึ่งตั้งค่าใน DefaultExtractorsFactory ได้โดยใช้ setMp3ExtractorFlags โปรดทราบว่าฟีเจอร์นี้ไม่เหมาะกับไฟล์ MP3 ขนาดใหญ่ โดยเฉพาะอย่างยิ่งหากผู้ใช้พยายามกรอไปใกล้ๆ ตอนท้ายของสตรีมในเวลาไม่นาน หลังจากเริ่มเล่น ซึ่งทำให้เพลเยอร์ต้องรอจนกว่าจะดาวน์โหลด และจัดทำดัชนีสตรีมทั้งหมดก่อนจึงจะกรอได้ ใน ExoPlayer เรา ตัดสินใจที่จะเพิ่มประสิทธิภาพเพื่อความเร็วมากกว่าความแม่นยำในกรณีนี้ และ FLAG_ENABLE_INDEX_SEEKING จึงปิดใช้โดยค่าเริ่มต้น

หากคุณควบคุมสื่อที่เล่นอยู่ เราขอแนะนำให้ใช้รูปแบบคอนเทนเนอร์ที่เหมาะสมกว่า เช่น MP4 เราไม่พบกรณีการใช้งานใดๆ ที่ MP3 เป็นตัวเลือกรูปแบบสื่อที่ดีที่สุด

ทำไมการกรอวิดีโอของฉันจึงช้า

เมื่อเพลเยอร์ค้นหาตำแหน่งการเล่นใหม่ในวิดีโอ เพลเยอร์จะต้องทำ 2 อย่างต่อไปนี้

  1. โหลดข้อมูลที่สอดคล้องกับตำแหน่งการเล่นใหม่ลงในบัฟเฟอร์ (อาจไม่จำเป็นหากมีการบัฟเฟอร์ข้อมูลนี้อยู่แล้ว)
  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 รองรับการใช้รายการแก้ไขบางส่วน เช่น สามารถหน่วงเวลาหรือเล่นซ้ำกลุ่มตัวอย่าง โดยเริ่มจากตัวอย่างการซิงค์ แต่จะไม่ตัดตัวอย่างเสียงหรือ สื่อโฆษณาก่อนเล่นสำหรับการแก้ไขที่ไม่ได้เริ่มจากตัวอย่างการซิงค์

หากคุณเห็นว่าสื่อบางส่วนหายไปหรือซ้ำกันโดยไม่คาดคิด ให้ลองตั้งค่า Mp4Extractor.FLAG_WORKAROUND_IGNORE_EDIT_LISTS หรือ FragmentedMp4Extractor.FLAG_WORKAROUND_IGNORE_EDIT_LISTS ซึ่งจะทำให้ โปรแกรมแยกไม่สนใจรายการแก้ไขทั้งหมด โดยตั้งค่าใน DefaultExtractorsFactoryได้โดยใช้ setMp4ExtractorFlags หรือ setFragmentedMp4ExtractorFlags

ทำไมสตรีมบางรายการจึงล้มเหลวโดยมีรหัสการตอบกลับ 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 ทั้ง 2 รายการเป็น HTTPS จึงไม่ใช่การเปลี่ยนเส้นทางข้ามโปรโตคอล การเปลี่ยนเส้นทางที่ 2 คือจาก https://secondserver.example.net/test.mp3 ไปยัง http://thirdserver.example.org/test.mp3 ซึ่งจะเปลี่ยนเส้นทางจาก HTTPS ไปยัง HTTP จึงเป็นการเปลี่ยนเส้นทางข้ามโปรโตคอล ExoPlayer จะไม่ติดตามการเปลี่ยนเส้นทางนี้ในการกำหนดค่าเริ่มต้น ซึ่งหมายความว่าการเล่นจะล้มเหลว

หากจำเป็น คุณสามารถกำหนดค่า ExoPlayer ให้ติดตามการเปลี่ยนเส้นทางข้ามโปรโตคอล เมื่อสร้างอินสแตนซ์ DefaultHttpDataSource.Factory ที่ใช้ใน แอปพลิเคชัน ดูข้อมูลเกี่ยวกับการเลือกและการกำหนดค่าสแต็กเครือข่ายได้ที่นี่

เหตุใดสตรีมบางรายการจึงล้มเหลวโดยมีข้อผิดพลาด 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 สูงเมื่อ ใช้ setPlaybackParameters API เนื่องจากบิลด์สำหรับแก้ไขข้อบกพร่องที่ทำงานใน Android เวอร์ชันเหล่านี้จะปิดใช้การเพิ่มประสิทธิภาพ ที่สำคัญต่อ API นี้

โปรดทราบว่าปัญหานี้ส่งผลต่อบิลด์การแก้ไขข้อบกพร่องเท่านั้น แต่ไม่มีผลต่อบิลด์ที่เผยแพร่ซึ่งจะเปิดใช้การเพิ่มประสิทธิภาพเสมอ ดังนั้น รุ่นที่คุณให้บริการแก่ผู้ใช้ปลายทางจึงไม่ควรได้รับผลกระทบจากปัญหานี้

ข้อผิดพลาด "เข้าถึงเพลเยอร์ในเธรดที่ไม่ถูกต้อง" หมายความว่าอย่างไร

ดูหมายเหตุเกี่ยวกับการแยกเธรดในหน้าเริ่มต้นใช้งาน

ฉันจะแก้ไข "บรรทัดสถานะที่ไม่คาดคิด: ICY 200 OK" ได้อย่างไร

ปัญหานี้อาจเกิดขึ้นได้หากการตอบกลับของเซิร์ฟเวอร์มีบรรทัดสถานะ ICY แทนที่จะเป็นบรรทัดที่สอดคล้องกับ HTTP บรรทัดสถานะ ICY เลิกใช้งานแล้วและไม่ควรใช้ ดังนั้นหากคุณควบคุมเซิร์ฟเวอร์ คุณควรอัปเดตเซิร์ฟเวอร์เพื่อให้การตอบกลับเป็นไปตาม HTTP หากทำไม่ได้ การใช้ไลบรารี ExoPlayer OkHttp จะช่วยแก้ปัญหาได้ เนื่องจากสามารถจัดการบรรทัดสถานะ ICY ได้อย่างถูกต้อง

ฉันจะค้นหาว่าสตรีมที่กำลังเล่นเป็นไลฟ์สดหรือไม่ได้อย่างไร

คุณสามารถค้นหาเมธอด isCurrentWindowLive ของเพลเยอร์ได้ นอกจากนี้ คุณยังตรวจสอบ isCurrentWindowDynamic เพื่อดูว่าช่วงเวลาเป็นแบบไดนามิกหรือไม่ (นั่นคือยังคงอัปเดตอยู่เรื่อยๆ)

ฉันจะเล่นเสียงต่อไปได้อย่างไรเมื่อแอปทำงานอยู่เบื้องหลัง

ทำตามขั้นตอนต่อไปนี้เพื่อให้เล่นเสียงต่อไปได้เมื่อแอปทำงานในเบื้องหลัง

  1. คุณต้องมีบริการที่ทำงานอยู่เบื้องหน้าที่ทำงานอยู่ ซึ่งจะช่วยป้องกันไม่ให้ระบบ ปิดกระบวนการของคุณเพื่อเพิ่มพื้นที่ว่างในทรัพยากร
  2. คุณต้องมี WifiLock และ WakeLock ซึ่งจะช่วยให้ ระบบเปิดสัญญาณวิทยุ Wi-Fi และ 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 ฉันจะรับไลบรารีการถอดรหัสเพื่อโหลดและใช้สำหรับการเล่นได้อย่างไรอาจมีประโยชน์เช่นกัน

ฉันจะรับไลบรารีการถอดรหัสเพื่อโหลดและใช้สำหรับการเล่นได้อย่างไร

  • ไลบรารีตัวถอดรหัสส่วนใหญ่มีขั้นตอนด้วยตนเองในการตรวจสอบและสร้างการอ้างอิง ดังนั้น โปรดตรวจสอบว่าคุณได้ทำตามขั้นตอนใน README สำหรับไลบรารีที่เกี่ยวข้องแล้ว เช่น สำหรับไลบรารี FFmpeg ของ ExoPlayer คุณต้องทำตาม วิธีการใน libraries/decoder_ffmpeg/README.md ซึ่งรวมถึงการส่งแฟล็กการกำหนดค่าเพื่อเปิดใช้ตัวถอดรหัสสำหรับรูปแบบใดก็ตามที่คุณต้องการเล่น
  • สำหรับไลบรารีที่มีโค้ดเนทีฟ โปรดตรวจสอบว่าคุณใช้ Android NDK เวอร์ชันที่ถูกต้องตามที่ระบุไว้ใน README และคอยดูข้อผิดพลาดที่ปรากฏขึ้นระหว่างการกำหนดค่าและการสร้าง คุณควรเห็นไฟล์ .so ปรากฏในไดเรกทอรีย่อย libs ของเส้นทางไลบรารีสำหรับสถาปัตยกรรมที่รองรับแต่ละรายการ หลังจากทำตามขั้นตอนใน README
  • หากต้องการลองเล่นโดยใช้ไลบรารีในแอปพลิเคชันเดโม โปรดดูหัวข้อ การเปิดใช้ตัวถอดรหัสที่มาพร้อมกัน ดูคำแนะนำในการใช้ไลบรารีจากแอปของคุณเองได้ใน README ของไลบรารี
  • หากใช้ DefaultRenderersFactory คุณควรเห็นบรรทัดบันทึกระดับข้อมูล เช่น "โหลด 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 หรือมีอัตราเฟรมสูง คุณสามารถลองเปิดใช้การจัดคิวบัฟเฟอร์แบบไม่พร้อมกัน

ข้อผิดพลาดของ Linters API ที่ไม่เสถียร

Media3 รับประกันความเข้ากันได้ของไบนารีสำหรับชุดย่อยของพื้นผิว API ส่วนที่ไม่รับประกันความเข้ากันได้ของไบนารีจะมีเครื่องหมาย @UnstableApi เพื่ออธิบายความแตกต่างนี้ให้ชัดเจน การใช้สัญลักษณ์ API ที่ไม่เสถียรจะทำให้เกิดข้อผิดพลาดของ Lint เว้นแต่จะมีการใส่คำอธิบายประกอบด้วย @OptIn

คำอธิบายประกอบ @UnstableApi ไม่ได้บ่งบอกถึงคุณภาพหรือประสิทธิภาพของ API แต่เป็นเพียงข้อเท็จจริงที่ว่า API นั้นไม่ได้ "หยุดการพัฒนา"

คุณมี 2 ตัวเลือกในการจัดการข้อผิดพลาดของ Lint API ที่ไม่เสถียร ดังนี้

  • เปลี่ยนไปใช้ API ที่เสถียรซึ่งให้ผลลัพธ์เดียวกัน
  • ใช้ API ที่ไม่เสถียรต่อไปและใส่คำอธิบายประกอบการใช้งานด้วย @OptIn ตามที่แสดงในภายหลัง
เพิ่มคำอธิบายประกอบ@OptIn

Android Studio ช่วยคุณเพิ่มคำอธิบายประกอบได้ดังนี้

ภาพหน้าจอ: วิธีเพิ่มคำอธิบายประกอบการเลือกใช้
รูปที่ 2: การเพิ่มคำอธิบายประกอบ @androidx.annotations.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.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