- timer only starts when the video plays and is stopped when video is paused

- renamed event constants
This commit is contained in:
Johannes Lumpe 2015-04-08 18:46:13 +03:00 committed by Brent Vatne
parent 00455ba1fb
commit e9e48bb666

View File

@ -36,16 +36,12 @@ static NSString *const statusKeyPath = @"status";
- (instancetype)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher { - (instancetype)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher {
if ((self = [super init])) { if ((self = [super init])) {
_eventDispatcher = eventDispatcher; _eventDispatcher = eventDispatcher;
/* Initialize videoProgress status publisher */
_progressUpdateInterval = 250;
_prevProgressUpdateTime = nil;
_progressUpdateTimer = [CADisplayLink displayLinkWithTarget:self selector:@selector(sendProgressUpdate)];
[_progressUpdateTimer addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
} }
return self; return self;
} }
#pragma mark - Progress
- (void)sendProgressUpdate { - (void)sendProgressUpdate {
AVPlayerItem *video = [_player currentItem]; AVPlayerItem *video = [_player currentItem];
if (video == nil || video.status != AVPlayerItemStatusReadyToPlay) { if (video == nil || video.status != AVPlayerItemStatusReadyToPlay) {
@ -58,21 +54,49 @@ static NSString *const statusKeyPath = @"status";
@"currentTime": [NSNumber numberWithFloat:CMTimeGetSeconds(video.currentTime)], @"currentTime": [NSNumber numberWithFloat:CMTimeGetSeconds(video.currentTime)],
@"target": self.reactTag @"target": self.reactTag
}]; }];
_prevProgressUpdateTime = [NSDate date]; _prevProgressUpdateTime = [NSDate date];
} }
} }
- (void)setSrc:(NSDictionary *)source { - (void)stopProgressTimer {
[_progressUpdateTimer invalidate];
}
- (void)startProgressTimer {
/* Initialize videoProgress status publisher */
_progressUpdateInterval = 250;
_prevProgressUpdateTime = nil;
[self stopProgressTimer];
_progressUpdateTimer = [CADisplayLink displayLinkWithTarget:self selector:@selector(sendProgressUpdate)];
[_progressUpdateTimer addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
}
#pragma mark - Player and source
- (AVPlayerItem*)playerItemForSource:(NSDictionary *)source {
bool isNetwork = [source objectForKey:@"isNetwork"]; bool isNetwork = [source objectForKey:@"isNetwork"];
bool isAsset = [source objectForKey:@"isAsset"];
NSString *uri = [source objectForKey:@"uri"]; NSString *uri = [source objectForKey:@"uri"];
NSString *type = [source objectForKey:@"type"]; NSString *type = [source objectForKey:@"type"];
_videoURL = isNetwork ? 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 (isAsset) {
AVURLAsset *asset = [AVURLAsset URLAssetWithURL:url options:nil];
return [AVPlayerItem playerItemWithAsset:asset];
}
return [AVPlayerItem playerItemWithURL:url];
}
- (void)setSrc:(NSDictionary *)source {
[_playerItem removeObserver:self forKeyPath:statusKeyPath]; [_playerItem removeObserver:self forKeyPath:statusKeyPath];
_playerItem = [AVPlayerItem playerItemWithURL:_videoURL]; _playerItem = [self playerItemForSource:source];
[_playerItem addObserver:self forKeyPath:statusKeyPath options:0 context:nil]; [_playerItem addObserver:self forKeyPath:statusKeyPath options:0 context:nil];
[_player pause]; [_player pause];
@ -88,11 +112,11 @@ static NSString *const statusKeyPath = @"status";
[self.layer addSublayer:_playerLayer]; [self.layer addSublayer:_playerLayer];
self.layer.needsDisplayOnBoundsChange = YES; self.layer.needsDisplayOnBoundsChange = YES;
[_eventDispatcher sendInputEventWithName:RNVideoEventLoadingError body:@{ [_eventDispatcher sendInputEventWithName:RNVideoEventLoading body:@{
@"src": @{ @"src": @{
@"uri":uri, @"uri": [source objectForKey:@"uri"],
@"type": type, @"type": [source objectForKey:@"type"],
@"isNetwork":[NSNumber numberWithBool:isNetwork] @"isNetwork":[NSNumber numberWithBool:(bool)[source objectForKey:@"isNetwork"]]
}, },
@"target": self.reactTag @"target": self.reactTag
}]; }];
@ -113,10 +137,11 @@ static NSString *const statusKeyPath = @"status";
@"target": self.reactTag @"target": self.reactTag
}]; }];
[self startProgressTimer];
[_player play]; [_player play];
[self applyModifiers]; [self applyModifiers];
} else if(_playerItem.status == AVPlayerItemStatusFailed) { } else if(_playerItem.status == AVPlayerItemStatusFailed) {
[_eventDispatcher sendInputEventWithName:RNVideoLoadingErrorEvent body:@{ [_eventDispatcher sendInputEventWithName:RNVideoEventLoadingError body:@{
@"error": @{ @"error": @{
@"code": [NSNumber numberWithInt:_playerItem.error.code], @"code": [NSNumber numberWithInt:_playerItem.error.code],
@"domain": _playerItem.error.domain @"domain": _playerItem.error.domain
@ -129,6 +154,14 @@ static NSString *const statusKeyPath = @"status";
} }
} }
- (void)playerItemDidReachEnd:(NSNotification *)notification {
AVPlayerItem *item = [notification object];
[item seekToTime:kCMTimeZero];
[_player play];
}
#pragma mark - additional prop setters
- (void)setResizeMode:(NSString*)mode { - (void)setResizeMode:(NSString*)mode {
_playerLayer.videoGravity = mode; _playerLayer.videoGravity = mode;
} }
@ -136,9 +169,12 @@ static NSString *const statusKeyPath = @"status";
- (void)setPaused:(BOOL)paused - (void)setPaused:(BOOL)paused
{ {
if (paused) { if (paused) {
[self stopProgressTimer];
[_player pause]; [_player pause];
} else { } else {
[self startProgressTimer];
[_player play]; [_player play];
} }
} }
@ -200,6 +236,8 @@ static NSString *const statusKeyPath = @"status";
} }
} }
#pragma mark - react and view related
- (void)insertReactSubview:(UIView *)view atIndex:(NSInteger)atIndex { - (void)insertReactSubview:(UIView *)view atIndex:(NSInteger)atIndex {
RCTLogError(@"video cannot have any subviews"); RCTLogError(@"video cannot have any subviews");
return; return;
@ -215,6 +253,8 @@ static NSString *const statusKeyPath = @"status";
_playerLayer.frame = self.bounds; _playerLayer.frame = self.bounds;
} }
#pragma mark - lifecycle
- (void)removeFromSuperview - (void)removeFromSuperview
{ {
[_player pause]; [_player pause];