ExoPlayer รองรับ RTSP ทั้งแบบสดและแบบออนดีมานด์ รูปแบบตัวอย่างและ ประเภทเครือข่ายที่รองรับแสดงอยู่ด้านล่าง
รูปแบบตัวอย่างที่รองรับ
- H264 (คำอธิบายสื่อ SDP ต้องมีข้อมูล SPS/PPS ในแอตทริบิวต์ fmtp สำหรับการเริ่มต้นตัวถอดรหัส)
- AAC (ที่มีบิตสตรีม ADTS)
- AC3
ประเภทเครือข่ายที่รองรับ
- RTP ผ่าน UDP Unicast (ไม่รองรับ Multicast)
- RTSP แบบแทรก, RTP ผ่าน RTSP โดยใช้ TCP
การใช้ MediaItem
หากต้องการเล่นสตรีม RTSP คุณต้องใช้โมดูล RTSP
Kotlin
implementation("androidx.media3:media3-exoplayer-rtsp:1.7.1")
Groovy
implementation "androidx.media3:media3-exoplayer-rtsp:1.7.1"
จากนั้นคุณจะสร้าง MediaItem
สำหรับ URI ของ RTSP และส่งไปยังเพลเยอร์ได้
Kotlin
// Create a player instance. val player = ExoPlayer.Builder(context).build() // Set the media item to be played. player.setMediaItem(MediaItem.fromUri(rtspUri)) // Prepare the player. player.prepare()
Java
// Create a player instance. ExoPlayer player = new ExoPlayer.Builder(context).build(); // Set the media item to be played. player.setMediaItem(MediaItem.fromUri(rtspUri)); // Prepare the player. player.prepare();
การตรวจสอบสิทธิ์
ExoPlayer รองรับการเล่นด้วยการตรวจสอบสิทธิ์ RTSP BASIC และ DIGEST หากต้องการเล่นเนื้อหา RTSP ที่ได้รับการปกป้อง คุณต้องกำหนดค่า URI ของ MediaItem
ด้วยข้อมูลการตรวจสอบสิทธิ์ โดยเฉพาะอย่างยิ่ง URI ควรมีรูปแบบเป็น rtsp://<username>:<password>@<host address>
การใช้ RtspMediaSource
หากต้องการตัวเลือกการปรับแต่งเพิ่มเติม คุณสามารถสร้าง RtspMediaSource
และส่งไปยังเพลเยอร์โดยตรงแทน MediaItem
Kotlin
// Create an RTSP media source pointing to an RTSP uri. val mediaSource: MediaSource = RtspMediaSource.Factory().createMediaSource(MediaItem.fromUri(rtspUri)) // Create a player instance. val player = ExoPlayer.Builder(context).build() // Set the media source to be played. player.setMediaSource(mediaSource) // Prepare the player. player.prepare()
Java
// Create an RTSP media source pointing to an RTSP uri. MediaSource mediaSource = new RtspMediaSource.Factory().createMediaSource(MediaItem.fromUri(rtspUri)); // Create a player instance. ExoPlayer player = new ExoPlayer.Builder(context).build(); // Set the media source to be played. player.setMediaSource(mediaSource); // Prepare the player. player.prepare();
การใช้ RTSP หลัง NAT (รองรับ RTP/TCP)
ExoPlayer ใช้ UDP เป็นโปรโตคอลเริ่มต้นสำหรับการรับส่ง RTP
เมื่อสตรีม RTSP ที่อยู่หลังเลเยอร์ NAT ระบบอาจส่งต่อแพ็กเก็ต RTP/UDP ขาเข้าไปยังอุปกรณ์ไม่ได้ กรณีนี้จะเกิดขึ้นหาก NAT ไม่มี การแมปพอร์ต UDP ที่จำเป็น หาก ExoPlayer ตรวจพบว่าไม่มีแพ็กเก็ต RTP ขาเข้ามาระยะหนึ่งแล้วและยังไม่ได้เริ่มเล่น ExoPlayer จะยกเลิกเซสชันการเล่น RTSP ปัจจุบัน และลองเล่นอีกครั้งโดยใช้ RTP ผ่าน RTSP (ส่งแพ็กเก็ต RTP โดยใช้การเชื่อมต่อ TCP ที่เปิดสำหรับ RTSP)
คุณปรับแต่งระยะหมดเวลาสำหรับการลองใหม่ด้วย TCP ได้โดยเรียกใช้เมธอด
RtspMediaSource.Factory.setTimeoutMs()
ตัวอย่างเช่น หากตั้งค่าการหมดเวลาเป็น 4 วินาที เพลเยอร์จะลองอีกครั้งด้วย TCP หลังจากที่ไม่มีการใช้งาน UDP เป็นเวลา 4 วินาที
การตั้งค่าระยะหมดเวลายังส่งผลต่อตรรกะการตรวจหาจุดสิ้นสุดของสตรีมด้วย กล่าวคือ ExoPlayer จะรายงานว่าการเล่นสิ้นสุดลงหากไม่ได้รับอะไรเลยในช่วงระยะเวลาของระยะหมดเวลาที่ตั้งไว้ การตั้งค่านี้ให้มีค่าน้อยเกินไปอาจทำให้เกิดสัญญาณสิ้นสุดสตรีมก่อนเวลาอันควรในกรณีที่เครือข่ายไม่ดี
RTP/TCP มีความเข้ากันได้ดีกว่าภายใต้การตั้งค่าเครือข่ายบางอย่าง คุณสามารถกำหนดค่า
ExoPlayer ให้ใช้ RTP/TCP เป็นค่าเริ่มต้นได้โดยใช้
RtspMediaSource.Factory.setForceUseRtpTcp()
การส่ง SocketFactory ที่กำหนดเอง
SocketFactory
อินสแตนซ์ที่กำหนดเองจะมีประโยชน์เมื่อต้องมีการกำหนดเส้นทางที่เฉพาะเจาะจง (เช่น เมื่อการรับส่งข้อมูล RTSP ต้องผ่านอินเทอร์เฟซที่เฉพาะเจาะจง หรือซ็อกเก็ตต้องมีแฟล็กการเชื่อมต่อเพิ่มเติม)
โดยค่าเริ่มต้น RtspMediaSource
จะใช้ Socket Factory มาตรฐานของ Java
(SocketFactory.getDefault()
) เพื่อสร้างการเชื่อมต่อไปยังปลายทางระยะไกล
คุณลบล้างลักษณะการทำงานนี้ได้โดยใช้
RtspMediaSource.Factory.setSocketFactory()
Kotlin
// Create an RTSP media source pointing to an RTSP uri and override the socket // factory. val mediaSource: MediaSource = RtspMediaSource.Factory() .setSocketFactory(...) .createMediaSource(MediaItem.fromUri(rtspUri))
Java
// Create an RTSP media source pointing to an RTSP uri and override the socket // factory. MediaSource mediaSource = new RtspMediaSource.Factory() .setSocketFactory(...) .createMediaSource(MediaItem.fromUri(rtspUri));