Реализация Picture-in-Picture режима для iOS-приложения

TRUETECH занимается разработкой, поддержкой и обслуживанием мобильных приложений iOS, Android, PWA. Имеем большой опыт и экспертизу для публикации мобильных приложений в популярные маркеты Google Play, App Store, Amazon, AppGallery и другие.

Разработка и поддержка любых видов мобильных приложений:

Информационные и развлекательные мобильные приложения
Новостные приложения, игры, справочники, онлайн-каталоги, погодные, фитнес и здоровье, туристические, образовательные, социальные сети и мессенджеры, квиз, блоги и подкасты, форумы, агрегаторы
Мобильные приложения электронной коммерции
Интернет-магазины, B2B-приложения, маркетплейсы, онлайн-обменники, кэшбэк-сервисы, биржи, дропшиппинг-платформы, программы лояльности, доставка еды и товаров, платежные системы
Мобильные приложения для управления бизнес-процессами
CRM-системы, ERP-системы, управление проектами, инструменты для команды продаж, учет финансов, управление производством, логистика и доставка, управление персоналом, системы мониторинга данных
Мобильные приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, платформы предоставления электронных услуг, платформы кешбека, видеохостинги, тематические порталы, платформы онлайн-бронирования и записи, платформы онлайн-торговли

Это лишь некоторые из типы мобильных приложений, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента.

Услуги, которые мы предлагаем
Показано 1 из 1Все 1735 услуг
Реализация Picture-in-Picture режима для iOS-приложения
Средний
~2-3 дня
Часто задаваемые вопросы

Наши компетенции:

Этапы разработки

Последние работы

  • image_mobile-applications_feedme_467_0.webp
    Разработка мобильного приложения для компании FEEDME
    792
  • image_mobile-applications_xoomer_471_0.webp
    Разработка мобильного приложения для компании XOOMER
    671
  • image_mobile-applications_rhl_428_0.webp
    Разработка мобильного приложения для компании RHL
    1097
  • image_mobile-applications_zippy_411_0.webp
    Разработка мобильного приложения для компании ZIPPY
    969
  • image_mobile-applications_affhome_429_0.webp
    Разработка мобильного приложения для компании Affhome
    914
  • image_mobile-applications_flavors_409_0.webp
    Разработка мобильного приложения для компании FLAVORS
    495

Реализация Picture-in-Picture режима для iOS-приложения

PiP на iOS работает не автоматически: приложение должно явно поддержать этот режим через AVKit API, правильно настроить AVAudioSession и обработать жизненный цикл PiP-окна. Кажется несложным — до тех пор, пока не начинаешь разбираться с кастомным контентом, не AVPlayer.

Базовая реализация с AVPlayerViewController

Самый простой путь — AVPlayerViewController. PiP из коробки: устанавливаем allowsPictureInPicturePlayback = true, настраиваем AVAudioSession, и кнопка PiP появляется автоматически.

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

Добавить в Info.plist: UIBackgroundModesaudio. Без этого PiP продолжит показывать видео, но звук пропадёт при переходе в фон.

Кастомный PiP: AVPictureInPictureController

Если видео-плеер кастомный (не AVPlayerViewController) — нужен AVPictureInPictureController напрямую. Инициализируется через AVPictureInPictureController(playerLayer:) для AVPlayerLayer или через AVPictureInPictureControllerContentSource с 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 pictureInPicture(_ controller: AVPictureInPictureController,
                          restoreUserInterfaceForPictureInPictureStopWithCompletionHandler completionHandler: @escaping (Bool) -> Void) {
        // восстановить UI при закрытии PiP-окна
        completionHandler(true)
    }
}

PiP с произвольным контентом (iOS 15+)

AVPictureInPictureVideoCallViewController (iOS 15+) — для не-видеоконтента: живое видео с камеры, WebRTC, анимации. Контент рендерится в UIView, который помещается в PiP-контейнер через AVPictureInPictureControllerContentSource(activeVideoCallSourceView:contentViewController:).

Это используют мессенджеры (FaceTime, Zoom) для видеозвонков поверх других приложений. Ключевое ограничение: контент должен быть действительно «активным вызовом» по смыслу — Apple может отклонить за злоупотребление в ревью.

Частые проблемы

PiP не запускается при переходе в фон. Причина в 90% случаев: не установлена canStartPictureInPictureAutomaticallyFromInline = true, или не настроен UIBackgroundModes: audio в Info.plist, или AVAudioSession неактивна.

Видео зависает при возврате из PiP. В restoreUserInterfaceForPictureInPictureStopWithCompletionHandler нужно вернуть completionHandler(true) только после того, как UI полностью восстановлен. Вызов completionHandler(true) сразу — система думает, что восстановление завершено и делает transition animation, но ваш UI ещё не готов.

Кастомные кнопки в PiP-окне. С iOS 16 — AVPictureInPictureController.requiresLinearPlayback = false и кастомные playbackControlsIncludeTransportBar, playbackControlsIncludeInfoViews. До iOS 16 — только стандартные контролы.

Сроки

2–3 рабочих дня для базовой интеграции PiP с AVPlayerViewController. Кастомный плеер с AVPictureInPictureController и нестандартным контентом — до 5 дней. Стоимость рассчитывается индивидуально.