Skip to content

Commit 324f3a3

Browse files
Go a bit further in changing over
1 parent e8c1eb8 commit 324f3a3

File tree

3 files changed

+46
-179
lines changed

3 files changed

+46
-179
lines changed

PlayerUI/Controllers/PUIPictureContainerViewController.swift

Lines changed: 0 additions & 69 deletions
This file was deleted.

PlayerUI/Views/PUIPlayerView.swift

Lines changed: 46 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -87,13 +87,20 @@ public final class PUIPlayerView: NSView {
8787
public var mediaTitle: String?
8888
public var mediaIsLiveStream: Bool = false
8989

90-
var pictureContainer: PUIPictureContainerViewController!
91-
9290
public init(player: AVPlayer) {
9391
self.player = player
92+
self.pipController = AVPictureInPictureController(contentSource: .init(playerLayer: playerLayer))
9493

9594
super.init(frame: .zero)
9695

96+
pipPossibleObservation = pipController.observe(
97+
\AVPictureInPictureController.isPictureInPicturePossible, options: [.initial, .new]
98+
) { [weak self] _, change in
99+
// Update the PiP button's enabled state.
100+
self?.pipButton.isEnabled = change.newValue ?? false
101+
}
102+
103+
pipController.delegate = self
97104
wantsLayer = true
98105
layer = PUIBoringLayer()
99106
layer?.backgroundColor = NSColor.black.cgColor
@@ -217,7 +224,7 @@ public final class PUIPlayerView: NSView {
217224
return player?.currentItem?.asset
218225
}
219226

220-
private var playerLayer = PUIBoringPlayerLayer()
227+
private let playerLayer = PUIBoringPlayerLayer()
221228

222229
private func setupPlayer() {
223230
elapsedTimeLabel.stringValue = elapsedTimeInitialValue
@@ -229,15 +236,6 @@ public final class PUIPlayerView: NSView {
229236
playerLayer.player = player
230237
playerLayer.videoGravity = .resizeAspect
231238

232-
if pictureContainer == nil {
233-
pictureContainer = PUIPictureContainerViewController(playerLayer: playerLayer)
234-
pictureContainer.delegate = self
235-
pictureContainer.view.frame = bounds
236-
pictureContainer.view.autoresizingMask = [.width, .height]
237-
238-
addSubview(pictureContainer.view)
239-
}
240-
241239
player.addObserver(self, forKeyPath: #keyPath(AVPlayer.status), options: [.initial, .new], context: nil)
242240
player.addObserver(self, forKeyPath: #keyPath(AVPlayer.volume), options: [.initial, .new], context: nil)
243241
player.addObserver(self, forKeyPath: #keyPath(AVPlayer.rate), options: [.initial, .new], context: nil)
@@ -341,8 +339,6 @@ public final class PUIPlayerView: NSView {
341339
}
342340

343341
fileprivate func updatePlayingState() {
344-
// pipController?.setPlaying(isPlaying)
345-
346342
if isPlaying {
347343
playButton.image = .PUIPause
348344
} else {
@@ -651,6 +647,7 @@ public final class PUIPlayerView: NSView {
651647
b.target = self
652648
b.action = #selector(togglePip)
653649
b.toolTip = "Toggle picture in picture"
650+
b.isEnabled = false
654651

655652
return b
656653
}()
@@ -662,6 +659,17 @@ public final class PUIPlayerView: NSView {
662659
private func setupControls() {
663660
externalStatusController.view.isHidden = true
664661
externalStatusController.view.translatesAutoresizingMaskIntoConstraints = false
662+
let playerView = NSView()
663+
playerView.translatesAutoresizingMaskIntoConstraints = false
664+
playerView.wantsLayer = true
665+
playerView.layer = playerLayer
666+
playerLayer.backgroundColor = .clear
667+
addSubview(playerView)
668+
playerView.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
669+
playerView.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
670+
playerView.topAnchor.constraint(equalTo: topAnchor).isActive = true
671+
playerView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
672+
665673
addSubview(externalStatusController.view)
666674
externalStatusController.view.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
667675
externalStatusController.view.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
@@ -1020,9 +1028,9 @@ public final class PUIPlayerView: NSView {
10201028

10211029
@IBAction public func togglePip(_ sender: NSView?) {
10221030
if isInPictureInPictureMode {
1023-
pipController?.stopPictureInPicture()
1031+
pipController.stopPictureInPicture()
10241032
} else {
1025-
enterPictureInPictureMode()
1033+
pipController.startPictureInPicture()
10261034
}
10271035
}
10281036

@@ -1268,24 +1276,8 @@ public final class PUIPlayerView: NSView {
12681276
}
12691277
}
12701278

1271-
fileprivate var pipController: AVPictureInPictureController?
1272-
1273-
fileprivate func enterPictureInPictureMode() {
1274-
delegate?.playerViewWillEnterPictureInPictureMode(self)
1275-
1276-
snapshotPlayer { [weak self] image in
1277-
self?.externalStatusController.snapshot = image
1278-
}
1279-
1280-
pipController = AVPictureInPictureController(playerLayer: playerLayer)
1281-
pipController?.delegate = self
1282-
// pipController?.setPlaying(isPlaying)
1283-
// pipController?.aspectRatio = currentPresentationSize ?? NSSize(width: 640, height: 360)
1284-
// pipController?.view.layer?.backgroundColor = NSColor.black.cgColor
1285-
1286-
// pipController?.presentAsPicture(inPicture: pictureContainer)
1287-
pipController?.startPictureInPicture()
1288-
}
1279+
fileprivate let pipController: AVPictureInPictureController
1280+
private var pipPossibleObservation: Any?
12891281

12901282
// MARK: - Visibility management
12911283

@@ -1638,65 +1630,9 @@ extension PUIPlayerView: PUIExternalPlaybackConsumer {
16381630

16391631
// MARK: - PiP delegate
16401632

1641-
extension PUIPlayerView: PUIPictureContainerViewControllerDelegate, AVPictureInPictureControllerDelegate {
1642-
1643-
// public func pipActionStop(_ pip: PIPViewController) {
1644-
// pause(pip)
1645-
//
1646-
// }
1647-
//
1648-
// public func pipActionReturn(_ pip: PIPViewController) {
1649-
// delegate?.playerViewWillExitPictureInPictureModelegate?.playerViewWillExitPictureInPictureMode(self, reason: .exitButton)de(self, reason: .returnButton)
1650-
//
1651-
// if !NSApp.isActive {
1652-
// NSApp.activate(ignoringOtherApps: true)
1653-
// }
1654-
//
1655-
// if let window = lastKnownWindow {
1656-
// window.makeKeyAndOrderFront(pip)
1657-
//
1658-
// if window.isMiniaturized {
1659-
// window.deminiaturize(nil)
1660-
// }
1661-
// }
1662-
// }
1663-
1664-
// public func pipActionPause(_ pip: PIPViewController) {
1665-
// pause(pip)
1666-
// }
1667-
//
1668-
// public func pipActionPlay(_ pip: PIPViewController) {
1669-
// play(pip)
1670-
// }
1671-
1672-
public func pictureInPictureController(_ pictureInPictureController: AVPictureInPictureController, failedToStartPictureInPictureWithError error: Error) {
1673-
isInPictureInPictureMode = false
1674-
pipController = nil
1675-
}
1676-
1677-
public func pictureInPictureControllerDidStopPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) {
1678-
print("Player Rate: \(player?.rate)")
1679-
isInPictureInPictureMode = false
1680-
pipController = nil
1681-
}
1682-
1683-
public func pictureInPictureControllerDidStartPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) {
1684-
isInPictureInPictureMode = true
1685-
}
1686-
1687-
// public func pipDidClose(_ pip: PIPViewController) {
1688-
// pictureContainer.view.frame = bounds
1689-
//
1690-
// addSubview(pictureContainer.view, positioned: .below, relativeTo: scrimContainerView)
1691-
//
1692-
// isInPictureInPictureMode = false
1693-
// pipController = nil
1694-
// }
1695-
1696-
public func pictureInPictureControllerWillStopPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) {
1697-
delegate?.playerViewWillExitPictureInPictureMode(self, reason: .returnButton)
1698-
print("Player Rate: \(player?.rate)")
1633+
extension PUIPlayerView: /*PUIPictureContainerViewControllerDelegate,*/ AVPictureInPictureControllerDelegate {
16991634

1635+
public func pictureInPictureController(_ pictureInPictureController: AVPictureInPictureController, restoreUserInterfaceForPictureInPictureStopWithCompletionHandler completionHandler: @escaping (Bool) -> Void) {
17001636
if !NSApp.isActive {
17011637
NSApp.activate(ignoringOtherApps: true)
17021638
}
@@ -1708,26 +1644,30 @@ extension PUIPlayerView: PUIPictureContainerViewControllerDelegate, AVPictureInP
17081644
window.deminiaturize(nil)
17091645
}
17101646
}
1647+
completionHandler(true)
17111648
}
17121649

1713-
// public func pipWillClose(_ pip: PIPViewController) {
1714-
// pip.replacementRect = frame
1715-
// pip.replacementView = self
1716-
// pip.replacementWindow = lastKnownWindow
1717-
// }
1718-
1719-
func pictureContainerViewSuperviewDidChange(to superview: NSView?) {
1720-
guard let superview = superview else { return }
1650+
public func pictureInPictureController(_ pictureInPictureController: AVPictureInPictureController, failedToStartPictureInPictureWithError error: Error) {
1651+
isInPictureInPictureMode = false
1652+
}
17211653

1722-
pictureContainer.view.frame = superview.bounds
1654+
public func pictureInPictureControllerDidStopPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) {
1655+
isInPictureInPictureMode = false
1656+
}
17231657

1724-
if superview == self, pipController != nil {
1725-
if pictureContainer.presentingViewController == pipController {
1726-
pipController?.stopPictureInPicture()
1727-
}
1658+
public func pictureInPictureControllerWillStartPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) {
1659+
delegate?.playerViewWillEnterPictureInPictureMode(self)
17281660

1729-
pipController = nil
1661+
snapshotPlayer { [weak self] image in
1662+
self?.externalStatusController.snapshot = image
17301663
}
17311664
}
17321665

1666+
public func pictureInPictureControllerDidStartPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) {
1667+
isInPictureInPictureMode = true
1668+
}
1669+
1670+
public func pictureInPictureControllerWillStopPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) {
1671+
delegate?.playerViewWillExitPictureInPictureMode(self, reason: .returnButton)
1672+
}
17331673
}

WWDC.xcodeproj/project.pbxproj

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,6 @@
147147
DDF7219D1ECA12780054C503 /* PlayerUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DDF721961ECA12780054C503 /* PlayerUI.framework */; };
148148
DDF7219E1ECA12780054C503 /* PlayerUI.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = DDF721961ECA12780054C503 /* PlayerUI.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
149149
DDF721C71ECA12A40054C503 /* PUIExternalPlaybackStatusViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDF721A51ECA12A40054C503 /* PUIExternalPlaybackStatusViewController.swift */; };
150-
DDF721C81ECA12A40054C503 /* PUIPictureContainerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDF721A61ECA12A40054C503 /* PUIPictureContainerViewController.swift */; };
151150
DDF721C91ECA12A40054C503 /* Colors.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDF721A81ECA12A40054C503 /* Colors.swift */; };
152151
DDF721CA1ECA12A40054C503 /* Images.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDF721A91ECA12A40054C503 /* Images.swift */; };
153152
DDF721CB1ECA12A40054C503 /* Speeds.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDF721AA1ECA12A40054C503 /* Speeds.swift */; };
@@ -414,7 +413,6 @@
414413
DDF721981ECA12780054C503 /* PlayerUI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PlayerUI.h; sourceTree = "<group>"; };
415414
DDF721991ECA12780054C503 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
416415
DDF721A51ECA12A40054C503 /* PUIExternalPlaybackStatusViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PUIExternalPlaybackStatusViewController.swift; sourceTree = "<group>"; };
417-
DDF721A61ECA12A40054C503 /* PUIPictureContainerViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PUIPictureContainerViewController.swift; sourceTree = "<group>"; };
418416
DDF721A81ECA12A40054C503 /* Colors.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Colors.swift; sourceTree = "<group>"; };
419417
DDF721A91ECA12A40054C503 /* Images.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Images.swift; sourceTree = "<group>"; };
420418
DDF721AA1ECA12A40054C503 /* Speeds.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Speeds.swift; sourceTree = "<group>"; };
@@ -986,7 +984,6 @@
986984
isa = PBXGroup;
987985
children = (
988986
DDF721A51ECA12A40054C503 /* PUIExternalPlaybackStatusViewController.swift */,
989-
DDF721A61ECA12A40054C503 /* PUIPictureContainerViewController.swift */,
990987
DDC6781E1EDB8EDA00A4E19C /* PUIAnnotationWindowController.swift */,
991988
);
992989
path = Controllers;
@@ -1545,7 +1542,6 @@
15451542
buildActionMask = 2147483647;
15461543
files = (
15471544
DDF721D11ECA12A40054C503 /* PUITimelineAnnotation.swift in Sources */,
1548-
DDF721C81ECA12A40054C503 /* PUIPictureContainerViewController.swift in Sources */,
15491545
DDF721D51ECA12A40054C503 /* AVPlayer+Validation.swift in Sources */,
15501546
DDF721CA1ECA12A40054C503 /* Images.swift in Sources */,
15511547
4DA83FE222AC3F2F0062DB8B /* PUIVibrantBackgroundButton.swift in Sources */,

0 commit comments

Comments
 (0)