Replace use of RCTBridge with RCTBubblingEventBlock (#381)

This commit is contained in:
James Hartt 2016-12-13 00:16:11 +00:00 committed by Matt Apperson
parent 0442061028
commit 9bcf70cbb5
4 changed files with 89 additions and 75 deletions

View File

@ -220,6 +220,16 @@ Video.propTypes = {
src: PropTypes.object, src: PropTypes.object,
seek: PropTypes.number, seek: PropTypes.number,
fullscreen: PropTypes.bool, fullscreen: PropTypes.bool,
onVideoLoadStart: PropTypes.func,
onVideoLoad: PropTypes.func,
onVideoError: PropTypes.func,
onVideoProgress: PropTypes.func,
onVideoSeek: PropTypes.func,
onVideoEnd: PropTypes.func,
onVideoFullscreenPlayerWillPresent: PropTypes.func,
onVideoFullscreenPlayerDidPresent: PropTypes.func,
onVideoFullscreenPlayerWillDismiss: PropTypes.func,
onVideoFullscreenPlayerDidDismiss: PropTypes.func,
/* Wrapper component */ /* Wrapper component */
source: PropTypes.oneOfType([ source: PropTypes.oneOfType([

View File

@ -9,6 +9,21 @@
@interface RCTVideo : UIView <RCTVideoPlayerViewControllerDelegate> @interface RCTVideo : UIView <RCTVideoPlayerViewControllerDelegate>
@property (nonatomic, copy) RCTBubblingEventBlock onVideoLoadStart;
@property (nonatomic, copy) RCTBubblingEventBlock onVideoLoad;
@property (nonatomic, copy) RCTBubblingEventBlock onVideoError;
@property (nonatomic, copy) RCTBubblingEventBlock onVideoProgress;
@property (nonatomic, copy) RCTBubblingEventBlock onVideoSeek;
@property (nonatomic, copy) RCTBubblingEventBlock onVideoEnd;
@property (nonatomic, copy) RCTBubblingEventBlock onVideoFullscreenPlayerWillPresent;
@property (nonatomic, copy) RCTBubblingEventBlock onVideoFullscreenPlayerDidPresent;
@property (nonatomic, copy) RCTBubblingEventBlock onVideoFullscreenPlayerWillDismiss;
@property (nonatomic, copy) RCTBubblingEventBlock onVideoFullscreenPlayerDidDismiss;
@property (nonatomic, copy) RCTBubblingEventBlock onReadyForDisplay;
@property (nonatomic, copy) RCTBubblingEventBlock onPlaybackStalled;
@property (nonatomic, copy) RCTBubblingEventBlock onPlaybackResume;
@property (nonatomic, copy) RCTBubblingEventBlock onPlaybackRateChange;
- (instancetype)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher NS_DESIGNATED_INITIALIZER; - (instancetype)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher NS_DESIGNATED_INITIALIZER;
- (AVPlayerViewController*)createPlayerViewController:(AVPlayer*)player withPlayerItem:(AVPlayerItem*)playerItem; - (AVPlayerViewController*)createPlayerViewController:(AVPlayer*)player withPlayerItem:(AVPlayerItem*)playerItem;

View File

@ -185,15 +185,14 @@ static NSString *const playbackRate = @"rate";
const Float64 duration = CMTimeGetSeconds(playerDuration); const Float64 duration = CMTimeGetSeconds(playerDuration);
const Float64 currentTimeSecs = CMTimeGetSeconds(currentTime); const Float64 currentTimeSecs = CMTimeGetSeconds(currentTime);
if( currentTimeSecs >= 0) { if( currentTimeSecs >= 0) {
[_eventDispatcher sendInputEventWithName:@"onVideoProgress" self.onVideoProgress(@{
body:@{
@"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": [NSNumber numberWithFloat:CMTimeGetSeconds([self playerItemSeekableTimeRange].duration)], @"seekableDuration": [NSNumber numberWithFloat:CMTimeGetSeconds([self playerItemSeekableTimeRange].duration)],
}]; });
} }
} }
@ -275,12 +274,16 @@ static NSString *const playbackRate = @"rate";
queue:NULL queue:NULL
usingBlock:^(CMTime time) { [weakSelf sendProgressUpdate]; } usingBlock:^(CMTime time) { [weakSelf sendProgressUpdate]; }
]; ];
[_eventDispatcher sendInputEventWithName:@"onVideoLoadStart"
body:@{@"src": @{ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
//Perform on next run loop, otherwise onVideoLoadStart is nil
self.onVideoLoadStart(@{@"src": @{
@"uri": [source objectForKey:@"uri"], @"uri": [source objectForKey:@"uri"],
@"type": [source objectForKey:@"type"], @"type": [source objectForKey:@"type"],
@"isNetwork":[NSNumber numberWithBool:(bool)[source objectForKey:@"isNetwork"]]}, @"isNetwork": [NSNumber numberWithBool:(bool)[source objectForKey:@"isNetwork"]]},
@"target": self.reactTag}]; @"target": self.reactTag
});
});
} }
- (AVPlayerItem*)playerItemForSource:(NSDictionary *)source - (AVPlayerItem*)playerItemForSource:(NSDictionary *)source
@ -339,8 +342,7 @@ static NSString *const playbackRate = @"rate";
orientation = @"portrait"; orientation = @"portrait";
} }
[_eventDispatcher sendInputEventWithName:@"onVideoLoad" self.onVideoLoad(@{@"duration": [NSNumber numberWithFloat:duration],
body:@{@"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],
@"canPlayFastForward": [NSNumber numberWithBool:_playerItem.canPlayFastForward], @"canPlayFastForward": [NSNumber numberWithBool:_playerItem.canPlayFastForward],
@ -353,16 +355,14 @@ static NSString *const playbackRate = @"rate";
@"height": height, @"height": height,
@"orientation": orientation @"orientation": orientation
}, },
@"target": self.reactTag}]; @"target": self.reactTag});
[self attachListeners]; [self attachListeners];
[self applyModifiers]; [self applyModifiers];
} else if(_playerItem.status == AVPlayerItemStatusFailed) { } else if(_playerItem.status == AVPlayerItemStatusFailed) {
[_eventDispatcher sendInputEventWithName:@"onVideoError" self.onVideoError(@{@"error": @{@"code": [NSNumber numberWithInteger: _playerItem.error.code],
body:@{@"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;
@ -376,19 +376,16 @@ static NSString *const playbackRate = @"rate";
} 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]) { if([change objectForKey:NSKeyValueChangeNewKey]) {
[_eventDispatcher sendInputEventWithName:@"onReadyForDisplay" self.onReadyForDisplay(@{@"target": self.reactTag});
body:@{@"target": self.reactTag}];
} }
} }
} else if (object == _player) { } else if (object == _player) {
if([keyPath isEqualToString:playbackRate]) { if([keyPath isEqualToString:playbackRate]) {
[_eventDispatcher sendInputEventWithName:@"onPlaybackRateChange" self.onPlaybackRateChange(@{@"playbackRate": [NSNumber numberWithFloat:_player.rate],
body:@{@"playbackRate": [NSNumber numberWithFloat:_player.rate], @"target": self.reactTag});
@"target": self.reactTag}];
if(_playbackStalled && _player.rate > 0) { if(_playbackStalled && _player.rate > 0) {
[_eventDispatcher sendInputEventWithName:@"onPlaybackResume" self.onPlaybackResume(@{@"playbackRate": [NSNumber numberWithFloat:_player.rate],
body:@{@"playbackRate": [NSNumber numberWithFloat:_player.rate], @"target": self.reactTag});
@"target": self.reactTag}];
_playbackStalled = NO; _playbackStalled = NO;
} }
} }
@ -412,13 +409,13 @@ static NSString *const playbackRate = @"rate";
- (void)playbackStalled:(NSNotification *)notification - (void)playbackStalled:(NSNotification *)notification
{ {
[_eventDispatcher sendInputEventWithName:@"onPlaybackStalled" body:@{@"target": self.reactTag}]; self.onPlaybackStalled(@{@"target": self.reactTag});
_playbackStalled = YES; _playbackStalled = YES;
} }
- (void)playerItemDidReachEnd:(NSNotification *)notification - (void)playerItemDidReachEnd:(NSNotification *)notification
{ {
[_eventDispatcher sendInputEventWithName:@"onVideoEnd" body:@{@"target": self.reactTag}]; self.onVideoEnd(@{@"target": self.reactTag});
if (_repeat) { if (_repeat) {
AVPlayerItem *item = [notification object]; AVPlayerItem *item = [notification object];
@ -490,10 +487,9 @@ static NSString *const playbackRate = @"rate";
if (CMTimeCompare(current, cmSeekTime) != 0) { if (CMTimeCompare(current, cmSeekTime) != 0) {
[_player seekToTime:cmSeekTime toleranceBefore:tolerance toleranceAfter:tolerance completionHandler:^(BOOL finished) { [_player seekToTime:cmSeekTime toleranceBefore:tolerance toleranceAfter:tolerance completionHandler:^(BOOL finished) {
[_eventDispatcher sendInputEventWithName:@"onVideoSeek" self.onVideoSeek(@{@"currentTime": [NSNumber numberWithFloat:CMTimeGetSeconds(item.currentTime)],
body:@{@"currentTime": [NSNumber numberWithFloat:CMTimeGetSeconds(item.currentTime)],
@"seekTime": [NSNumber numberWithFloat:seekTime], @"seekTime": [NSNumber numberWithFloat:seekTime],
@"target": self.reactTag}]; @"target": self.reactTag});
}]; }];
_pendingSeek = false; _pendingSeek = false;
@ -575,11 +571,11 @@ static NSString *const playbackRate = @"rate";
if( viewController ) if( viewController )
{ {
_presentingViewController = viewController; _presentingViewController = viewController;
[_eventDispatcher sendInputEventWithName:@"onVideoFullscreenPlayerWillPresent" body:@{@"target": self.reactTag}]; self.onVideoFullscreenPlayerWillPresent(@{@"target": self.reactTag});
[viewController presentViewController:_playerViewController animated:true completion:^{ [viewController presentViewController:_playerViewController animated:true completion:^{
_playerViewController.showsPlaybackControls = YES; _playerViewController.showsPlaybackControls = YES;
_fullscreenPlayerPresented = fullscreen; _fullscreenPlayerPresented = fullscreen;
[_eventDispatcher sendInputEventWithName:@"onVideoFullscreenPlayerDidPresent" body:@{@"target": self.reactTag}]; self.onVideoFullscreenPlayerDidPresent(@{@"target": self.reactTag});
}]; }];
} }
} }
@ -659,7 +655,7 @@ static NSString *const playbackRate = @"rate";
{ {
if (_playerViewController == playerViewController && _fullscreenPlayerPresented) if (_playerViewController == playerViewController && _fullscreenPlayerPresented)
{ {
[_eventDispatcher sendInputEventWithName:@"onVideoFullscreenPlayerWillDismiss" body:@{@"target": self.reactTag}]; self.onVideoFullscreenPlayerWillDismiss(@{@"target": self.reactTag});
} }
} }
@ -670,7 +666,7 @@ static NSString *const playbackRate = @"rate";
_fullscreenPlayerPresented = false; _fullscreenPlayerPresented = false;
_presentingViewController = nil; _presentingViewController = nil;
[self applyModifiers]; [self applyModifiers];
[_eventDispatcher sendInputEventWithName:@"onVideoFullscreenPlayerDidDismiss" body:@{@"target": self.reactTag}]; self.onVideoFullscreenPlayerDidDismiss(@{@"target": self.reactTag});
} }
} }

View File

@ -14,28 +14,6 @@ RCT_EXPORT_MODULE();
return [[RCTVideo alloc] initWithEventDispatcher:self.bridge.eventDispatcher]; return [[RCTVideo alloc] initWithEventDispatcher:self.bridge.eventDispatcher];
} }
/* Should support: onLoadStart, onLoad, and onError to stay consistent with Image */
- (NSArray *)customDirectEventTypes
{
return @[
@"onVideoLoadStart",
@"onVideoLoad",
@"onVideoError",
@"onVideoProgress",
@"onVideoSeek",
@"onVideoEnd",
@"onVideoFullscreenPlayerWillPresent",
@"onVideoFullscreenPlayerDidPresent",
@"onVideoFullscreenPlayerWillDismiss",
@"onVideoFullscreenPlayerDidDismiss",
@"onReadyForDisplay",
@"onPlaybackStalled",
@"onPlaybackResume",
@"onPlaybackRateChange"
];
}
- (dispatch_queue_t)methodQueue - (dispatch_queue_t)methodQueue
{ {
return dispatch_get_main_queue(); return dispatch_get_main_queue();
@ -55,6 +33,21 @@ RCT_EXPORT_VIEW_PROPERTY(seek, float);
RCT_EXPORT_VIEW_PROPERTY(currentTime, float); RCT_EXPORT_VIEW_PROPERTY(currentTime, float);
RCT_EXPORT_VIEW_PROPERTY(fullscreen, BOOL); RCT_EXPORT_VIEW_PROPERTY(fullscreen, BOOL);
RCT_EXPORT_VIEW_PROPERTY(progressUpdateInterval, float); RCT_EXPORT_VIEW_PROPERTY(progressUpdateInterval, float);
/* Should support: onLoadStart, onLoad, and onError to stay consistent with Image */
RCT_EXPORT_VIEW_PROPERTY(onVideoLoadStart, RCTBubblingEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onVideoLoad, RCTBubblingEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onVideoError, RCTBubblingEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onVideoProgress, RCTBubblingEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onVideoSeek, RCTBubblingEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onVideoEnd, RCTBubblingEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onVideoFullscreenPlayerWillPresent, RCTBubblingEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onVideoFullscreenPlayerDidPresent, RCTBubblingEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onVideoFullscreenPlayerWillDismiss, RCTBubblingEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onVideoFullscreenPlayerDidDismiss, RCTBubblingEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onReadyForDisplay, RCTBubblingEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onPlaybackStalled, RCTBubblingEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onPlaybackResume, RCTBubblingEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onPlaybackRateChange, RCTBubblingEventBlock);
- (NSDictionary *)constantsToExport - (NSDictionary *)constantsToExport
{ {