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));