From eb7cca1c56eb7f98ebe4a24f556f5b3d6feb18fa Mon Sep 17 00:00:00 2001 From: Arkadiusz Fal Date: Sat, 21 May 2022 22:58:11 +0200 Subject: [PATCH] PiP improvements --- Model/Player/Backends/AVPlayerBackend.swift | 19 ++++++++++++------- Model/Player/Backends/MPVBackend.swift | 2 ++ Model/Player/PiPDelegate.swift | 13 ++++++++++--- Model/Player/PlayerControlsModel.swift | 2 +- Model/Player/PlayerModel.swift | 1 - Model/Player/PlayerQueue.swift | 2 -- Shared/Player/Controls/PlayerControls.swift | 2 +- Shared/Player/PlayerQueueRow.swift | 2 ++ Shared/Videos/VideoCell.swift | 2 ++ 9 files changed, 30 insertions(+), 15 deletions(-) diff --git a/Model/Player/Backends/AVPlayerBackend.swift b/Model/Player/Backends/AVPlayerBackend.swift index 8b607ea0..7e0b31ba 100644 --- a/Model/Player/Backends/AVPlayerBackend.swift +++ b/Model/Player/Backends/AVPlayerBackend.swift @@ -37,7 +37,7 @@ final class AVPlayerBackend: PlayerBackend { private(set) var avPlayer = AVPlayer() var controller: AppleAVPlayerViewController? - var enterPiPOnPlay = false + var startPictureInPictureOnPlay = false var switchToMPVOnPipClose = false private var asset: AVURLAsset? @@ -323,6 +323,8 @@ final class AVPlayerBackend: PlayerBackend { } } } + + self.setRate(self.model.currentRate) } let replaceItemAndSeek = { @@ -442,7 +444,7 @@ final class AVPlayerBackend: PlayerBackend { self, selector: #selector(itemDidPlayToEndTime), name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, - object: playerItem + object: model.playerItem ) } @@ -450,7 +452,7 @@ final class AVPlayerBackend: PlayerBackend { NotificationCenter.default.removeObserver( self, name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, - object: playerItem + object: model.playerItem ) } @@ -470,6 +472,9 @@ final class AVPlayerBackend: PlayerBackend { model.hide() #endif } else { + if model.playingInPictureInPicture { + startPictureInPictureOnPlay = true + } model.advanceToNextItem() } } @@ -538,10 +543,10 @@ final class AVPlayerBackend: PlayerBackend { if player.timeControlStatus != .waitingToPlayAtSpecifiedRate { if let controller = self.model.pipController { if controller.isPictureInPicturePossible { - if self.enterPiPOnPlay { - self.enterPiPOnPlay = false - DispatchQueue.main.async { [weak self] in - self?.model.pipController?.startPictureInPicture() + if self.startPictureInPictureOnPlay { + self.startPictureInPictureOnPlay = false + DispatchQueue.main.async { + self.model.pipController?.startPictureInPicture() } } } diff --git a/Model/Player/Backends/MPVBackend.swift b/Model/Player/Backends/MPVBackend.swift index cafd77c8..9c435828 100644 --- a/Model/Player/Backends/MPVBackend.swift +++ b/Model/Player/Backends/MPVBackend.swift @@ -201,6 +201,8 @@ final class MPVBackend: PlayerBackend { startControlsUpdates() } + setRate(model.currentRate) + client?.play() } diff --git a/Model/Player/PiPDelegate.swift b/Model/Player/PiPDelegate.swift index bbe164ca..9ac10894 100644 --- a/Model/Player/PiPDelegate.swift +++ b/Model/Player/PiPDelegate.swift @@ -13,7 +13,10 @@ final class PiPDelegate: NSObject, AVPictureInPictureControllerDelegate { func pictureInPictureControllerWillStartPictureInPicture(_: AVPictureInPictureController) {} - func pictureInPictureControllerDidStartPictureInPicture(_: AVPictureInPictureController) {} + func pictureInPictureControllerDidStartPictureInPicture(_: AVPictureInPictureController) { + player?.playingInPictureInPicture = true + player?.avPlayerBackend.startPictureInPictureOnPlay = false + } func pictureInPictureControllerDidStopPictureInPicture(_: AVPictureInPictureController) { if player?.avPlayerBackend.switchToMPVOnPipClose ?? false { @@ -24,12 +27,16 @@ final class PiPDelegate: NSObject, AVPictureInPictureControllerDelegate { } } } + + player?.playingInPictureInPicture = false } func pictureInPictureControllerWillStopPictureInPicture(_: AVPictureInPictureController) {} func pictureInPictureController( _: AVPictureInPictureController, - restoreUserInterfaceForPictureInPictureStopWithCompletionHandler _: @escaping (Bool) -> Void - ) {} + restoreUserInterfaceForPictureInPictureStopWithCompletionHandler completionHandler: @escaping (Bool) -> Void + ) { + completionHandler(true) + } } diff --git a/Model/Player/PlayerControlsModel.swift b/Model/Player/PlayerControlsModel.swift index e8a55eb9..86434b1f 100644 --- a/Model/Player/PlayerControlsModel.swift +++ b/Model/Player/PlayerControlsModel.swift @@ -3,7 +3,7 @@ import Foundation import SwiftUI final class PlayerControlsModel: ObservableObject { - @Published var isLoadingVideo = true + @Published var isLoadingVideo = false @Published var isPlaying = true @Published var currentTime = CMTime.zero @Published var duration = CMTime.zero diff --git a/Model/Player/PlayerModel.swift b/Model/Player/PlayerModel.swift index a44607f5..1a0a1454 100644 --- a/Model/Player/PlayerModel.swift +++ b/Model/Player/PlayerModel.swift @@ -343,7 +343,6 @@ final class PlayerModel: ObservableObject { } inactiveBackends().forEach { $0.pause() } - backend.setRate(currentRate) let fromBackend: PlayerBackend = from == .appleAVPlayer ? avPlayerBackend : mpvBackend let toBackend: PlayerBackend = to == .appleAVPlayer ? avPlayerBackend : mpvBackend diff --git a/Model/Player/PlayerQueue.swift b/Model/Player/PlayerQueue.swift index f8c20990..2512c655 100644 --- a/Model/Player/PlayerQueue.swift +++ b/Model/Player/PlayerQueue.swift @@ -111,7 +111,6 @@ extension PlayerModel { remove(newItem) currentItem = newItem - pause() accounts.api.loadDetails(newItem) { newItem in self.playItem(newItem, video: newItem.video, at: time) @@ -152,7 +151,6 @@ extension PlayerModel { if play { currentItem = item // pause playing current video as it's going to be replaced with next one - pause() } queue.insert(item, at: prepending ? 0 : queue.endIndex) diff --git a/Shared/Player/Controls/PlayerControls.swift b/Shared/Player/Controls/PlayerControls.swift index 8a369e40..c3df2ab0 100644 --- a/Shared/Player/Controls/PlayerControls.swift +++ b/Shared/Player/Controls/PlayerControls.swift @@ -252,7 +252,7 @@ struct PlayerControls: View { DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) { print(player.pipController?.isPictureInPicturePossible ?? false ? "possible" : "NOT possible") - player.avPlayerBackend.enterPiPOnPlay = true + player.avPlayerBackend.startPictureInPictureOnPlay = true player.pipController?.startPictureInPicture() } } diff --git a/Shared/Player/PlayerQueueRow.swift b/Shared/Player/PlayerQueueRow.swift index ab411bd7..307175a6 100644 --- a/Shared/Player/PlayerQueueRow.swift +++ b/Shared/Player/PlayerQueueRow.swift @@ -30,6 +30,8 @@ struct PlayerQueueRow: View { Button { player.prepareCurrentItemForHistory() + player.avPlayerBackend.startPictureInPictureOnPlay = player.playingInPictureInPicture + if history { player.playHistory(item, at: watchStoppedAt) } else { diff --git a/Shared/Videos/VideoCell.swift b/Shared/Videos/VideoCell.swift index 32a77d23..1e417062 100644 --- a/Shared/Videos/VideoCell.swift +++ b/Shared/Videos/VideoCell.swift @@ -91,6 +91,8 @@ struct VideoCell: View { playAt = .secondsInDefaultTimescale(watch!.stoppedAt) } + player.avPlayerBackend.startPictureInPictureOnPlay = player.playingInPictureInPicture + player.play(video, at: playAt, inNavigationView: inNavigationView) } }