From 4520c135ce2fdb74d3593bfee4e1a4bd089736d4 Mon Sep 17 00:00:00 2001 From: Chris Zielinski Date: Tue, 19 Jun 2018 23:25:33 -0700 Subject: [PATCH] Refactor FillMode (again), add convenience method for adding player to parent view controller --- Project/Player/ViewController.swift | 10 +--- Project/PlayerMac/ViewController.swift | 7 ++- Sources/Player.swift | 72 ++++++++++++++++++-------- 3 files changed, 57 insertions(+), 32 deletions(-) diff --git a/Project/Player/ViewController.swift b/Project/Player/ViewController.swift index 44525d1..c8ef8c5 100644 --- a/Project/Player/ViewController.swift +++ b/Project/Player/ViewController.swift @@ -47,9 +47,7 @@ class ViewController: UIViewController { player.playbackDelegate = self player.view.translatesAutoresizingMaskIntoConstraints = false - addChildViewController(player) - player.didMove(toParentViewController: self) - view.addSubview(player.view) + player.add(to: self) let uri = "https://www.apple.com/105/media/us/iphone-x/2017/01df5b43-28e4-4848-bf20-490c34a926a7" + "/films/meet-iphone-x/iphone-x-meet-iphone-tpl-cc-us-20171129_1280x720h.mp4" @@ -85,13 +83,9 @@ class ViewController: UIViewController { @objc private func orientationWillChange() { let currentOrientation = UIDevice.current.orientation if UIDeviceOrientationIsLandscape(currentOrientation) { - print("Landscape") player.fillMode = .resizeAspectFill - // Resize other things } else if UIDeviceOrientationIsPortrait(currentOrientation) { - print("Portrait") - // Resize other things - player.fillMode = .resizeAspect + player.fillMode = .resizeAspectFit } } diff --git a/Project/PlayerMac/ViewController.swift b/Project/PlayerMac/ViewController.swift index 6be364b..17f629f 100644 --- a/Project/PlayerMac/ViewController.swift +++ b/Project/PlayerMac/ViewController.swift @@ -38,7 +38,7 @@ class ViewController: NSViewController { } override func loadView() { - view = player.view + view = NSView() view.autoresizingMask = [.height, .width] view.setFrameSize(NSSize(width: 400 * (16.0 / 9), height: 400)) } @@ -48,6 +48,10 @@ class ViewController: NSViewController { override func viewDidLoad() { super.viewDidLoad() + player.view.autoresizingMask = [.height, .width] + player.view.frame = view.bounds + player.add(to: self) + player.playerDelegate = self player.playbackDelegate = self @@ -57,6 +61,7 @@ class ViewController: NSViewController { player.playbackLoops = true player.fillMode = .resizeAspectFill player.controlsStyle = .floating + player.playbackPausesWhenResigningActive = false } override func viewDidAppear() { diff --git a/Sources/Player.swift b/Sources/Player.swift index 8a78c96..32d51d7 100755 --- a/Sources/Player.swift +++ b/Sources/Player.swift @@ -98,36 +98,48 @@ public protocol PlayerPlaybackDelegate: NSObjectProtocol { @objc optional func playerPlaybackWillLoop(player: Player) } -// MARK: - Type Aliases +// MARK: - Player -#if canImport(AppKit) - public typealias PlayerViewController = NSViewController +/// ▶️ Player, simple way to play and stream media +open class Player: Player.ViewController { + // MARK: - Type Aliases + + #if canImport(AppKit) + public typealias ViewController = NSViewController public typealias PlayerView = AVPlayerView public typealias Image = NSImage public typealias Color = NSColor public typealias SnapshotResult = Image? public typealias NibName = NSNib.Name? -#else - public typealias PlayerViewController = UIViewController + #else + public typealias ViewController = UIViewController public typealias Image = UIImage public typealias Color = UIColor public typealias SnapshotResult = Image public typealias NibName = String? -#endif - -// MARK: - Player + #endif -/// ▶️ Player, simple way to play and stream media -open class Player: PlayerViewController { /// Video fill mode options for `Player.fillMode`. /// - /// - resize: Stretch to fill. - /// - resizeAspectFill: Preserve aspect ratio, filling bounds. - /// - resizeAspectFit: Preserve aspect ratio, fill within bounds. + /// - resizeStretch: Specifies that the video should be stretched to fill the layer’s bounds. + /// - resizeAspectFill: Specifies that the player should preserve the video’s aspect ratio and fill the layer’s bounds. + /// - resizeAspectFit: Specifies that the player should preserve the video’s aspect ratio and fit the video within the layer’s bounds. public enum FillMode: String { - case resizeFill = "AVLayerVideoGravityResize" + case resizeStretch = "AVLayerVideoGravityResize" case resizeAspectFill = "AVLayerVideoGravityResizeAspectFill" case resizeAspectFit = "AVLayerVideoGravityResizeAspect" // default + + fileprivate var avLayerVideoGravityValue: AVLayerVideoGravity { + return AVLayerVideoGravity(rawValue: self.rawValue) +// switch self { +// case .resizeFill: +// return .resize +// case .resizeAspectFill: +// return .resizeAspectFill +// case .resizeAspectFit: +// return .resizeAspect +// } + } } /// Player delegate. @@ -181,20 +193,20 @@ open class Player: PlayerViewController { } /// Specifies how the video is displayed within a player layer’s bounds. - /// The default value is `AVLayerVideoGravityResizeAspect`. See `FillMode` enum. - open var fillMode: AVLayerVideoGravity { + /// The default value is `.resizeAspectFit`. See the `FillMode` enum. + open var fillMode: FillMode { get { #if canImport(AppKit) - return AVLayerVideoGravity(rawValue: playerView.videoGravity) + return FillMode(rawValue: playerView.videoGravity)! #else - return playerView.fillMode + return FillMode(rawValue: playerView.fillMode.rawValue)! #endif } set { #if canImport(AppKit) playerView.videoGravity = newValue.rawValue #else - playerView.fillMode = newValue + playerView.fillMode = newValue.avLayerVideoGravityValue #endif } } @@ -323,7 +335,7 @@ open class Player: PlayerViewController { #if canImport(AppKit) /// The player view’s controls style. /// - /// The player view supports a number of different control styles that you can use to customize the player view’s appearance and behavior. See `AVPlayerViewControlsStyle` for the possible values. The default value of this property is `.minimal` + /// The player view supports a number of different control styles that you can use to customize the player view’s appearance and behavior. See `AVPlayerViewControlsStyle` for the possible values. The default value of this property is `.default` open var controlsStyle: AVPlayerViewControlsStyle { get { return playerView.controlsStyle @@ -387,10 +399,11 @@ open class Player: PlayerViewController { private func sharedInit() { avPlayer.actionAtItemEnd = .pause timeObserver = nil + fillMode = .resizeAspectFit #if canImport(AppKit) playerView.player = avPlayer - playerView.controlsStyle = .minimal + playerView.controlsStyle = .default #endif } @@ -410,12 +423,25 @@ open class Player: PlayerViewController { // MARK: - view lifecycle - open override func loadView() { + /// A convenience method for adding a player to the given view controller. + /// The player will be added to `viewController`'s `childViewControllers` array and its view hierarchy. + /// + /// - Parameter viewController: The parent view controller that the player will be added to. + open func add(to viewController: ViewController) { + viewController.addChildViewController(self) + viewController.view.addSubview(view) + #if canImport(UIKit) - playerView.playerLayer.isHidden = true + didMove(toParentViewController: viewController) #endif + } + open override func loadView() { view = playerView + + #if canImport(UIKit) + playerView.playerLayer.isHidden = true + #endif } open override func viewDidLoad() {