iOS 비디오 PIP 재생 구현 - kirseia/study GitHub Wiki

PIP

  • Picture in Picture
  • iOS 에서도 제한적으로 처리 가능
  • youtube 앱에서 재생 하는 것처럼 VC위에 오버레이 되어서 재생 가능

한계

  • 홈 버튼을 눌러서도 재생처리하는 것은 iPad 에서만 가능

구현 방식은 크게 3가지

1) iphone / ipad 모두 구현 가능한 방식
  • 재생 레이어(AVPlayerLayer)를 ViewController 위가 아닌 window 위에 얹어서 재생하기
  • 다만, 이렇게 될 경우 익숙한 ViewController 생명주기를 따르지 않기 때문에 구현에 주의가 필요
  • ViewController 가 Player / PlayerLayer 를 가지고 있을 경우 ViewController 를 넘어서는 순간 메모리에서 해제 될 수 있으므로 주의 필요
guard let window = UIApplication.shared.keyWindow else { return }
        
windowSize = window.frame.size
window.addSubview(playerView)
2) ipad만 가능한 방식
  • AVPictureInPictureController 를 활용하는 방식
  • AVPictureInPictureController 는 subclassing 하면 안됨
  • AVPlayerLayer를 AVPictureInPictureController 에 세팅해서 사용.
  • pictureInPictureController.startPictureInPicture() 를 호출하면 바로 사용 가능
// setup 
if let layer = playerView.playerLayer, AVPictureInPictureController.isPictureInPictureSupported() {
    pipController = AVPictureInPictureController(playerLayer: layer)
    pipController?.delegate = self
}

// start / stop 
if enable {
    pipController?.startPictureInPicture()
} else {
    pipController?.stopPictureInPicture()
}

// background 갈 때 바로 pip 처리 및 복귀 했을 때 처리 
NotificationCenter.default.addObserver(forName: UIApplication.willResignActiveNotification , object: nil, queue: nil) { [weak self] (noti) in
    // pip start 
}

NotificationCenter.default.addObserver(forName: UIApplication.willEnterForegroundNotification, object: nil, queue: nil) { [weak self] (noti) in
    // pip stop
}
        

ref. https://developer.apple.com/library/archive/documentation/WindowsViews/Conceptual/AdoptingMultitaskingOniPad/QuickStartForPictureInPicture.html

3) AVPlayerViewController 이용하기
  • ViewController 를 AVPlayerViewController 를 상속받는다.
  • 기본적으로 pip 가 가능함.
  • 다른 컨트롤러 없이 iOS의 기본 UI를 이용해서 재생만 하고 싶을 때 사용하면 됨
  • 젤 간단
import AVKit

class SampleAVPlayerViewController: AVPlayerViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let url = URL(fileURLWithPath: 비디오파일패스)
        self.player = AVPlayer(url: url)
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        self.player?.play()
    }
}
  • 끝. 참 쉽죠?