Skip to content

Commit

Permalink
[expo-av] Fix fullscreen events not emitted on iOS (expo#9323)
Browse files Browse the repository at this point in the history
* [ncl] Log full-screen events

* [expo-av] Fix fullscreen events not emitted on iOS

* [expo-av] Update changelog
  • Loading branch information
IjzerenHein committed Jul 21, 2020
1 parent 7755091 commit 2355f87
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 9 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
### 🐛 Bug fixes

- Fix audio recording after reload. ([#9283](https://github.com/expo/expo/pull/9283) by [@IjzerenHein](https://github.com/IjzerenHein))
- Fix fullscreen events not emitted on iOS. ([#9323](https://github.com/expo/expo/pull/9323) by [@IjzerenHein](https://github.com/IjzerenHein))

## 8.3.0 — 2020-07-08

Expand Down
2 changes: 1 addition & 1 deletion ios/EXAV/Video/EXVideoView.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#import <EXAV/EXAVObject.h>
#import <EXAV/EXVideoPlayerViewControllerDelegate.h>

@interface EXVideoView : UIView <EXVideoPlayerViewControllerDelegate, EXAVObject>
@interface EXVideoView : UIView <EXVideoPlayerViewControllerDelegate, AVPlayerViewControllerDelegate, EXAVObject>

typedef NS_OPTIONS(NSUInteger, EXVideoFullscreenUpdate)
{
Expand Down
48 changes: 40 additions & 8 deletions ios/EXAV/Video/EXVideoView.m
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ - (EXVideoPlayerViewController *)_createNewPlayerViewController
EXVideoPlayerViewController *controller = [[EXVideoPlayerViewController alloc] init];
[controller setShowsPlaybackControls:_useNativeControls];
[controller setRctDelegate:self];
[controller setDelegate:self];
[controller.view setFrame:self.bounds];
[controller setPlayer:_data.player];
[controller addObserver:self forKeyPath:EXVideoReadyForDisplayKeyPath options:NSKeyValueObservingOptionNew context:nil];
Expand Down Expand Up @@ -199,7 +200,11 @@ - (void)_removePlayerViewController
if (strongSelf && strongSelf.playerViewController) {
[strongSelf.playerViewController.view removeFromSuperview];
[strongSelf.playerViewController removeObserver:strongSelf forKeyPath:EXVideoReadyForDisplayKeyPath];
[strongSelf.playerViewController removeObserver:strongSelf forKeyPath:EXVideoBoundsKeyPath];
if (@available(iOS 12, *)) {
// EXVideoBounds monitoring is only used as a fallback on iOS 11 or lower
} else {
[strongSelf.playerViewController removeObserver:strongSelf forKeyPath:EXVideoBoundsKeyPath];
}
strongSelf.playerViewController = nil;
}
};
Expand Down Expand Up @@ -238,11 +243,12 @@ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(N
@"status": [_data getStatus]});
}
}
} else if (object == _playerViewController && [keyPath isEqualToString:EXVideoBoundsKeyPath]) {

// On iOS 11 or lower, use video-bounds monitoring to detect changes in the full-screen
// mode due to activating native controls
} else if (object == _playerViewController && [keyPath isEqualToString:EXVideoBoundsKeyPath]) {
CGRect viewBounds = [change[@"new"] CGRectValue];
CGRect screen = [[UIScreen mainScreen] bounds];

if (viewBounds.size.height != screen.size.height && viewBounds.size.width != screen.size.width && _fullscreenPlayerPresented && !_fullscreenPlayerViewController) {
// Fullscreen player is being dismissed
_fullscreenPlayerPresented = NO;
Expand Down Expand Up @@ -499,11 +505,15 @@ - (void)setUseNativeControls:(BOOL)useNativeControls
}
if (!strongSelf.playerViewController && strongSelf.data) {
strongSelf.playerViewController = [strongSelf _createNewPlayerViewController];
// We're listening for changes to `videoBounds`, because it seems
// to be the easiest way to detect fullscreen changes triggered by the native video button.
// See https://stackoverflow.com/questions/36323259/detect-video-playing-full-screen-in-portrait-or-landscape/36388184#36388184
// and https://github.com/expo/expo/issues/1566
[strongSelf.playerViewController addObserver:self forKeyPath:EXVideoBoundsKeyPath options:NSKeyValueObservingOptionNew context:nil];
if (@available(iOS 12, *)) {
// On iOS 12 or higher, use the AVPlayerViewControllerDelegate full-screen delegate methods:
// https://stackoverflow.com/a/58809976/3785358
} else {
// On iOS 11 or earlier, fallback to listening for changes to `videoBounds`.
// See https://stackoverflow.com/questions/36323259/detect-video-playing-full-screen-in-portrait-or-landscape/36388184#36388184
// and https://github.com/expo/expo/issues/1566
[strongSelf.playerViewController addObserver:self forKeyPath:EXVideoBoundsKeyPath options:NSKeyValueObservingOptionNew context:nil];
}
// Resize mode must be set before layer is added
// to prevent video from being animated when `resizeMode` is `cover`
[strongSelf _updateNativeResizeMode];
Expand Down Expand Up @@ -636,6 +646,28 @@ - (void)videoPlayerViewControllerDidDismiss:(AVPlayerViewController *)playerView
}
}

#pragma mark - AVVideoPlayerViewControllerDelegate

- (void)playerViewController:(AVPlayerViewController *)playerViewController
willBeginFullScreenPresentationWithAnimationCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
if (playerViewController == _playerViewController) {
_fullscreenPlayerPresented = YES;
[self _callFullscreenCallbackForUpdate:EXVideoFullscreenUpdatePlayerWillPresent];
[self _callFullscreenCallbackForUpdate:EXVideoFullscreenUpdatePlayerDidPresent];
}
}

- (void)playerViewController:(AVPlayerViewController *)playerViewController
willEndFullScreenPresentationWithAnimationCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
if (playerViewController == _playerViewController) {
_fullscreenPlayerPresented = NO;
[self _callFullscreenCallbackForUpdate:EXVideoFullscreenUpdatePlayerWillDismiss];
[self _callFullscreenCallbackForUpdate:EXVideoFullscreenUpdatePlayerDidDismiss];
}
}

#pragma mark - EXAVObject

- (void)pauseImmediately
Expand Down

0 comments on commit 2355f87

Please sign in to comment.