I did some studying on Picture in Picture for AVPlayerViewController. I’m trying to make it so that I can put some text as subtitles or some other Views to the PiP window when the app goes into background but no luck of getting any solution for that. Is there any way or any work around I can achieve that?
final class AVPlayerViewModel: ObservableObject {
@Published var pipStatus: PipStatus = .undefined
@Published var media: Media?
let player = AVPlayer()
private var cancellable: AnyCancellable?
init() {
setAudioSessionCategory(to: .playback)
cancellable = $media
.compactMap({ $0 })
.compactMap({ URL(string: $0.url) })
.sink(receiveValue: { [weak self] in
guard let self = self else { return }
self.player.replaceCurrentItem(with: AVPlayerItem(url: $0))
})
}
func play() {
player.play()
}
func pause() {
player.pause()
}
func setAudioSessionCategory(to value: AVAudioSession.Category) {
let audioSession = AVAudioSession.sharedInstance()
do {
try audioSession.setCategory(value)
} catch {
print("Setting category to AVAudioSessionCategoryPlayback failed.")
}
}
}
struct AVVideoPlayer: UIViewControllerRepresentable {
@ObservedObject var viewModel: AVPlayerViewModel
func makeUIViewController(context: Context) -> AVPlayerViewController {
let vc = AVPlayerViewController()
vc.player = viewModel.player
vc.canStartPictureInPictureAutomaticallyFromInline = true
vc.delegate = context.coordinator
return vc
}
func updateUIViewController(_ uiViewController: AVPlayerViewController, context: Context) {
// You can update the UI if needed
}
func makeCoordinator() -> Coordinator {
return Coordinator(self)
}
class Coordinator: NSObject, AVPlayerViewControllerDelegate {
let parent: AVVideoPlayer
init(_ parent: AVVideoPlayer) {
self.parent = parent
}
func playerViewControllerWillStartPictureInPicture(_ playerViewController: AVPlayerViewController) {
parent.viewModel.pipStatus = .willStart
}
func playerViewControllerDidStartPictureInPicture(_ playerViewController: AVPlayerViewController) {
parent.viewModel.pipStatus = .didStart
}
func playerViewControllerWillStopPictureInPicture(_ playerViewController: AVPlayerViewController) {
parent.viewModel.pipStatus = .willStop
}
func playerViewControllerDidStopPictureInPicture(_ playerViewController: AVPlayerViewController) {
parent.viewModel.pipStatus = .didStop
}
}
}
This is the working code I got from Here.