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.4.1")
Groovy
implementation "androidx.media3:media3-exoplayer-rtsp:1.4.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()
. לדוגמה, אם מגדירים את זמן הקצוב לתפוגה לארבע שניות, הנגן ינסה שוב באמצעות TCP אחרי ארבע שניות של חוסר פעילות ב-UDP.
הגדרת הזמן הקצוב לתפוגה משפיעה גם על הלוגיקה של זיהוי סיום הסטרימינג. כלומר, ExoPlayer ידווח שההפעלה הסתיימה אם לא יתקבל שום דבר במשך הזמן של הזמן הקצוב לתפוגה. הגדרת ערך קטן מדי עלולה להוביל לשליחת אות סיום שידור מוקדם בתנאים של רשת חלשה.
RTP/TCP מציע תאימות טובה יותר בהגדרות רשת מסוימות. אפשר להגדיר את ExoPlayer להשתמש ב-RTP/TCP כברירת מחדל באמצעות RtspMediaSource.Factory.setForceUseRtpTcp()
.
העברה של SocketFactory בהתאמה אישית
מכונות SocketFactory
בהתאמה אישית יכולות להיות שימושיות כשנדרש ניתוב ספציפי (לדוגמה, כשתנועת RTSP צריכה לעבור ממשק ספציפי, או כשהשקע צריך דגלים נוספים של קישוריות).
כברירת מחדל, 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));