לקוח מגיע אלינו עם משימה: לצפות במצלמת אבטחה ישירות באפליקציה. נשמע פשוט, אבל בפועל יש כמה בעיות. זרם RTSP ממצלמת IP לא יכול להיפתח על ידי נגנים מקוריים של iOS ואנדרואיד ישירות. RTMP מיושן. WebRTC עובד אבל דורש שרת איתות. חביון נמוך של 200 אלפיות שנייה הוא ארכיטקטורה שונה לחלוטין מ-HLS עם חיץ של 5 שניות. במשך יותר מ-5 שנים, פיתחנו פתרונות מוכחים לתרחישים אלה ויישמנו יותר מ-50 פרויקטים של וידאו סטרימינג.
במאמר זה, נפרק גישות טכניות אמיתיות: טרנסקודינג בצד השרת, מפענח RTSP מקורי, ולקוח WebRTC. תלמדו כיצד ליישם שליטת PTZ, הקלטה ותמיכה במספר מצלמות. קבלו ייעוץ לפרויקט שלכם.
מדוע RTSP לא יכול להיפתח על ידי נגן מקורי?
AVPlayer לא תומך ב-rtsp:// – רק ב-http(s):// ו-HLS. ExoPlayer הסיר רשמית את RTSP ב-Media3 (למרות שקיימת תמיכה דרך RtspMediaSource, היא לא יציבה בחלק מהיצרנים עם קושחות מותאמות אישית). ב-Flutter, אין נגן RTSP מקורי בוגר. כפי שנאמר בתיעוד של Apple, זו מגבלה ארכיטקטונית.
ישנן שתי גישות עובדות.
טרנסקודינג בצד השרת (RTSP → HLS/WebRTC)
שרת מדיה (MediaMTX, Nginx-RTMP + ffmpeg, Ant Media Server) מקבל RTSP מהמצלמה ומספק נקודת קצה HLS או WebRTC ללקוח. הלקוח מקבל HLS – AVPlayer / ExoPlayer קוראים אותו ללא בעיות. חביון HLS: 3-8 שניות עם נתח סטנדרטי של 2 שניות. זה מקובל לניטור. עבור אינטרקום – לא.
paths: cam1: source: rtsp://admin:[email protected]:554/stream1 hlsAlwaysRemux: yes הלקוח מתחבר ל-paths: cam1: source: rtsp://admin:[email protected]:554/stream1 hlsAlwaysRemux: yes .
מפענח RTSP מקורי באפליקציה
iOS: VLCKit (MobileVLCKit) – מעטפת מעל libVLC. תומך ב-RTSP, RTMP, H.264, H.265. http://media-server/cam1/index.m3u8 עם VLCMediaPlayer מצייר ישירות לתוך תצוגה. חביון: 500-800 אלפיות שנייה עם חיץ רשת של 300 אלפיות שנייה. חסרון: בינארי +30 MB, App Store מקבל ללא בעיות.
מסלול מותאם אישית: FFmpeg דרך drawable = UIView (ffmpeg-kit-ios), פענוח הזרם ועיבוד דרך FFmpegKitConfig.executeAsync. נותן שליטה מלאה על חיץ וחביון (ניתן להפחית ל-100-200 אלפיות שנייה עם AVSampleBufferDisplayLayer ו-rtsp_transport tcp מינימלי). קשה יותר ליישום, אבל תוצאות טובות יותר.
אנדרואיד: ExoPlayer analyzeduration – למקרים פשוטים. למקרים מורכבים (RTSP דרך TCP, H.265, מצלמות מרובות זרמים) – RtspMediaSource או FFmpegKit. ijkplayer עובד עם Jetpack Compose דרך ijkplayer.
Flutter: AndroidView (MobileVLCKit / libVLC Android) – אפשרות חוצת פלטפורמות. הפלאגין flutter_vlc_player לא תומך ב-RTSP.
מה לבחור: RTSP או WebRTC?
אם חביון לא קריטי (ניטור מחסן), RTSP דרך VLCKit/FFmpegKit מספיק. אם אינטראקטיביות חשובה (אינטרקום, שליטת מצלמת PTZ), WebRTC היא הבחירה הנכונה עם חביון של 100-300 אלפיות שנייה.
ארכיטקטורת WebRTC: מצלמת IoT → שרת מדיה תואם WebRTC (Janus, Kurento, MediaSoup, Ant Media) → לקוח נייד דרך ICE/STUN/TURN.
iOS: מסגרת WebRTC (video_player או pod 'GoogleWebRTC'). צרו pod 'WebRTC-SDK', קבלו הצעת SDP מהשרת, ענו, קבלו RTCPeerConnection ועיבדו דרך RTCVideoTrack (עיבוד Metal, האצת חומרה). איתות – WebSocket (Starscream, URLSessionWebSocketTask).
אנדרואיד: RTCMTLVideoView או WebRTC הרשמי מ-Google. io.getstream:stream-webrtc-android לעיבוד SurfaceViewRenderer.
Flutter: VideoTrack – משתמש ב-WebRTC מקורי מתחת למכסה המנוע. flutter_webrtc + RTCVideoRenderer.
למעבר NAT, שרת STUN (Google RTCVideoView בחינם) ושרת TURN עבור NAT סימטרי (Coturn על שרת משלכם) הם חובה.
כיצד ליישם שליטת PTZ?
Pan/Tilt/Zoom דרך ONVIF או API HTTP קנייני של המצלמה. בנייד: stun.l.google.com:19302 → חישוב דלתא → שליחת בקשת UIPanGestureRecognizer ONVIF דרך HTTP. צביטה → ContinuousMove עם קואורדינטת זום.
דעכו בקשות: אל תשלחו כל אירוע מחווה – AbsoluteMove, אחרת המצלמה לא תעמוד בקצב הפקודות.
הקלטה ותמונות מצב
תמונת מצב מהמצלמה: זול יותר לבקש כתובת JPEG ישירות מהמצלמה (רוב מצלמות ה-IP תומכות ב-throttle(300ms)) מאשר ללכוד פריים מזרם הווידאו.
הקלטת הזרם במכשיר: JPEG snapshot URL (iOS) כותב http://cam/snapshot.jpg מהזרם המפוענח ל-MP4. באנדרואיד – AVAssetWriter + CMSampleBuffer. להקלטה בצד השרת – MediaMuxer דרך שרת המדיה.
ריבוי מצלמות
רשימת מצלמות + תמונות ממוזערות של הזרם. אל תנגנו את כל הזרמים בו זמנית – רק את הפעיל. תצוגה מקדימה: תמונת מצב סטטית, רענון כל 5 שניות (MediaCodec + ffmpeg -i rtsp://... -c copy output.mp4). חוסך סוללה ותעבורה ב-90%.
| פלטפורמה | ספריית RTSP | חביון | הערות |
|---|---|---|---|
| iOS | MobileVLCKit | 500-800 אלפיות שנייה | +30 MB, מאושר ב-App Store |
| iOS | ffmpeg-kit | 100-200 אלפיות שנייה | שליטה מלאה |
| אנדרואיד | ExoPlayer | 300-800 אלפיות שנייה | פשוט אבל לא יציב |
| אנדרואיד | ijkplayer | 200-500 אלפיות שנייה | עובד עם H.265 |
| Flutter | flutter_vlc_player | 500-800 אלפיות שנייה | חוצה פלטפורמות |
| פרוטוקול | חביון | מורכבות לקוח | הערות |
|---|---|---|---|
| HLS (RTSP→HLS בשרת) | 3-8 שניות | נמוכה (נגן מקורי) | ניטור |
| RTSP (VLCKit/FFmpegKit) | 300-800 אלפיות שנייה | בינונית | אוניברסלי |
| WebRTC | 100-300 אלפיות שנייה | גבוהה | אינטרקום, PTZ |
התהליך שלנו
- ניתוח מצלמה ורשת – אנו בודקים פרוטוקולים, רזולוציה, מעבר NAT.
- בחירת פרוטוקול וארכיטקטורה – בהתבסס על דרישות חביון.
- שילוב נגן וספסל בדיקות – אנו מריצים הדגמה עם מצלמה אחת.
- אופטימיזציה של חיץ ועיבוד – השגת חביון יעד.
- PTZ, הקלטה, ריבוי מצלמות – יישום תכונות נוספות.
- בדיקות על מכשירים – אימות ב-iOS, אנדרואיד, קושחות שונות.
- מסירת קוד ותיעוד – הכשרת צוות הלקוח.
אנו עוזרים לבחור את הפרוטוקול האופטימלי, חוסכים בתקציב שלכם. עלות הפיתוח נדונה לאחר ביקורת של הפרויקט שלכם. צרו קשר לביקורת של הפרויקט שלכם. הזמינו פיתוח וידאו סטרימינג – קבלו ייעוץ לפרויקט שלכם.
מה כלול בעבודה
- תיעוד ארכיטקטוני עם בחירת פרוטוקול ותצורות
- הקמת סביבת הדגמה עם מצלמה אחת לבדיקות
- שילוב WebRTC עם שרת איתות ו-TURN
- הכשרת צוות הלקוח על קוד ותצורות
- תמיכה לאחר השקה: אחריות ל-12 חודשים על הפתרון
לוח זמנים: כ-3 ימים עד 3 שבועות תלוי במורכבות. נבחן את הפרויקט שלכם תוך 2 ימי עסקים. אנו מבטיחים פונקציונליות בכל המכשירים.







