- timer only starts when the video plays and is stopped when video is paused
- renamed event constants
This commit is contained in:
parent
00455ba1fb
commit
e9e48bb666
68
RCTVideo.m
68
RCTVideo.m
@ -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];
|
||||||
|
Loading…
Reference in New Issue
Block a user