RTSP

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

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

  • ‫H264 (תיאור המדיה ב-SDP חייב לכלול נתוני SPS/PPS במאפיין fmtp לצורך אתחול המפענח).
  • ‫AAC (עם ADTS bitstream).
  • AC3.

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

  • ‫RTP over UDP unicast (אין תמיכה ב-multicast).
  • ‫RTSP משולב, RTP over RTSP באמצעות TCP.

שימוש ב-MediaItem

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

Kotlin

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

מגניב

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, יכול להיות ש-NAT לא יוכל להעביר את חבילות ה-RTP/UDP הנכנסות למכשיר. השגיאה הזו מתרחשת אם ל-NAT אין מיפוי של יציאות UDP נדרשות. אם ExoPlayer מזהה שלא התקבלו חבילות RTP במשך זמן מה וההפעלה עדיין לא התחילה, הוא מנתק את סשן ההפעלה הנוכחי של RTSP ומנסה להפעיל את התוכן באמצעות RTP-over-RTSP (שליחת חבילות RTP באמצעות חיבור ה-TCP שנפתח עבור RTSP).

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

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

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

העברת SocketFactory בהתאמה אישית

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

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