ExoPlayer รองรับทั้ง RTSP แบบสดและแบบออนดีมานด์ รูปแบบและประเภทเครือข่ายของตัวอย่างที่รองรับมีดังนี้
รูปแบบตัวอย่างที่รองรับ
- H264 (คำอธิบายสื่อ SDP ต้องมีข้อมูล SPS/PPS ในแอตทริบิวต์ fmtp สำหรับการจัดเตรียมโปรแกรมถอดรหัส)
- AAC (พร้อมสตรีมบิต ADTS)
- AC3
ประเภทเครือข่ายที่รองรับ
- RTP ผ่าน UDP แบบยูนิแคสต์ (ไม่รองรับมัลติแคสต์)
- RTSP แบบสลับช่อง, RTP ผ่าน RTSP โดยใช้ TCP
การใช้ MediaItem
หากต้องการเล่นสตรีม RTSP คุณต้องใช้โมดูล RTSP
Kotlin
implementation("androidx.media3:media3-exoplayer-rtsp:1.4.1")
Groovy
implementation "androidx.media3:media3-exoplayer-rtsp:1.4.1"
จากนั้นคุณจะสร้าง MediaItem
สำหรับ RTSP URI และส่งไปยังโปรแกรมเล่นได้
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-over-RTSP (การส่งแพ็กเก็ต RTP โดยใช้การเชื่อมต่อ TCP ที่เปิดไว้สำหรับ RTSP)
คุณปรับเวลาหมดอายุสำหรับการลองใช้ TCP อีกครั้งได้โดยเรียกใช้เมธอด
RtspMediaSource.Factory.setTimeoutMs()
ตัวอย่างเช่น หากตั้งค่าการหมดเวลาเป็น 4 วินาที โปรแกรมเล่นจะลองใช้ TCP อีกครั้งหลังจาก UDP ไม่มีการใช้งานเป็นเวลา 4 วินาที
การตั้งค่าระยะหมดเวลายังมีผลต่อตรรกะการตรวจหาการสิ้นสุดสตรีมด้วย กล่าวคือ ExoPlayer จะรายงานว่าการเล่นสิ้นสุดลงหากไม่ได้รับการตอบกลับภายในระยะเวลาที่กำหนดไว้ การตั้งค่านี้ต่ำเกินไปอาจส่งผลให้สัญญาณ "สิ้นสุดสตรีม" แสดงขึ้นก่อนเวลาอันควรเมื่อเครือข่ายอยู่ในสภาพที่ไม่เอื้ออำนวย
RTP/TCP เข้ากันได้ดีกว่าในการตั้งค่าเครือข่ายบางรายการ คุณสามารถกําหนดค่า
ExoPlayer ให้ใช้ RTP/TCP โดยค่าเริ่มต้นได้โดยใช้
RtspMediaSource.Factory.setForceUseRtpTcp()
การส่ง SocketFactory ที่กําหนดเอง
อินสแตนซ์ SocketFactory
ที่กําหนดเองจะมีประโยชน์เมื่อจําเป็นต้องมีการกําหนดเส้นทางที่เฉพาะเจาะจง (เช่น เมื่อการรับส่งข้อมูล RTSP ต้องผ่านอินเทอร์เฟซที่เฉพาะเจาะจง หรือซ็อกเก็ตต้องใช้ Flag การเชื่อมต่อเพิ่มเติม)
โดยค่าเริ่มต้น RtspMediaSource
จะใช้โรงงานซ็อกเก็ตมาตรฐานของ 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));