Fix local playback with source dictionary, set default rate/volume

This commit is contained in:
Brent Vatne 2015-04-08 10:34:27 -07:00
parent e9e48bb666
commit bd1dc1f014
2 changed files with 33 additions and 39 deletions

View File

@ -36,6 +36,8 @@ 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;
_rate = 1.0;
_volume = 1.0;
} }
return self; return self;
} }
@ -54,7 +56,7 @@ 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];
} }
} }
@ -64,36 +66,17 @@ static NSString *const statusKeyPath = @"status";
} }
- (void)startProgressTimer { - (void)startProgressTimer {
/* Initialize videoProgress status publisher */
_progressUpdateInterval = 250; _progressUpdateInterval = 250;
_prevProgressUpdateTime = nil; _prevProgressUpdateTime = nil;
[self stopProgressTimer]; [self stopProgressTimer];
_progressUpdateTimer = [CADisplayLink displayLinkWithTarget:self selector:@selector(sendProgressUpdate)]; _progressUpdateTimer = [CADisplayLink displayLinkWithTarget:self selector:@selector(sendProgressUpdate)];
[_progressUpdateTimer addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode]; [_progressUpdateTimer addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
} }
#pragma mark - Player and source #pragma mark - Player and source
- (AVPlayerItem*)playerItemForSource:(NSDictionary *)source {
bool isNetwork = [source objectForKey:@"isNetwork"];
bool isAsset = [source objectForKey:@"isAsset"];
NSString *uri = [source objectForKey:@"uri"];
NSString *type = [source objectForKey:@"type"];
NSURL *url = isNetwork || isAsset ?
[NSURL URLWithString:uri] :
[[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 { - (void)setSrc:(NSDictionary *)source {
[_playerItem removeObserver:self forKeyPath:statusKeyPath]; [_playerItem removeObserver:self forKeyPath:statusKeyPath];
_playerItem = [self playerItemForSource:source]; _playerItem = [self playerItemForSource:source];
@ -122,6 +105,24 @@ static NSString *const statusKeyPath = @"status";
}]; }];
} }
- (AVPlayerItem*)playerItemForSource:(NSDictionary *)source {
bool isNetwork = [RCTConvert BOOL:[source objectForKey:@"isNetwork"]];
bool isAsset = [RCTConvert BOOL:[source objectForKey:@"isAsset"]];
NSString *uri = [source objectForKey:@"uri"];
NSString *type = [source objectForKey:@"type"];
NSURL *url = (isNetwork || isAsset) ?
[NSURL URLWithString:uri] :
[[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)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) {
if (_playerItem.status == AVPlayerItemStatusReadyToPlay) { if (_playerItem.status == AVPlayerItemStatusReadyToPlay) {
@ -155,12 +156,13 @@ static NSString *const statusKeyPath = @"status";
} }
- (void)playerItemDidReachEnd:(NSNotification *)notification { - (void)playerItemDidReachEnd:(NSNotification *)notification {
AVPlayerItem *item = [notification object]; AVPlayerItem *item = [notification object];
[item seekToTime:kCMTimeZero]; [item seekToTime:kCMTimeZero];
[_player play]; [_player play];
[self applyModifiers];
} }
#pragma mark - additional prop setters #pragma mark - Prop setters
- (void)setResizeMode:(NSString*)mode { - (void)setResizeMode:(NSString*)mode {
_playerLayer.videoGravity = mode; _playerLayer.videoGravity = mode;
@ -197,8 +199,7 @@ static NSString *const statusKeyPath = @"status";
- (void)applyModifiers - (void)applyModifiers
{ {
/* volume must be set to 0 if muted is YES, or the video seems to /* volume must be set to 0 if muted is YES, or the video freezes playback */
* freeze */
if (_muted) { if (_muted) {
[_player setVolume:0]; [_player setVolume:0];
[_player setMuted:YES]; [_player setMuted:YES];
@ -210,13 +211,6 @@ static NSString *const statusKeyPath = @"status";
[_player setRate:_rate]; [_player setRate:_rate];
} }
- (void)playerItemDidReachEnd:(NSNotification *)notification {
AVPlayerItem *item = [notification object];
[item seekToTime:kCMTimeZero];
[_player play];
[self applyModifiers];
}
- (void)setRepeatEnabled { - (void)setRepeatEnabled {
[[NSNotificationCenter defaultCenter] addObserver:self [[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(playerItemDidReachEnd:) selector:@selector(playerItemDidReachEnd:)
@ -236,7 +230,7 @@ static NSString *const statusKeyPath = @"status";
} }
} }
#pragma mark - react and view related #pragma mark - React View Management
- (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");
@ -253,7 +247,7 @@ static NSString *const statusKeyPath = @"status";
_playerLayer.frame = self.bounds; _playerLayer.frame = self.bounds;
} }
#pragma mark - lifecycle #pragma mark - Lifecycle
- (void)removeFromSuperview - (void)removeFromSuperview
{ {

View File

@ -90,8 +90,8 @@ var Video = React.createClass({
var RCTVideo = createReactIOSNativeComponentClass({ var RCTVideo = createReactIOSNativeComponentClass({
validAttributes: merge(ReactIOSViewAttributes.UIView, validAttributes: merge(ReactIOSViewAttributes.UIView,
{src: {diff: deepDiffer}, resizeMode: true, repeat: true, paused: true, muted: true, {src: {diff: deepDiffer}, resizeMode: true, repeat: true,
volume: true, rate: true}), paused: true, muted: true, volume: true, rate: true}),
uiViewClassName: 'RCTVideo', uiViewClassName: 'RCTVideo',
}); });