Skip to content

Commit

Permalink
Additional refinement
Browse files Browse the repository at this point in the history
  • Loading branch information
allenhumphreys committed Jun 8, 2023
1 parent 324f3a3 commit 59a0085
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 52 deletions.
6 changes: 1 addition & 5 deletions PlayerUI/Protocols/PUIPlayerViewDelegates.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,10 @@

import Cocoa

public enum PUIPiPExitReason {
case returnButton, exitButton
}

public protocol PUIPlayerViewDelegate: AnyObject {

func playerViewWillEnterPictureInPictureMode(_ playerView: PUIPlayerView)
func playerViewWillExitPictureInPictureMode(_ playerView: PUIPlayerView, reason: PUIPiPExitReason)
func playerWillRestoreUserInterfaceForPictureInPictureStop(_ playerView: PUIPlayerView)
func playerViewDidSelectAddAnnotation(_ playerView: PUIPlayerView, at timestamp: Double)
func playerViewDidSelectToggleFullScreen(_ playerView: PUIPlayerView)
func playerViewDidSelectLike(_ playerView: PUIPlayerView)
Expand Down
90 changes: 48 additions & 42 deletions PlayerUI/Views/PUIPlayerView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,24 +19,7 @@ public final class PUIPlayerView: NSView {

public weak var delegate: PUIPlayerViewDelegate?

public internal(set) var isInPictureInPictureMode: Bool = false {
didSet {
guard isInPictureInPictureMode != oldValue else { return }

pipButton.state = isInPictureInPictureMode ? .on : .off

if isInPictureInPictureMode {
externalStatusController.providerIcon = .PUIPictureInPictureLarge
externalStatusController.providerName = "Picture in Picture"
externalStatusController.providerDescription = "Playing in Picture in Picture"
externalStatusController.view.isHidden = false
} else {
externalStatusController.view.isHidden = true
}

invalidateTouchBar()
}
}
public var isInPictureInPictureMode: Bool { pipController.isPictureInPictureActive }

public weak var appearanceDelegate: PUIPlayerViewAppearanceDelegate? {
didSet {
Expand Down Expand Up @@ -96,7 +79,6 @@ public final class PUIPlayerView: NSView {
pipPossibleObservation = pipController.observe(
\AVPictureInPictureController.isPictureInPicturePossible, options: [.initial, .new]
) { [weak self] _, change in
// Update the PiP button's enabled state.
self?.pipButton.isEnabled = change.newValue ?? false
}

Expand Down Expand Up @@ -1630,9 +1612,49 @@ extension PUIPlayerView: PUIExternalPlaybackConsumer {

// MARK: - PiP delegate

extension PUIPlayerView: /*PUIPictureContainerViewControllerDelegate,*/ AVPictureInPictureControllerDelegate {
extension PUIPlayerView: AVPictureInPictureControllerDelegate {

// Start

public func pictureInPictureControllerWillStartPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) {
delegate?.playerViewWillEnterPictureInPictureMode(self)

snapshotPlayer { [weak self] image in
self?.externalStatusController.snapshot = image
}
}

public func pictureInPictureControllerDidStartPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) {
pipButton.state = .on
externalStatusController.providerIcon = .PUIPictureInPictureLarge
externalStatusController.providerName = "Picture in Picture"
externalStatusController.providerDescription = "Playing in Picture in Picture"
externalStatusController.view.isHidden = false

invalidateTouchBar()
}

public func pictureInPictureController(
_ pictureInPictureController: AVPictureInPictureController,
failedToStartPictureInPictureWithError error: Error
) {
os_log(.error, log: log, "Failed to start PiP \(error, privacy: .public)")
}

// Stop

// Called 1st
public func pictureInPictureControllerWillStopPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) {

}

// Called 2nd, not called when the exit button is pressed
public func pictureInPictureController(
_ pictureInPictureController: AVPictureInPictureController,
restoreUserInterfaceForPictureInPictureStopWithCompletionHandler completionHandler: @escaping (Bool) -> Void
) {
delegate?.playerWillRestoreUserInterfaceForPictureInPictureStop(self)

public func pictureInPictureController(_ pictureInPictureController: AVPictureInPictureController, restoreUserInterfaceForPictureInPictureStopWithCompletionHandler completionHandler: @escaping (Bool) -> Void) {
if !NSApp.isActive {
NSApp.activate(ignoringOtherApps: true)
}
Expand All @@ -1644,30 +1666,14 @@ extension PUIPlayerView: /*PUIPictureContainerViewControllerDelegate,*/ AVPictur
window.deminiaturize(nil)
}
}
completionHandler(true)
}

public func pictureInPictureController(_ pictureInPictureController: AVPictureInPictureController, failedToStartPictureInPictureWithError error: Error) {
isInPictureInPictureMode = false
completionHandler(true)
}

// Called Last
public func pictureInPictureControllerDidStopPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) {
isInPictureInPictureMode = false
}

public func pictureInPictureControllerWillStartPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) {
delegate?.playerViewWillEnterPictureInPictureMode(self)

snapshotPlayer { [weak self] image in
self?.externalStatusController.snapshot = image
}
}

public func pictureInPictureControllerDidStartPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) {
isInPictureInPictureMode = true
}

public func pictureInPictureControllerWillStopPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) {
delegate?.playerViewWillExitPictureInPictureMode(self, reason: .returnButton)
pipButton.state = .off
externalStatusController.view.isHidden = true
invalidateTouchBar()
}
}
3 changes: 1 addition & 2 deletions WWDC/AppCoordinator+Shelf.swift
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,7 @@ extension AppCoordinator: ShelfViewControllerDelegate {

if currentPlayerController == nil {
currentPlayerController = VideoPlayerViewController(player: playbackViewModel.player, session: viewModel)
currentPlayerController?.playerWillExitPictureInPicture = { [weak self] reason in
guard reason == .returnButton else { return }
currentPlayerController?.playerWillRestoreUserInterfaceForPictureInPictureStop = { [weak self] in
self?.returnToPlayingSessionContext()
}

Expand Down
6 changes: 3 additions & 3 deletions WWDC/VideoPlayerViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ final class VideoPlayerViewController: NSViewController {
}
}

var playerWillExitPictureInPicture: ((PUIPiPExitReason) -> Void)?
var playerWillRestoreUserInterfaceForPictureInPictureStop: (() -> Void)?
var playerWillExitFullScreen: (() -> Void)?

init(player: AVPlayer, session: SessionViewModel) {
Expand Down Expand Up @@ -336,8 +336,8 @@ extension VideoPlayerViewController: PUIPlayerViewDelegate {
playerView.snapshotPlayer(completion: completion)
}

func playerViewWillExitPictureInPictureMode(_ playerView: PUIPlayerView, reason: PUIPiPExitReason) {
playerWillExitPictureInPicture?(reason)
func playerWillRestoreUserInterfaceForPictureInPictureStop(_ playerView: PUIPlayerView) {
playerWillRestoreUserInterfaceForPictureInPictureStop?()
}

func playerViewWillEnterPictureInPictureMode(_ playerView: PUIPlayerView) {
Expand Down

0 comments on commit 59a0085

Please sign in to comment.