RTSP

ExoPlayer תומך ב-RTSP בשידור חי וגם על פי דרישה. פורמטים נתמכים לדוגמה ו סוגי הרשתות מפורטים למטה.

פורמטים נתמכים לדוגמה

  • H264 (תיאור המדיה של SDP חייב לכלול נתוני SPS/PPS ב-FMtp לאתחול המפענח).
  • AAC (עם ADTS Bitstream).
  • AC3.

סוגי רשתות נתמכים

  • RTP בחיבור UDP unicast (אין תמיכה בריבוי שידורים).
  • RTSP משולב, RTP ב-RTSP באמצעות TCP.

שימוש ב-MediaItem

כדי להפעיל זרם RTSP, צריך להסתמך על מודול ה-RTSP.

Kotlin

implementation("androidx.media3:media3-exoplayer-rtsp:1.4.0")

מגניב

implementation "androidx.media3:media3-exoplayer-rtsp:1.4.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-over-RTSP (העברת מנות RTP באמצעות חיבור TCP שנפתח עבור RTSP).

אפשר להתאים אישית את הזמן הקצוב לתפוגה של ניסיון חוזר עם TCP על ידי קריאה ל-method RtspMediaSource.Factory.setTimeoutMs() לדוגמה, אם הזמן הקצוב לתפוגה מוגדר ל- ארבע שניות, הנגן ינסה שוב עם TCP אחרי ארבע שניות של UDP חוסר פעילות.

הגדרת הזמן הקצוב לתפוגה משפיעה גם על הלוגיקה של זיהוי סוף השידור. כלומר, ExoPlayer ידווח שההפעלה הסתיימה אם לא התקבל שום דבר עבור משך הזמן הקצוב לתפוגה שהוגדר. אם מגדירים ערך קטן מדי, זה עלול לגרום אות סוף סטרימינג בתנאי רשת גרועים.

פרוטוקול RTP/TCP מאפשר תאימות טובה יותר בחלק מהגדרות הרשת. אפשר להגדיר ExoPlayer ישתמש ב-RTP/TCP כברירת מחדל עם RtspMediaSource.Factory.setForceUseRtpTcp()

העברת Socket מפעל בהתאמה אישית

מכונות SocketFactory בהתאמה אישית יכולות להיות שימושיות כאשר ניתוב מסוים נדרש (לדוגמה, כשתנועת RTSP צריכה לעבור ממשק ספציפי, או ב-socket נדרשים סימוני קישוריות נוספים).

כברירת מחדל, 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));