diff --git a/Example/Example Swift/CustomPlayerViewController.swift b/Example/Example Swift/CustomPlayerViewController.swift index f1aafd9..4bbeb99 100644 --- a/Example/Example Swift/CustomPlayerViewController.swift +++ b/Example/Example Swift/CustomPlayerViewController.swift @@ -49,6 +49,7 @@ class CustomPlayerViewController: UIViewController { func setupPictureInPicture() { pipToggleButton.setImage(AVPictureInPictureController.pictureInPictureButtonStartImage(compatibleWith: nil), for: .normal) pipToggleButton.setImage(AVPictureInPictureController.pictureInPictureButtonStopImage(compatibleWith: nil), for: .selected) + pipToggleButton.setImage(AVPictureInPictureController.pictureInPictureButtonStopImage(compatibleWith: nil), for: [.selected, .highlighted]) guard AVPictureInPictureController.isPictureInPictureSupported(), let pictureInPictureController = AVPictureInPictureController(playerLayer: playerView.playerLayer) else { diff --git a/LICENSE b/LICENSE index 5649c36..d5bc162 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2018 ky1vstar +Copyright (c) 2019 ky1vstar Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/Source/Core/PiPPictureInPictureController.m b/Source/Core/PiPPictureInPictureController.m index f570578..9c0a0b2 100644 --- a/Source/Core/PiPPictureInPictureController.m +++ b/Source/Core/PiPPictureInPictureController.m @@ -12,7 +12,6 @@ #import "PiPPlayerViewController.h" #import "PiPManager+Private.h" -static NSString *kPictureInPicturePossible = @"pictureInPicturePossible"; static __weak PiPPictureInPictureController *_currentPictureInPictureController; @interface PiPPictureInPictureController () { @@ -36,6 +35,8 @@ @interface PiPPictureInPictureController () { @implementation PiPPictureInPictureController +#pragma mark - Class methods + + (void)pictureInPictureControllerWillStart:(PiPPictureInPictureController *)pictureInPictureController { if (_currentPictureInPictureController != pictureInPictureController) { [_currentPictureInPictureController stopPictureInPicture]; @@ -50,6 +51,8 @@ + (void)pictureInPictureControllerWillStop:(PiPPictureInPictureController *)pict } } +#pragma mark - Initializers + - (instancetype)initWithPlayerLayer:(AVPlayerLayer *)playerLayer { if (self = [super init]) { _playerLayer = playerLayer; @@ -84,6 +87,8 @@ - (void)dealloc { [self stopPictureInPicture]; } +#pragma mark - AVPictureInPictureController methods + - (void)setDelegate:(id)delegate { _delegate = delegate; @@ -110,12 +115,8 @@ - (void)stopPictureInPicture { [_currentPlayerViewController stop]; } -- (void)updatePossibility { - BOOL newValue = _playerLayerObserver.valid && _allowsPictureInPicturePlayback && PiPManager.pictureInPicturePossible; - - if (newValue != _pictureInPicturePossible) { - self.pictureInPicturePossible = newValue; - } +- (void)stopPictureInPictureEvenWhenInBackground { + [self stopPictureInPicture]; } - (void)setAllowsPictureInPicturePlayback:(BOOL)allowsPictureInPicturePlayback { @@ -124,7 +125,17 @@ - (void)setAllowsPictureInPicturePlayback:(BOOL)allowsPictureInPicturePlayback { [self updatePossibility]; } -#pragma mark - Mimic AVPictureInPictureController +#pragma mark - Possibility + +- (void)updatePossibility { + BOOL newValue = _playerLayerObserver.valid && _allowsPictureInPicturePlayback && PiPManager.pictureInPicturePossible; + + if (newValue != _pictureInPicturePossible) { + self.pictureInPicturePossible = newValue; + } +} + +#pragma mark - Runtime support for non-implemented methods - (BOOL)isKindOfClass:(Class)aClass { if (aClass == AVPictureInPictureController.class) { @@ -156,13 +167,6 @@ - (void)forwardInvocation:(NSInvocation *)anInvocation { [anInvocation invoke]; } -//- (BOOL)pictureInPictureWasStartedWhenEnteringBackground { -// return NO; -//} -// -//- (void)playerLayerLayoutDidChange { -//} - #pragma mark - PiPPlayerViewControllerDelegate - (void)playerViewControllerWillStartPictureInPicture:(PiPPlayerViewController *)playerViewController { diff --git a/Source/Core/PiPPlayerLayerObserver.m b/Source/Core/PiPPlayerLayerObserver.m index fdca63b..2a9a637 100644 --- a/Source/Core/PiPPlayerLayerObserver.m +++ b/Source/Core/PiPPlayerLayerObserver.m @@ -9,6 +9,7 @@ #import "PiPPlayerLayerObserver.h" #import "NSObject+PiPhone.h" +static BOOL kAlwaysReadyForDisplay = NO; static NSString *kPlayerKeyPath = @"player"; static NSString *kCurrentItemKeyPath = @"player.currentItem"; static NSString *kReadyForDisplayKeyPath = @"readyForDisplay"; @@ -33,6 +34,15 @@ @interface PiPPlayerLayerObserver () @implementation PiPPlayerLayerObserver ++ (void)initialize { + // AVQueuePlayer is broken on iOS 9. After currentItem being changed AVPlayerLayer's readyForDisplay will always remain NO; + if (@available(iOS 10.0, *)) { + kAlwaysReadyForDisplay = NO; + } else { + kAlwaysReadyForDisplay = YES; + } +} + - (instancetype)initWithPlayerLayer:(AVPlayerLayer *)playerLayer { if (self = [super init]) { _delegates = [NSHashTable weakObjectsHashTable]; @@ -63,7 +73,7 @@ - (void)setupObservations { [self addObserversForPlayer:_player]; _currentPlayerItem = _player.currentItem; - _readyForDisplay = _playerLayer.readyForDisplay; + _readyForDisplay = _playerLayer.readyForDisplay || kAlwaysReadyForDisplay; _playerItemStatus = playerItem.status; _presentationSize = playerItem.presentationSize; _playing = _player.rate > 0; @@ -139,7 +149,7 @@ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(N } else if ([keyPath isEqualToString:kReadyForDisplayKeyPath]) { NSNumber *number = [change[NSKeyValueChangeNewKey] ifNullThenNil]; - _readyForDisplay = number.boolValue; + _readyForDisplay = number.boolValue || kAlwaysReadyForDisplay; [self updateValidity]; [self updateInitializing];