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.10.0")
ดึงดูด
implementation "androidx.media3:media3-exoplayer-rtsp:1.10.0"
จากนั้นคุณจะสร้าง 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 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(socketFactory) .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(socketFactory) .createMediaSource(MediaItem.fromUri(rtspUri));