Skip to content

Commit

Permalink
[expo-av] Fix instability issues when changing source and useNativeCo…
Browse files Browse the repository at this point in the history
…ntrols (expo#9381)

* [ncl] Add multiple sources switching for video-player

* [expo-av] Fix stability issues when changing source & useNativeControls

* [test] Add video tests for changing source & useNativeControls

* [expo-av] Update changelog
  • Loading branch information
IjzerenHein authored Jul 24, 2020
1 parent 3ffff88 commit 58d5aae
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 32 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
- Fix duplicate full-screen will-dismiss event on iOS. ([#9366](https://github.com/expo/expo/pull/9366) by [@IjzerenHein](https://github.com/IjzerenHein))
- De-activate audio-session after unloading sound. ([#9365](https://github.com/expo/expo/pull/9365) by [@IjzerenHein](https://github.com/IjzerenHein))
- Fix resume audio when in background. ([#9363](https://github.com/expo/expo/pull/9363) by [@IjzerenHein](https://github.com/IjzerenHein))
- Fix instability issues when changing source and useNativeControls. ([#9381](https://github.com/expo/expo/pull/9381) by [@IjzerenHein](https://github.com/IjzerenHein))

## 8.3.0 — 2020-07-08

Expand Down
77 changes: 45 additions & 32 deletions ios/EXAV/Video/EXVideoView.m
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,16 @@ - (void)_updateForNewPlayer
}
}

- (void)_removeData
{
if (_data) {
[_data pauseImmediately];
[_data setStatusUpdateCallback:nil];
[_exAV demoteAudioSessionIfPossible];
_data = nil;
}
}

- (void)_removePlayer
{
if (_requestedFullscreenChangeRejecter) {
Expand All @@ -129,15 +139,19 @@ - (void)_removePlayer
_requestedFullscreenChange = NO;
}

if (_data) {
[_data pauseImmediately];
[_data setStatusUpdateCallback:nil];
[_exAV demoteAudioSessionIfPossible];
[self _removeFullscreenPlayerViewController];
[self _removePlayerLayer];
[self _removePlayerViewController];
_data = nil;
}
// Any ViewController/layer updates need to be
// executed on the main UI thread.
__weak EXVideoView *weakSelf = self;
void (^block)(void) = ^ {
__strong EXVideoView *strongSelf = weakSelf;
if (strongSelf) {
[strongSelf _removeFullscreenPlayerViewController];
[strongSelf _removePlayerLayer];
[strongSelf _removePlayerViewController];
}
};
_playerHasLoaded = NO;
[UMUtilities performSynchronouslyOnMainThread:block];
}

#pragma mark - _playerViewController / _playerLayer management
Expand Down Expand Up @@ -194,22 +208,14 @@ - (void)_removeFullscreenPlayerViewController
- (void)_removePlayerViewController
{
if (_playerViewController) {
__weak EXVideoView *weakSelf = self;
void (^block)(void) = ^ {
__strong EXVideoView *strongSelf = weakSelf;
if (strongSelf && strongSelf.playerViewController) {
[strongSelf.playerViewController.view removeFromSuperview];
[strongSelf.playerViewController removeObserver:strongSelf forKeyPath:EXVideoReadyForDisplayKeyPath];
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;
}
};

[UMUtilities performSynchronouslyOnMainThread:block];
[_playerViewController.view removeFromSuperview];
[_playerViewController removeObserver:self forKeyPath:EXVideoReadyForDisplayKeyPath];
if (@available(iOS 12, *)) {
// EXVideoBounds monitoring is only used as a fallback on iOS 11 or lower
} else {
[_playerViewController removeObserver:self forKeyPath:EXVideoBoundsKeyPath];
}
_playerViewController = nil;
}
}

Expand Down Expand Up @@ -276,8 +282,10 @@ - (void)setSource:(NSDictionary *)source
{
if (_data) {
[_statusToSet addEntriesFromDictionary:[_data getStatus]];
[self _removePlayer];
[self _removeData];
}

[self _removePlayer];

if (initialStatus) {
[_statusToSet addEntriesFromDictionary:initialStatus];
Expand Down Expand Up @@ -305,6 +313,7 @@ - (void)setSource:(NSDictionary *)source
void (^errorCallback)(NSString *) = ^(NSString *error) {
__strong EXVideoView *strongSelf = weakSelf;
if (strongSelf) {
[strongSelf _removeData];
[strongSelf _removePlayer];
[strongSelf _callErrorCallback:error];
}
Expand All @@ -321,6 +330,7 @@ - (void)setSource:(NSDictionary *)source
resolve(successStatus);
}
} else if (strongSelf) {
[strongSelf _removeData];
[strongSelf _removePlayer];
if (reject) {
reject(@"E_VIDEO_NOTCREATED", error, UMErrorWithMessage(error));
Expand Down Expand Up @@ -474,8 +484,8 @@ - (void)setSource:(NSDictionary *)source
dispatch_async(_exAV.methodQueue, ^{
__strong EXVideoView *strongSelf = weakSelf;
if (strongSelf) {
[strongSelf setSource:source withStatus:nil resolver:nil rejecter:nil];
strongSelf.lastSetSource = source;
[strongSelf setSource:source withStatus:nil resolver:nil rejecter:nil];
}
});
}
Expand All @@ -492,14 +502,17 @@ - (NSDictionary *)source
- (void)setUseNativeControls:(BOOL)useNativeControls
{
_useNativeControls = useNativeControls;
if (_data == nil) {
if (!_playerHasLoaded) {
return;
}

__weak EXVideoView *weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
__strong EXVideoView *strongSelf = weakSelf;
if (strongSelf && strongSelf.useNativeControls) {
if (!strongSelf || !strongSelf.playerHasLoaded) {
return;
}
if (strongSelf.useNativeControls) {
if (strongSelf.playerLayer) {
[strongSelf _removePlayerLayer];
}
Expand All @@ -519,7 +532,7 @@ - (void)setUseNativeControls:(BOOL)useNativeControls
[strongSelf _updateNativeResizeMode];
[strongSelf addSubview:strongSelf.playerViewController.view];
}
} else if (strongSelf) {
} else {
if (strongSelf.playerViewController) {
[strongSelf _removePlayerViewController];
}
Expand Down Expand Up @@ -619,6 +632,7 @@ - (void)layoutSubviews

- (void)removeFromSuperview
{
[self _removeData];
[self _removePlayer];
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super removeFromSuperview];
Expand Down Expand Up @@ -709,8 +723,7 @@ - (void)handleMediaServicesReset:(void (^)(void))finishCallback
if (_onLoadStart) {
_onLoadStart(nil);
}
[self _removePlayerLayer];
[self _removePlayerViewController];
[self _removePlayer];

__weak __typeof__(self) weakSelf = self;
[_data handleMediaServicesReset:^{
Expand Down

0 comments on commit 58d5aae

Please sign in to comment.