הטמעת מצב תמונה-בתוך-תמונה עבור אפליקציות iOS

הווידאו עובר לרקע, הצליל נעלם, או שחלון ה-Picture-in-Picture לא מופיע — מצב מוכר? אנחנו מיישמים מצב PiP עבור אפליקציות iOS, ומגדירים את ההפעלה באמצעות AVKit ו-AVPictureInPictureController. הצוות שלנו מטפל בכל המחזור, מהאודיט ועד היישום, ומבטיח פעילות יציבה ותמיכה מתמשכת.

פיתוח ותמיכה בכל סוגי היישומים הניידים:

יישומים ניידים למידע ובידור
אפליקציות חדשות, משחקים, מדריכים, קטלוגים מקוונים, אפליקציות מזג אוויר, אפליקציות כושר ובריאות, אפליקציות נסיעות, אפליקציות חינוכיות, רשתות חברתיות ומסנג'רים, חידונים, בלוגים ופודקאסטים, פורומים, אגרגטורים
יישומים ניידים למסחר אלקטרוני
חנויות מקוונות, אפליקציות B2B, מרקטפלייסים, בורסות מקוונות, שירותי קאשבק, בורסות, פלטפורמות דרופשיפינג, תוכניות נאמנות, משלוחי מזון ומוצרים, מערכות תשלום.
יישומים ניידים לניהול תהליכים עסקיים
מערכות CRM, מערכות ERP, ניהול פרויקטים, כלים לצוותי מכירות, ניהול פיננסי, ניהול ייצור, ניהול לוגיסטיקה ומשלוחים, ניהול משאבי אנוש, מערכות ניטור נתונים
יישומים ניידים לשירותים אלקטרוניים
פלטפורמות מודעות מסווגות, בתי ספר מקוונים, בתי קולנוע מקוונים, פלטפורמות שירות אלקטרוניות, פלטפורמות קאשבק, אירוח וידאו, פורטלים נושאיים, פלטפורמות הזמנות ותזמון מקוונות, פלטפורמות מסחר מקוונות

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

השירותים שאנו מציעים
מציג 1 מתוך 1כל 1734 השירותים
הטמעת מצב תמונה-בתוך-תמונה עבור אפליקציות iOS
בינוני
~2-3 ימים

הכישורים שלנו:

שאלות נפוצות

העבודות האחרונות

  • פיתוח אפליקציית מובייל עבור FEEDME
    פיתוח אפליקציית מובייל עבור FEEDME
    971
  • פיתוח אפליקציית מובייל עבור XOOMER
    פיתוח אפליקציית מובייל עבור XOOMER
    869
  • פיתוח אפליקציית מובייל עבור RHL
    פיתוח אפליקציית מובייל עבור RHL
    1289
  • פיתוח אפליקציית מובייל עבור ZIPPY
    פיתוח אפליקציית מובייל עבור ZIPPY
    1143
  • פיתוח אפליקציית מובייל עבור Affhome
    פיתוח אפליקציית מובייל עבור Affhome
    1076
  • פיתוח אפליקציית מובייל עבור חברת FLAVORS
    פיתוח אפליקציית מובייל עבור חברת FLAVORS
    677

הטמעת מצב תמונה-בתוך-תמונה עבור אפליקציות iOS

מצב תמונה-בתוך-תמונה (PiP) ב-iOS לא מופעל מעצמו—האפליקציה שלך חייבת לתמוך בו במפורש באמצעות AVKit או ממשק ה-API של AVPictureInPictureController. ב-90% מהפרויקטים שאנחנו רואים, הבעיה זהה: הווידאו עובר לרקע אבל האודיו נופל, או שחלון ה-PiP אף פעם לא מופיע. ניפוי באגים סטנדרטי לוקח עד 3 ימים, והגדרה נכונה של AVAudioSession מקצרת את זה ב-30%. המהנדסים המוסמכים שלנו עזרו לעשרות צוותים לנווט במכשולים האלה—הנה איך להימנע מלחזור על הטעויות שלהם. נסקור שלוש גישות, סיבוכים נפוצים, ומקרה אמיתי שבו אינטגרציה חכמה חסכה $8,000–$10,000 (35–40%) מהתקציב. אינטגרציית PiP בסיסית מתחילה ב-$1,500, בעוד שפתרונות מותאמים אישית נעים בין $3,000 ל-$5,000.

מהי הדרך המהירה ביותר להפעיל PiP?

יישום בסיסי עם AVPlayerViewController

המסלול המהיר ביותר הוא AVPlayerViewController. PiP מופעל עם הגדרה אחת: הגדר את allowsPictureInPicturePlayback = true, Configure את AVAudioSession—וכפתור ה-PiP מופיע אוטומטית. הנה קוד מינימלי—כ-20 שורות:

import AVKit
class VideoViewController: UIViewController {
    private var player: AVPlayer!
    private var playerViewController: AVPlayerViewController!
    override func viewDidLoad() {
        super.viewDidLoad()
        // Обязательно: категория playback для фонового воспроизведения
        try? AVAudioSession.sharedInstance().setCategory(.playback, mode: .moviePlayback)
        try? AVAudioSession.sharedInstance().setActive(true)
        player = AVPlayer(url: videoURL)
        playerViewController = AVPlayerViewController()
        playerViewController.player = player
        playerViewController.allowsPictureInPicturePlayback = true
        addChild(playerViewController)
        view.addSubview(playerViewController.view)
        playerViewController.view.frame = view.bounds
        playerViewController.didMove(toParent: self)
    }
}

אל תשכח להוסיף את import AVKit class VideoViewController: UIViewController { private var player: AVPlayer! private var playerViewController: AVPlayerViewController! override func viewDidLoad() { super.viewDidLoad() // Обязательно: категория playback для фонового воспроизведения try? AVAudioSession.sharedInstance().setCategory(.playback, mode: .moviePlayback) try? AVAudioSession.sharedInstance().setActive(true) player = AVPlayer(url: videoURL) playerViewController = AVPlayerViewController() playerViewController.player = player playerViewController.allowsPictureInPicturePlayback = true addChild(playerViewController) view.addSubview(playerViewController.view) playerViewController.view.frame = view.bounds playerViewController.didMove(toParent: self) } } → UIBackgroundModes ל-Info.plist. בלעדיו, PiP יציג וידאו אבל האודיו ינותק כשנכנסים לרקע—בעיה ש-70% מהמתחילים נתקלים בה. אינטגרציה בסיסית לוקחת 2–3 ימים, כולל בדיקות על גרסאות iOS שונות.

למה נגן מותאם אישית גמיש פי 3 מ-AVPlayerViewController

אם הנגן שלך מותאם אישית (מבוסס על audio, AVPlayerLayer, או OpenGL), SpriteKit לא יעבוד. אתה צריך AVPlayerViewController ישירות. הוא מאותחל דרך AVPictureInPictureController עבור AVPictureInPictureController(playerLayer:) או דרך AVPlayerLayer עם AVPictureInPictureControllerContentSource לעיבוד מותאם אישית. לפרויקטים מורכבים, נגן מותאם אישית עדיף פי 3 על AVPlayerViewController בגמישות. השווה עם הגישה הבסיסית:

מאפיין AVPlayerViewController AVPictureInPictureController
מורכבות אינטגרציה מינימלית בינונית
התאמה אישית של ממשק משתמש מוגבלת מלאה
תמיכה בתוכן שאינו וידאו לא כן (iOS 15+)
קוד נדרש ~20 שורות ~80 שורות
תאימות iOS iOS 9+ iOS 9+ (תוכן iOS 15+)
מהירות יישום (בסיס) 2–3 ימים 3–5 ימים

דוגמה ליישום מותאם אישית:

class CustomVideoPlayer: UIView {
    private var playerLayer: AVPlayerLayer!
    private var pipController: AVPictureInPictureController?

    func setupPiP() {
        guard AVPictureInPictureController.isPictureInPictureSupported() else { return }
        pipController = AVPictureInPictureController(playerLayer: playerLayer)
        pipController?.delegate = self
        pipController?.canStartPictureInPictureAutomaticallyFromInline = true // автостарт при уходе в фон
    }
}

extension CustomVideoPlayer: AVPictureInPictureControllerDelegate {
    func pictureInPictureControllerWillStartPictureInPicture(_ controller: AVPictureInPictureController) {
        // скрыть кастомные контролы поверх видео
    }

    func pictureInPictureController(_ controller: AVPictureInPictureController, restoreUserInterfaceForPictureInPictureStopWithCompletionHandler completionHandler: @escaping (Bool) -> Void) {
        // восстановить UI при закрытии PiP-окна
        completionHandler(true)
    }
}

ההבדל ברור: AVPictureInPictureSampleBufferPlaybackDelegate לווידאו פשוט, class CustomVideoPlayer: UIView { private var playerLayer: AVPlayerLayer! private var pipController: AVPictureInPictureController? func setupPiP() { guard AVPictureInPictureController.isPictureInPictureSupported() else { return } pipController = AVPictureInPictureController(playerLayer: playerLayer) pipController?.delegate = self pipController?.canStartPictureInPictureAutomaticallyFromInline = true // автостарт при уходе в фон } } extension CustomVideoPlayer: AVPictureInPictureControllerDelegate { func pictureInPictureControllerWillStartPictureInPicture(_ controller: AVPictureInPictureController) { // скрыть кастомные контролы поверх видео } func pictureInPictureController(_ controller: AVPictureInPictureController, restoreUserInterfaceForPictureInPictureStopWithCompletionHandler completionHandler: @escaping (Bool) -> Void) { // восстановить UI при закрытии PiP-окна completionHandler(true) } } לשליטה מלאה. המהנדסים שלנו עם ניסיון של 5+ שנים מעדיפים את האפשרות השנייה לפרויקטים עם תוכן לא סטנדרטי. הגישה המותאמת אישית דורשת כ-80 שורות קוד לעומת 20 לבסיסית, אבל מציעה גמישות גדולה פי 3.

איך לפתור בעיות של PiP שלא מתחיל במצב רקע

ב-90% מהמקרים, הבעיה נגרמת מאחד משלושה דברים:

  • AVPlayerViewController לא מוגדר.
  • AVPictureInPictureController חסר מ-Info.plist.
  • AVPictureInPictureVideoCallViewController לא מופעל או שהקטגוריה לא AVPictureInPictureControllerContentSource(activeVideoCallSourceView:contentViewController:).

בדוק כל נקודה—ו-PiP יעבוד. אם הווידאו קופא כשחוזרים מ-PiP, דחה את הקריאה ל-canStartPictureInPictureAutomaticallyFromInline = true ב-UIBackgroundModes: audio עד שממשק המשתמש ישוחזר במלואו. לפי התיעוד הרשמי של Apple, הגדרה נכונה של AVAudioSession היא קריטית: בלעדיה, האודיו אובד במצב רקע. ההבטחה שלנו: אנחנו מתקנים את הבעיות האלה תוך פחות משעתיים ברוב הפרויקטים.

הגדרת PiP לתוכן שרירותי

החל מ-iOS 15+, AVAudioSession זמין. בעזרתו, ניתן למקם כל UIView בחלון ה-PiP—לדוגמה, פיד מצלמה או וידאו WebRTC. התוכן מועבר דרך .playback. פתרון זה משמש אפליקציות מסרים (FaceTime, Zoom) לשיחות וידאו המוצגות מעל אפליקציות אחרות. מגבלה: התוכן חייב לייצג מבחינה רעיונית "שיחה פעילה"—Apple עשויה לדחות את האפליקציה אם יש ניצול לרעה בבדיקה. יישום פתרון זה לוקח עד 5 ימים כולל בדיקות.

היקף העבודה לאינטגרציית PiP

כשאתה מזמין את שירות אינטגרציית ה-PiP שלנו, אנחנו מספקים:

  1. אינטגרציה עם הנגן שלך (AVPlayerViewController או מותאם אישית) — לוקח 1–2 ימים.
  2. הגדרת AVAudioSession ו-Info.plist — עד 0.5 יום.
  3. טיפול בכל מצבי ה-PiP (התחלה, עצירה, שחזור ממשק משתמש) — 0.5–1 יום.
  4. בדיקות על מכשירים עם גרסאות iOS שונות (החל מ-iOS 14) — 1–2 ימים.
  5. תיעוד השינויים לצוות שלך — 0.5 יום.
מדריך שלב-אחר-שלב ליישום PiP
  1. קבע את סוג הנגן: האם אתה משתמש ב-completionHandler(true) או בנגן מותאם אישית? לווידאו פשוט, הראשון; למורכב, האחרון.
  2. הגדר את restoreUserInterfaceForPictureInPictureStopWithCompletionHandler עם קטגוריית UIBackgroundModes: audio והפעל אותו לפני יצירת הנגן.
  3. הוסף את AVAudioSession ל-Info.plist.
  4. יישם את ה-delegate של AVPictureInPictureController.isPictureInPictureSupported() כדי לטפל במעברים.
  5. בדוק על מכשירים אמיתיים תחת גרסאות iOS שונות—במיוחד iOS 14–17.

לוחות זמנים ותקציב

אינטגרציה בסיסית עם AVPlayerViewController לוקחת 2–3 ימי עבודה. נגן מותאם אישית עם AVPictureInPictureController ותוכן לא סטנדרטי—עד 5 ימים. העלות מחושבת באופן אישי; חיסכון טיפוסי מהימנעות מעבודה חוזרת מגיע ל-$5,000–$8,000 — צור קשר עם תמיכת המפתחים של Apple להנחיות רשמיות, או פנה לצוות המוסמך שלנו להערכת פרויקט. הזמן אינטגרציית PiP וחסוך עד 40% מתקציב הפיתוח. קבל ייעוץ לפרויקט שלך היום.