Add cache property; Make playerItemForSource in 'RCTVideoManager.m' async

This commit is contained in:
Laurin Quast 2018-02-28 17:42:49 +01:00
parent 6b2c1046dd
commit 438aa79494
3 changed files with 283 additions and 266 deletions

View File

@ -247,6 +247,7 @@ export default class Video extends Component {
Video.propTypes = { Video.propTypes = {
/* Native only */ /* Native only */
src: PropTypes.object, src: PropTypes.object,
cache: PropTypes.bool,
seek: PropTypes.number, seek: PropTypes.number,
fullscreen: PropTypes.bool, fullscreen: PropTypes.bool,
onVideoLoadStart: PropTypes.func, onVideoLoadStart: PropTypes.func,

View File

@ -89,13 +89,13 @@ static NSString *const timedMetadata = @"timedMetadata";
} }
- (AVPlayerViewController*)createPlayerViewController:(AVPlayer*)player withPlayerItem:(AVPlayerItem*)playerItem { - (AVPlayerViewController*)createPlayerViewController:(AVPlayer*)player withPlayerItem:(AVPlayerItem*)playerItem {
RCTVideoPlayerViewController* playerLayer= [[RCTVideoPlayerViewController alloc] init]; RCTVideoPlayerViewController* playerLayer= [[RCTVideoPlayerViewController alloc] init];
playerLayer.showsPlaybackControls = NO; playerLayer.showsPlaybackControls = NO;
playerLayer.rctDelegate = self; playerLayer.rctDelegate = self;
playerLayer.view.frame = self.bounds; playerLayer.view.frame = self.bounds;
playerLayer.player = _player; playerLayer.player = _player;
playerLayer.view.frame = self.bounds; playerLayer.view.frame = self.bounds;
return playerLayer; return playerLayer;
} }
/* --------------------------------------------------------- /* ---------------------------------------------------------
@ -104,35 +104,35 @@ static NSString *const timedMetadata = @"timedMetadata";
- (CMTime)playerItemDuration - (CMTime)playerItemDuration
{ {
AVPlayerItem *playerItem = [_player currentItem]; AVPlayerItem *playerItem = [_player currentItem];
if (playerItem.status == AVPlayerItemStatusReadyToPlay) if (playerItem.status == AVPlayerItemStatusReadyToPlay)
{ {
return([playerItem duration]); return([playerItem duration]);
} }
return(kCMTimeInvalid); return(kCMTimeInvalid);
} }
- (CMTimeRange)playerItemSeekableTimeRange - (CMTimeRange)playerItemSeekableTimeRange
{ {
AVPlayerItem *playerItem = [_player currentItem]; AVPlayerItem *playerItem = [_player currentItem];
if (playerItem.status == AVPlayerItemStatusReadyToPlay) if (playerItem.status == AVPlayerItemStatusReadyToPlay)
{ {
return [playerItem seekableTimeRanges].firstObject.CMTimeRangeValue; return [playerItem seekableTimeRanges].firstObject.CMTimeRangeValue;
} }
return (kCMTimeRangeZero); return (kCMTimeRangeZero);
} }
/* Cancels the previously registered time observer. */ /* Cancels the previously registered time observer. */
-(void)removePlayerTimeObserver -(void)removePlayerTimeObserver
{ {
if (_timeObserver) if (_timeObserver)
{ {
[_player removeTimeObserver:_timeObserver]; [_player removeTimeObserver:_timeObserver];
_timeObserver = nil; _timeObserver = nil;
} }
} }
#pragma mark - Progress #pragma mark - Progress
@ -175,32 +175,32 @@ static NSString *const timedMetadata = @"timedMetadata";
- (void)sendProgressUpdate - (void)sendProgressUpdate
{ {
AVPlayerItem *video = [_player currentItem]; AVPlayerItem *video = [_player currentItem];
if (video == nil || video.status != AVPlayerItemStatusReadyToPlay) { if (video == nil || video.status != AVPlayerItemStatusReadyToPlay) {
return; return;
} }
CMTime playerDuration = [self playerItemDuration]; CMTime playerDuration = [self playerItemDuration];
if (CMTIME_IS_INVALID(playerDuration)) { if (CMTIME_IS_INVALID(playerDuration)) {
return; return;
} }
CMTime currentTime = _player.currentTime; CMTime currentTime = _player.currentTime;
const Float64 duration = CMTimeGetSeconds(playerDuration); const Float64 duration = CMTimeGetSeconds(playerDuration);
const Float64 currentTimeSecs = CMTimeGetSeconds(currentTime); const Float64 currentTimeSecs = CMTimeGetSeconds(currentTime);
[[NSNotificationCenter defaultCenter] postNotificationName:@"RCTVideo_progress" object:nil userInfo:@{@"progress": [NSNumber numberWithDouble: currentTimeSecs / duration]}]; [[NSNotificationCenter defaultCenter] postNotificationName:@"RCTVideo_progress" object:nil userInfo:@{@"progress": [NSNumber numberWithDouble: currentTimeSecs / duration]}];
if( currentTimeSecs >= 0 && self.onVideoProgress) { if( currentTimeSecs >= 0 && self.onVideoProgress) {
self.onVideoProgress(@{ self.onVideoProgress(@{
@"currentTime": [NSNumber numberWithFloat:CMTimeGetSeconds(currentTime)], @"currentTime": [NSNumber numberWithFloat:CMTimeGetSeconds(currentTime)],
@"playableDuration": [self calculatePlayableDuration], @"playableDuration": [self calculatePlayableDuration],
@"atValue": [NSNumber numberWithLongLong:currentTime.value], @"atValue": [NSNumber numberWithLongLong:currentTime.value],
@"atTimescale": [NSNumber numberWithInt:currentTime.timescale], @"atTimescale": [NSNumber numberWithInt:currentTime.timescale],
@"target": self.reactTag, @"target": self.reactTag,
@"seekableDuration": [self calculateSeekableDuration], @"seekableDuration": [self calculateSeekableDuration],
}); });
} }
} }
/*! /*!
@ -230,12 +230,12 @@ static NSString *const timedMetadata = @"timedMetadata";
- (NSNumber *)calculateSeekableDuration - (NSNumber *)calculateSeekableDuration
{ {
CMTimeRange timeRange = [self playerItemSeekableTimeRange]; CMTimeRange timeRange = [self playerItemSeekableTimeRange];
if (CMTIME_IS_NUMERIC(timeRange.duration)) if (CMTIME_IS_NUMERIC(timeRange.duration))
{ {
return [NSNumber numberWithFloat:CMTimeGetSeconds(timeRange.duration)]; return [NSNumber numberWithFloat:CMTimeGetSeconds(timeRange.duration)];
} }
return [NSNumber numberWithInteger:0]; return [NSNumber numberWithInteger:0];
} }
- (void)addPlayerItemObservers - (void)addPlayerItemObservers
@ -266,11 +266,23 @@ static NSString *const timedMetadata = @"timedMetadata";
#pragma mark - Player and source #pragma mark - Player and source
- (void)setCache:(BOOL *)cache
{
// @TODO: Implement
}
- (void)setSrc:(NSDictionary *)source - (void)setSrc:(NSDictionary *)source
{ {
[self removePlayerTimeObserver]; [self removePlayerTimeObserver];
[self removePlayerItemObservers]; [self removePlayerItemObservers];
_playerItem = [self playerItemForSource:source]; [self playerItemForSource:source withCallback:^(AVPlayerItem * playerItem) {
[self didSetPlayerItemWithSource:source playerItem:playerItem];
}];
}
- (void) didSetPlayerItemWithSource:(NSDictionary *)source playerItem:(AVPlayerItem *) playerItem
{
_playerItem = playerItem;
[self addPlayerItemObservers]; [self addPlayerItemObservers];
[_player pause]; [_player pause];
@ -303,16 +315,16 @@ static NSString *const timedMetadata = @"timedMetadata";
id uri = [source objectForKey:@"uri"]; id uri = [source objectForKey:@"uri"];
id type = [source objectForKey:@"type"]; id type = [source objectForKey:@"type"];
self.onVideoLoadStart(@{@"src": @{ self.onVideoLoadStart(@{@"src": @{
@"uri": uri ? uri : [NSNull null], @"uri": uri ? uri : [NSNull null],
@"type": type ? type : [NSNull null], @"type": type ? type : [NSNull null],
@"isNetwork": [NSNumber numberWithBool:(bool)[source objectForKey:@"isNetwork"]]}, @"isNetwork": [NSNumber numberWithBool:(bool)[source objectForKey:@"isNetwork"]]},
@"target": self.reactTag @"target": self.reactTag
}); });
} }
}); });
} }
- (AVPlayerItem*)playerItemForSource:(NSDictionary *)source - (void)playerItemForSource:(NSDictionary *)source withCallback:(void(^)(AVPlayerItem *))handler
{ {
bool isNetwork = [RCTConvert BOOL:[source objectForKey:@"isNetwork"]]; bool isNetwork = [RCTConvert BOOL:[source objectForKey:@"isNetwork"]];
bool isAsset = [RCTConvert BOOL:[source objectForKey:@"isAsset"]]; bool isAsset = [RCTConvert BOOL:[source objectForKey:@"isAsset"]];
@ -320,52 +332,55 @@ static NSString *const timedMetadata = @"timedMetadata";
NSString *type = [source objectForKey:@"type"]; NSString *type = [source objectForKey:@"type"];
NSURL *url = (isNetwork || isAsset) ? NSURL *url = (isNetwork || isAsset) ?
[NSURL URLWithString:uri] : [NSURL URLWithString:uri] :
[[NSURL alloc] initFileURLWithPath:[[NSBundle mainBundle] pathForResource:uri ofType:type]]; [[NSURL alloc] initFileURLWithPath:[[NSBundle mainBundle] pathForResource:uri ofType:type]];
if (isNetwork) { if (isNetwork) {
// @TODO: Check if item is cached an if so use the cached asset
NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies]; NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies];
AVURLAsset *asset = [AVURLAsset URLAssetWithURL:url options:@{AVURLAssetHTTPCookiesKey : cookies}]; AVURLAsset *asset = [AVURLAsset URLAssetWithURL:url options:@{AVURLAssetHTTPCookiesKey : cookies}];
return [AVPlayerItem playerItemWithAsset:asset]; handler([AVPlayerItem playerItemWithAsset:asset]);
return;
} }
else if (isAsset) { else if (isAsset) {
AVURLAsset *asset = [AVURLAsset URLAssetWithURL:url options:nil]; AVURLAsset *asset = [AVURLAsset URLAssetWithURL:url options:nil];
return [AVPlayerItem playerItemWithAsset:asset]; handler([AVPlayerItem playerItemWithAsset:asset]);
return;
} }
handler([AVPlayerItem playerItemWithURL:url]);
return [AVPlayerItem playerItemWithURL:url]; return;
} }
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{ {
if (object == _playerItem) { if (object == _playerItem) {
// When timeMetadata is read the event onTimedMetadata is triggered // When timeMetadata is read the event onTimedMetadata is triggered
if ([keyPath isEqualToString: timedMetadata]) if ([keyPath isEqualToString: timedMetadata])
{ {
NSArray<AVMetadataItem *> *items = [change objectForKey:@"new"]; NSArray<AVMetadataItem *> *items = [change objectForKey:@"new"];
if (items && ![items isEqual:[NSNull null]] && items.count > 0) { if (items && ![items isEqual:[NSNull null]] && items.count > 0) {
NSMutableArray *array = [NSMutableArray new]; NSMutableArray *array = [NSMutableArray new];
for (AVMetadataItem *item in items) { for (AVMetadataItem *item in items) {
NSString *value = item.value; NSString *value = item.value;
NSString *identifier = item.identifier; NSString *identifier = item.identifier;
if (![value isEqual: [NSNull null]]) { if (![value isEqual: [NSNull null]]) {
NSDictionary *dictionary = [[NSDictionary alloc] initWithObjects:@[value, identifier] forKeys:@[@"value", @"identifier"]]; NSDictionary *dictionary = [[NSDictionary alloc] initWithObjects:@[value, identifier] forKeys:@[@"value", @"identifier"]];
[array addObject:dictionary]; [array addObject:dictionary];
} }
}
self.onTimedMetadata(@{
@"target": self.reactTag,
@"metadata": array
});
} }
self.onTimedMetadata(@{
@"target": self.reactTag,
@"metadata": array
});
}
} }
if ([keyPath isEqualToString:statusKeyPath]) { if ([keyPath isEqualToString:statusKeyPath]) {
@ -388,15 +403,15 @@ static NSString *const timedMetadata = @"timedMetadata";
CGAffineTransform preferredTransform = [videoTrack preferredTransform]; CGAffineTransform preferredTransform = [videoTrack preferredTransform];
if ((videoTrack.naturalSize.width == preferredTransform.tx if ((videoTrack.naturalSize.width == preferredTransform.tx
&& videoTrack.naturalSize.height == preferredTransform.ty) && videoTrack.naturalSize.height == preferredTransform.ty)
|| (preferredTransform.tx == 0 && preferredTransform.ty == 0)) || (preferredTransform.tx == 0 && preferredTransform.ty == 0))
{ {
orientation = @"landscape"; orientation = @"landscape";
} else } else
orientation = @"portrait"; orientation = @"portrait";
} }
if(self.onVideoLoad) { if(self.onVideoLoad) {
self.onVideoLoad(@{@"duration": [NSNumber numberWithFloat:duration], self.onVideoLoad(@{@"duration": [NSNumber numberWithFloat:duration],
@"currentTime": [NSNumber numberWithFloat:CMTimeGetSeconds(_playerItem.currentTime)], @"currentTime": [NSNumber numberWithFloat:CMTimeGetSeconds(_playerItem.currentTime)],
@"canPlayReverse": [NSNumber numberWithBool:_playerItem.canPlayReverse], @"canPlayReverse": [NSNumber numberWithBool:_playerItem.canPlayReverse],
@ -406,12 +421,12 @@ static NSString *const timedMetadata = @"timedMetadata";
@"canStepBackward": [NSNumber numberWithBool:_playerItem.canStepBackward], @"canStepBackward": [NSNumber numberWithBool:_playerItem.canStepBackward],
@"canStepForward": [NSNumber numberWithBool:_playerItem.canStepForward], @"canStepForward": [NSNumber numberWithBool:_playerItem.canStepForward],
@"naturalSize": @{ @"naturalSize": @{
@"width": width, @"width": width,
@"height": height, @"height": height,
@"orientation": orientation @"orientation": orientation
}, },
@"target": self.reactTag}); @"target": self.reactTag});
} }
[self attachListeners]; [self attachListeners];
@ -419,7 +434,7 @@ static NSString *const timedMetadata = @"timedMetadata";
} else if(_playerItem.status == AVPlayerItemStatusFailed && self.onVideoError) { } else if(_playerItem.status == AVPlayerItemStatusFailed && self.onVideoError) {
self.onVideoError(@{@"error": @{@"code": [NSNumber numberWithInteger: _playerItem.error.code], self.onVideoError(@{@"error": @{@"code": [NSNumber numberWithInteger: _playerItem.error.code],
@"domain": _playerItem.error.domain}, @"domain": _playerItem.error.domain},
@"target": self.reactTag}); @"target": self.reactTag});
} }
} else if ([keyPath isEqualToString:playbackBufferEmptyKeyPath]) { } else if ([keyPath isEqualToString:playbackBufferEmptyKeyPath]) {
_playerBufferEmpty = YES; _playerBufferEmpty = YES;
@ -432,28 +447,28 @@ static NSString *const timedMetadata = @"timedMetadata";
_playerBufferEmpty = NO; _playerBufferEmpty = NO;
self.onVideoBuffer(@{@"isBuffering": @(NO), @"target": self.reactTag}); self.onVideoBuffer(@{@"isBuffering": @(NO), @"target": self.reactTag});
} }
} else if (object == _playerLayer) { } else if (object == _playerLayer) {
if([keyPath isEqualToString:readyForDisplayKeyPath] && [change objectForKey:NSKeyValueChangeNewKey]) { if([keyPath isEqualToString:readyForDisplayKeyPath] && [change objectForKey:NSKeyValueChangeNewKey]) {
if([change objectForKey:NSKeyValueChangeNewKey] && self.onReadyForDisplay) { if([change objectForKey:NSKeyValueChangeNewKey] && self.onReadyForDisplay) {
self.onReadyForDisplay(@{@"target": self.reactTag}); self.onReadyForDisplay(@{@"target": self.reactTag});
} }
} }
} else if (object == _player) { } else if (object == _player) {
if([keyPath isEqualToString:playbackRate]) { if([keyPath isEqualToString:playbackRate]) {
if(self.onPlaybackRateChange) { if(self.onPlaybackRateChange) {
self.onPlaybackRateChange(@{@"playbackRate": [NSNumber numberWithFloat:_player.rate], self.onPlaybackRateChange(@{@"playbackRate": [NSNumber numberWithFloat:_player.rate],
@"target": self.reactTag}); @"target": self.reactTag});
}
if(_playbackStalled && _player.rate > 0) {
if(self.onPlaybackResume) {
self.onPlaybackResume(@{@"playbackRate": [NSNumber numberWithFloat:_player.rate],
@"target": self.reactTag});
}
_playbackStalled = NO;
}
} }
if(_playbackStalled && _player.rate > 0) {
if(self.onPlaybackResume) {
self.onPlaybackResume(@{@"playbackRate": [NSNumber numberWithFloat:_player.rate],
@"target": self.reactTag});
}
_playbackStalled = NO;
}
}
} else { } else {
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
} }
} }
@ -481,7 +496,7 @@ static NSString *const timedMetadata = @"timedMetadata";
- (void)playerItemDidReachEnd:(NSNotification *)notification - (void)playerItemDidReachEnd:(NSNotification *)notification
{ {
if(self.onVideoEnd) { if(self.onVideoEnd) {
self.onVideoEnd(@{@"target": self.reactTag}); self.onVideoEnd(@{@"target": self.reactTag});
} }
if (_repeat) { if (_repeat) {
@ -569,9 +584,9 @@ static NSString *const timedMetadata = @"timedMetadata";
[_player seekToTime:cmSeekTime toleranceBefore:tolerance toleranceAfter:tolerance completionHandler:^(BOOL finished) { [_player seekToTime:cmSeekTime toleranceBefore:tolerance toleranceAfter:tolerance completionHandler:^(BOOL finished) {
if (!wasPaused) [_player play]; if (!wasPaused) [_player play];
if(self.onVideoSeek) { if(self.onVideoSeek) {
self.onVideoSeek(@{@"currentTime": [NSNumber numberWithFloat:CMTimeGetSeconds(item.currentTime)], self.onVideoSeek(@{@"currentTime": [NSNumber numberWithFloat:CMTimeGetSeconds(item.currentTime)],
@"seekTime": [NSNumber numberWithFloat:seekTime], @"seekTime": [NSNumber numberWithFloat:seekTime],
@"target": self.reactTag}); @"target": self.reactTag});
} }
}]; }];
@ -625,103 +640,103 @@ static NSString *const timedMetadata = @"timedMetadata";
- (BOOL)getFullscreen - (BOOL)getFullscreen
{ {
return _fullscreenPlayerPresented; return _fullscreenPlayerPresented;
} }
- (void)setFullscreen:(BOOL)fullscreen - (void)setFullscreen:(BOOL)fullscreen
{ {
if( fullscreen && !_fullscreenPlayerPresented ) if( fullscreen && !_fullscreenPlayerPresented )
{
// Ensure player view controller is not null
if( !_playerViewController )
{ {
// Ensure player view controller is not null [self usePlayerViewController];
if( !_playerViewController ) }
{ // Set presentation style to fullscreen
[self usePlayerViewController]; [_playerViewController setModalPresentationStyle:UIModalPresentationFullScreen];
}
// Set presentation style to fullscreen
[_playerViewController setModalPresentationStyle:UIModalPresentationFullScreen];
// Find the nearest view controller // Find the nearest view controller
UIViewController *viewController = [self firstAvailableUIViewController]; UIViewController *viewController = [self firstAvailableUIViewController];
if( !viewController ) if( !viewController )
{
UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow];
viewController = keyWindow.rootViewController;
if( viewController.childViewControllers.count > 0 )
{
viewController = viewController.childViewControllers.lastObject;
}
}
if( viewController )
{
_presentingViewController = viewController;
if(self.onVideoFullscreenPlayerWillPresent) {
self.onVideoFullscreenPlayerWillPresent(@{@"target": self.reactTag});
}
[viewController presentViewController:_playerViewController animated:true completion:^{
_playerViewController.showsPlaybackControls = YES;
_fullscreenPlayerPresented = fullscreen;
if(self.onVideoFullscreenPlayerDidPresent) {
self.onVideoFullscreenPlayerDidPresent(@{@"target": self.reactTag});
}
}];
}
}
else if ( !fullscreen && _fullscreenPlayerPresented )
{ {
[self videoPlayerViewControllerWillDismiss:_playerViewController]; UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow];
[_presentingViewController dismissViewControllerAnimated:true completion:^{ viewController = keyWindow.rootViewController;
[self videoPlayerViewControllerDidDismiss:_playerViewController]; if( viewController.childViewControllers.count > 0 )
}]; {
viewController = viewController.childViewControllers.lastObject;
}
} }
if( viewController )
{
_presentingViewController = viewController;
if(self.onVideoFullscreenPlayerWillPresent) {
self.onVideoFullscreenPlayerWillPresent(@{@"target": self.reactTag});
}
[viewController presentViewController:_playerViewController animated:true completion:^{
_playerViewController.showsPlaybackControls = YES;
_fullscreenPlayerPresented = fullscreen;
if(self.onVideoFullscreenPlayerDidPresent) {
self.onVideoFullscreenPlayerDidPresent(@{@"target": self.reactTag});
}
}];
}
}
else if ( !fullscreen && _fullscreenPlayerPresented )
{
[self videoPlayerViewControllerWillDismiss:_playerViewController];
[_presentingViewController dismissViewControllerAnimated:true completion:^{
[self videoPlayerViewControllerDidDismiss:_playerViewController];
}];
}
} }
- (void)usePlayerViewController - (void)usePlayerViewController
{ {
if( _player ) if( _player )
{ {
_playerViewController = [self createPlayerViewController:_player withPlayerItem:_playerItem]; _playerViewController = [self createPlayerViewController:_player withPlayerItem:_playerItem];
// to prevent video from being animated when resizeMode is 'cover' // to prevent video from being animated when resizeMode is 'cover'
// resize mode must be set before subview is added // resize mode must be set before subview is added
[self setResizeMode:_resizeMode]; [self setResizeMode:_resizeMode];
[self addSubview:_playerViewController.view]; [self addSubview:_playerViewController.view];
} }
} }
- (void)usePlayerLayer - (void)usePlayerLayer
{ {
if( _player ) if( _player )
{ {
_playerLayer = [AVPlayerLayer playerLayerWithPlayer:_player]; _playerLayer = [AVPlayerLayer playerLayerWithPlayer:_player];
_playerLayer.frame = self.bounds; _playerLayer.frame = self.bounds;
_playerLayer.needsDisplayOnBoundsChange = YES; _playerLayer.needsDisplayOnBoundsChange = YES;
// to prevent video from being animated when resizeMode is 'cover' // to prevent video from being animated when resizeMode is 'cover'
// resize mode must be set before layer is added // resize mode must be set before layer is added
[self setResizeMode:_resizeMode]; [self setResizeMode:_resizeMode];
[_playerLayer addObserver:self forKeyPath:readyForDisplayKeyPath options:NSKeyValueObservingOptionNew context:nil]; [_playerLayer addObserver:self forKeyPath:readyForDisplayKeyPath options:NSKeyValueObservingOptionNew context:nil];
[self.layer addSublayer:_playerLayer]; [self.layer addSublayer:_playerLayer];
self.layer.needsDisplayOnBoundsChange = YES; self.layer.needsDisplayOnBoundsChange = YES;
} }
} }
- (void)setControls:(BOOL)controls - (void)setControls:(BOOL)controls
{ {
if( _controls != controls || (!_playerLayer && !_playerViewController) ) if( _controls != controls || (!_playerLayer && !_playerViewController) )
{
_controls = controls;
if( _controls )
{ {
_controls = controls; [self removePlayerLayer];
if( _controls ) [self usePlayerViewController];
{
[self removePlayerLayer];
[self usePlayerViewController];
}
else
{
[_playerViewController.view removeFromSuperview];
_playerViewController = nil;
[self usePlayerLayer];
}
} }
else
{
[_playerViewController.view removeFromSuperview];
_playerViewController = nil;
[self usePlayerLayer];
}
}
} }
- (void)setProgressUpdateInterval:(float)progressUpdateInterval - (void)setProgressUpdateInterval:(float)progressUpdateInterval
@ -731,33 +746,33 @@ static NSString *const timedMetadata = @"timedMetadata";
- (void)removePlayerLayer - (void)removePlayerLayer
{ {
[_playerLayer removeFromSuperlayer]; [_playerLayer removeFromSuperlayer];
[_playerLayer removeObserver:self forKeyPath:readyForDisplayKeyPath]; [_playerLayer removeObserver:self forKeyPath:readyForDisplayKeyPath];
_playerLayer = nil; _playerLayer = nil;
} }
#pragma mark - RCTVideoPlayerViewControllerDelegate #pragma mark - RCTVideoPlayerViewControllerDelegate
- (void)videoPlayerViewControllerWillDismiss:(AVPlayerViewController *)playerViewController - (void)videoPlayerViewControllerWillDismiss:(AVPlayerViewController *)playerViewController
{ {
if (_playerViewController == playerViewController && _fullscreenPlayerPresented && self.onVideoFullscreenPlayerWillDismiss) if (_playerViewController == playerViewController && _fullscreenPlayerPresented && self.onVideoFullscreenPlayerWillDismiss)
{ {
self.onVideoFullscreenPlayerWillDismiss(@{@"target": self.reactTag}); self.onVideoFullscreenPlayerWillDismiss(@{@"target": self.reactTag});
} }
} }
- (void)videoPlayerViewControllerDidDismiss:(AVPlayerViewController *)playerViewController - (void)videoPlayerViewControllerDidDismiss:(AVPlayerViewController *)playerViewController
{ {
if (_playerViewController == playerViewController && _fullscreenPlayerPresented) if (_playerViewController == playerViewController && _fullscreenPlayerPresented)
{ {
_fullscreenPlayerPresented = false; _fullscreenPlayerPresented = false;
_presentingViewController = nil; _presentingViewController = nil;
_playerViewController = nil; _playerViewController = nil;
[self applyModifiers]; [self applyModifiers];
if(self.onVideoFullscreenPlayerDidDismiss) { if(self.onVideoFullscreenPlayerDidDismiss) {
self.onVideoFullscreenPlayerDidDismiss(@{@"target": self.reactTag}); self.onVideoFullscreenPlayerDidDismiss(@{@"target": self.reactTag});
}
} }
}
} }
#pragma mark - React View Management #pragma mark - React View Management
@ -773,12 +788,12 @@ static NSString *const timedMetadata = @"timedMetadata";
if( _controls ) if( _controls )
{ {
view.frame = self.bounds; view.frame = self.bounds;
[_playerViewController.contentOverlayView insertSubview:view atIndex:atIndex]; [_playerViewController.contentOverlayView insertSubview:view atIndex:atIndex];
} }
else else
{ {
RCTLogError(@"video cannot have any subviews"); RCTLogError(@"video cannot have any subviews");
} }
return; return;
} }
@ -787,7 +802,7 @@ static NSString *const timedMetadata = @"timedMetadata";
{ {
if( _controls ) if( _controls )
{ {
[subview removeFromSuperview]; [subview removeFromSuperview];
} }
else else
{ {
@ -810,10 +825,10 @@ static NSString *const timedMetadata = @"timedMetadata";
} }
else else
{ {
[CATransaction begin]; [CATransaction begin];
[CATransaction setAnimationDuration:0]; [CATransaction setAnimationDuration:0];
_playerLayer.frame = self.bounds; _playerLayer.frame = self.bounds;
[CATransaction commit]; [CATransaction commit];
} }
} }

View File

@ -20,6 +20,7 @@ RCT_EXPORT_MODULE();
} }
RCT_EXPORT_VIEW_PROPERTY(src, NSDictionary); RCT_EXPORT_VIEW_PROPERTY(src, NSDictionary);
RCT_EXPORT_VIEW_PROPERTY(cache, BOOL);
RCT_EXPORT_VIEW_PROPERTY(resizeMode, NSString); RCT_EXPORT_VIEW_PROPERTY(resizeMode, NSString);
RCT_EXPORT_VIEW_PROPERTY(repeat, BOOL); RCT_EXPORT_VIEW_PROPERTY(repeat, BOOL);
RCT_EXPORT_VIEW_PROPERTY(paused, BOOL); RCT_EXPORT_VIEW_PROPERTY(paused, BOOL);