ExoPlayer תומך ב-RTSP בשידור חי ועל פי דרישה. בהמשך מפורטים הפורמטים של הדגימות וסוגי הרשתות שנתמכים.
פורמטים נתמכים לדוגמה
- H264 (תיאור המדיה של SDP חייב לכלול נתוני SPS/PPS במאפיין fmtp לצורך אתחול המפענח).
- AAC (עם זרם נתונים של ADTS).
- AC3.
סוגי הרשתות הנתמכות
- RTP over UDP unicast (אין תמיכה ב-multicast).
- RTSP משולב, RTP על גבי RTSP באמצעות TCP.
שימוש ב-MediaItem
כדי להפעיל שידור RTSP, צריך להסתמך על מודול RTSP.
Kotlin
implementation("androidx.media3:media3-exoplayer-rtsp:1.11.1")
מגניב
implementation "androidx.media3:media3-exoplayer-rtsp:1.11.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 במשך זמן מה וההפעלה עדיין לא התחילה, ExoPlayer מנתק את סשן ההפעלה הנוכחי של RTSP ומנסה שוב להפעיל באמצעות RTP-over-RTSP (העברת חבילות RTP באמצעות חיבור ה-TCP שנפתח עבור RTSP).
כדי להתאים אישית את הזמן הקצוב לתפוגה של ניסיונות חוזרים באמצעות TCP, אפשר להפעיל את ה-method RtspMediaSource.Factory.setTimeoutMs(). לדוגמה, אם הזמן הקצוב לתפוגה מוגדר ל-4 שניות, הנגן ינסה שוב עם TCP אחרי 4 שניות של חוסר פעילות ב-UDP.
הגדרת הזמן הקצוב לתפוגה משפיעה גם על הלוגיקה של זיהוי סוף הסטרימינג. כלומר, 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));