tobias
2016-05-23 13:52:08 +02:00
9 changed files with 165 additions and 22 deletions

View File

@@ -7,6 +7,8 @@
static NSString *const statusKeyPath = @"status";
static NSString *const playbackLikelyToKeepUpKeyPath = @"playbackLikelyToKeepUp";
static NSString *const playbackBufferEmptyKeyPath = @"playbackBufferEmpty";
static NSString *const readyForDisplayKeyPath = @"readyForDisplay";
static NSString *const playbackRate = @"rate";
@implementation RCTVideo
{
@@ -36,6 +38,7 @@ static NSString *const playbackBufferEmptyKeyPath = @"playbackBufferEmpty";
BOOL _muted;
BOOL _paused;
BOOL _repeat;
BOOL _playbackStalled;
BOOL _playInBackground;
BOOL _playWhenInactive;
NSString * _resizeMode;
@@ -48,6 +51,7 @@ static NSString *const playbackBufferEmptyKeyPath = @"playbackBufferEmpty";
if ((self = [super init])) {
_eventDispatcher = eventDispatcher;
_playbackStalled = NO;
_rate = 1.0;
_volume = 1.0;
_resizeMode = @"AVLayerVideoGravityResizeAspectFill";
@@ -233,13 +237,13 @@ static NSString *const playbackBufferEmptyKeyPath = @"playbackBufferEmpty";
[self addPlayerItemObservers];
[_player pause];
[_playerLayer removeFromSuperlayer];
_playerLayer = nil;
[self removePlayerLayer];
[_playerViewController.view removeFromSuperview];
_playerViewController = nil;
_player = [AVPlayer playerWithPlayerItem:_playerItem];
_player.actionAtItemEnd = AVPlayerActionAtItemEndNone;
[_player addObserver:self forKeyPath:playbackRate options:0 context:nil];
const Float64 progressUpdateIntervalMS = _progressUpdateInterval / 1000;
// @see endScrubbing in AVPlayerDemoPlaybackViewController.m of https://developer.apple.com/library/ios/samplecode/AVPlayerDemo/Introduction/Intro.html
@@ -290,9 +294,21 @@ static NSString *const playbackBufferEmptyKeyPath = @"playbackBufferEmpty";
NSObject *width = @"undefined";
NSObject *height = @"undefined";
NSString *orientation = @"undefined";
if ([_playerItem.asset tracksWithMediaType:AVMediaTypeVideo].count > 0) {
width = [NSNumber numberWithFloat:[_playerItem.asset tracksWithMediaType:AVMediaTypeVideo][0].naturalSize.width];
height = [NSNumber numberWithFloat:[_playerItem.asset tracksWithMediaType:AVMediaTypeVideo][0].naturalSize.height];
AVAssetTrack *videoTrack = [[_playerItem.asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
width = [NSNumber numberWithFloat:videoTrack.naturalSize.width];
height = [NSNumber numberWithFloat:videoTrack.naturalSize.height];
CGAffineTransform preferredTransform = [videoTrack preferredTransform];
if ((videoTrack.naturalSize.width == preferredTransform.tx
&& videoTrack.naturalSize.height == preferredTransform.ty)
|| (preferredTransform.tx == 0 && preferredTransform.ty == 0))
{
orientation = @"landscape";
} else
orientation = @"portrait";
}
[_eventDispatcher sendInputEventWithName:@"onVideoLoad"
@@ -306,7 +322,8 @@ static NSString *const playbackBufferEmptyKeyPath = @"playbackBufferEmpty";
@"canStepForward": [NSNumber numberWithBool:_playerItem.canStepForward],
@"naturalSize": @{
@"width": width,
@"height": height
@"height": height,
@"orientation": orientation
},
@"target": self.reactTag}];
@@ -328,6 +345,25 @@ static NSString *const playbackBufferEmptyKeyPath = @"playbackBufferEmpty";
}
_playerBufferEmpty = NO;
}
} else if (object == _playerLayer) {
if([keyPath isEqualToString:readyForDisplayKeyPath] && [change objectForKey:NSKeyValueChangeNewKey]) {
if([change objectForKey:NSKeyValueChangeNewKey]) {
[_eventDispatcher sendInputEventWithName:@"onReadyForDisplay"
body:@{@"target": self.reactTag}];
}
}
} else if (object == _player) {
if([keyPath isEqualToString:playbackRate]) {
[_eventDispatcher sendInputEventWithName:@"onPlaybackRateChange"
body:@{@"playbackRate": [NSNumber numberWithFloat:_player.rate],
@"target": self.reactTag}];
if(_playbackStalled && _player.rate > 0) {
[_eventDispatcher sendInputEventWithName:@"onPlaybackResume"
body:@{@"playbackRate": [NSNumber numberWithFloat:_player.rate],
@"target": self.reactTag}];
_playbackStalled = NO;
}
}
} else {
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
@@ -340,6 +376,16 @@ static NSString *const playbackBufferEmptyKeyPath = @"playbackBufferEmpty";
selector:@selector(playerItemDidReachEnd:)
name:AVPlayerItemDidPlayToEndTimeNotification
object:[_player currentItem]];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(playbackStalled:)
name:AVPlayerItemPlaybackStalledNotification
object:nil];
}
- (void)playbackStalled:(NSNotification *)notification
{
[_eventDispatcher sendInputEventWithName:@"onPlaybackStalled" body:@{@"target": self.reactTag}];
_playbackStalled = YES;
}
- (void)playerItemDidReachEnd:(NSNotification *)notification
@@ -534,6 +580,8 @@ static NSString *const playbackBufferEmptyKeyPath = @"playbackBufferEmpty";
_playerLayer = [AVPlayerLayer playerLayerWithPlayer:_player];
_playerLayer.frame = self.bounds;
_playerLayer.needsDisplayOnBoundsChange = YES;
[_playerLayer addObserver:self forKeyPath:readyForDisplayKeyPath options:NSKeyValueObservingOptionNew context:nil];
[self.layer addSublayer:_playerLayer];
self.layer.needsDisplayOnBoundsChange = YES;
@@ -547,8 +595,7 @@ static NSString *const playbackBufferEmptyKeyPath = @"playbackBufferEmpty";
_controls = controls;
if( _controls )
{
[_playerLayer removeFromSuperlayer];
_playerLayer = nil;
[self removePlayerLayer];
[self usePlayerViewController];
}
else
@@ -560,6 +607,13 @@ static NSString *const playbackBufferEmptyKeyPath = @"playbackBufferEmpty";
}
}
- (void)removePlayerLayer
{
[_playerLayer removeFromSuperlayer];
[_playerLayer removeObserver:self forKeyPath:readyForDisplayKeyPath];
_playerLayer = nil;
}
#pragma mark - RCTVideoPlayerViewControllerDelegate
- (void)videoPlayerViewControllerWillDismiss:(AVPlayerViewController *)playerViewController
@@ -643,10 +697,10 @@ static NSString *const playbackBufferEmptyKeyPath = @"playbackBufferEmpty";
- (void)removeFromSuperview
{
[_player pause];
[_player removeObserver:self forKeyPath:playbackRate];
_player = nil;
[_playerLayer removeFromSuperlayer];
_playerLayer = nil;
[self removePlayerLayer];
[_playerViewController.view removeFromSuperview];
_playerViewController = nil;