|  |  | @@ -23,8 +23,7 @@ static int const RCTVideoUnset = -1; | 
			
		
	
		
		
			
				
					
					|  |  |  | #define DebugLog(...) (void)0 |  |  |  | #define DebugLog(...) (void)0 | 
			
		
	
		
		
			
				
					
					|  |  |  | #endif |  |  |  | #endif | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | @implementation RCTVideo |  |  |  | @implementation RCTVideo { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     AVPlayer *_player; |  |  |  |     AVPlayer *_player; | 
			
		
	
		
		
			
				
					
					|  |  |  |     AVPlayerItem *_playerItem; |  |  |  |     AVPlayerItem *_playerItem; | 
			
		
	
		
		
			
				
					
					|  |  |  |     BOOL _playerItemObserversSet; |  |  |  |     BOOL _playerItemObserversSet; | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -74,8 +73,7 @@ static int const RCTVideoUnset = -1; | 
			
		
	
		
		
			
				
					
					|  |  |  | #endif |  |  |  | #endif | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | - (instancetype)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher |  |  |  | - (instancetype)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     if ((self = [super init])) { |  |  |  |     if ((self = [super init])) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         filters = @{ |  |  |  |         filters = @{ | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -150,45 +148,40 @@ static int const RCTVideoUnset = -1; | 
			
		
	
		
		
			
				
					
					|  |  |  |  **  Get the duration for a AVPlayerItem. |  |  |  |  **  Get the duration for a AVPlayerItem. | 
			
		
	
		
		
			
				
					
					|  |  |  |  ** ------------------------------------------------------- */ |  |  |  |  ** ------------------------------------------------------- */ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | - (CMTime)playerItemDuration |  |  |  | - (CMTime)playerItemDuration { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     AVPlayerItem *playerItem = [_player currentItem]; |  |  |  |     AVPlayerItem *playerItem = [_player currentItem]; | 
			
		
	
		
		
			
				
					
					|  |  |  |   if (playerItem.status == AVPlayerItemStatusReadyToPlay) |  |  |  |     if (playerItem.status == AVPlayerItemStatusReadyToPlay) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |   { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |         return ([playerItem duration]); |  |  |  |         return ([playerItem duration]); | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     return (kCMTimeInvalid); |  |  |  |     return (kCMTimeInvalid); | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | - (CMTimeRange)playerItemSeekableTimeRange |  |  |  | - (CMTimeRange)playerItemSeekableTimeRange { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     AVPlayerItem *playerItem = [_player currentItem]; |  |  |  |     AVPlayerItem *playerItem = [_player currentItem]; | 
			
		
	
		
		
			
				
					
					|  |  |  |   if (playerItem.status == AVPlayerItemStatusReadyToPlay) |  |  |  |     if (playerItem.status == AVPlayerItemStatusReadyToPlay) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |   { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |         return [playerItem seekableTimeRanges].firstObject.CMTimeRangeValue; |  |  |  |         return [playerItem seekableTimeRanges].firstObject.CMTimeRangeValue; | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     return (kCMTimeRangeZero); |  |  |  |     return (kCMTimeRangeZero); | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | -(void)addPlayerTimeObserver |  |  |  | - (void)addPlayerTimeObserver { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     const Float64 progressUpdateIntervalMS = _progressUpdateInterval / 1000; |  |  |  |     const Float64 progressUpdateIntervalMS = _progressUpdateInterval / 1000; | 
			
		
	
		
		
			
				
					
					|  |  |  |     // @see endScrubbing in AVPlayerDemoPlaybackViewController.m |  |  |  |     // @see endScrubbing in AVPlayerDemoPlaybackViewController.m | 
			
		
	
		
		
			
				
					
					|  |  |  |     // of https://developer.apple.com/library/ios/samplecode/AVPlayerDemo/Introduction/Intro.html |  |  |  |     // of https://developer.apple.com/library/ios/samplecode/AVPlayerDemo/Introduction/Intro.html | 
			
		
	
		
		
			
				
					
					|  |  |  |     __weak RCTVideo *weakSelf = self; |  |  |  |     __weak RCTVideo *weakSelf = self; | 
			
		
	
		
		
			
				
					
					|  |  |  |     _timeObserver = [_player addPeriodicTimeObserverForInterval:CMTimeMakeWithSeconds(progressUpdateIntervalMS, NSEC_PER_SEC) |  |  |  |     _timeObserver = [_player addPeriodicTimeObserverForInterval:CMTimeMakeWithSeconds(progressUpdateIntervalMS, NSEC_PER_SEC) | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                           queue:NULL |  |  |  |                                                           queue:NULL | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                    usingBlock:^(CMTime time) { [weakSelf sendProgressUpdate]; } |  |  |  |                                                      usingBlock:^(CMTime time) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                                          [weakSelf sendProgressUpdate]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                                      } | 
			
		
	
		
		
			
				
					
					|  |  |  |     ]; |  |  |  |     ]; | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | /* Cancels the previously registered time observer. */ |  |  |  | /* Cancels the previously registered time observer. */ | 
			
		
	
		
		
			
				
					
					|  |  |  | -(void)removePlayerTimeObserver |  |  |  | - (void)removePlayerTimeObserver { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  |     if (_timeObserver) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |   if (_timeObserver) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   { |  |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |         [_player removeTimeObserver:_timeObserver]; |  |  |  |         [_player removeTimeObserver:_timeObserver]; | 
			
		
	
		
		
			
				
					
					|  |  |  |         _timeObserver = nil; |  |  |  |         _timeObserver = nil; | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -196,8 +189,7 @@ static int const RCTVideoUnset = -1; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | #pragma mark - Progress |  |  |  | #pragma mark - Progress | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | - (void)dealloc |  |  |  | - (void)dealloc { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     [[NSNotificationCenter defaultCenter] removeObserver:self]; |  |  |  |     [[NSNotificationCenter defaultCenter] removeObserver:self]; | 
			
		
	
		
		
			
				
					
					|  |  |  |     [self removePlayerLayer]; |  |  |  |     [self removePlayerLayer]; | 
			
		
	
		
		
			
				
					
					|  |  |  |     [self removePlayerItemObservers]; |  |  |  |     [self removePlayerItemObservers]; | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -206,24 +198,21 @@ static int const RCTVideoUnset = -1; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | #pragma mark - App lifecycle handlers |  |  |  | #pragma mark - App lifecycle handlers | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | - (void)applicationWillResignActive:(NSNotification *)notification |  |  |  | - (void)applicationWillResignActive:(NSNotification *)notification { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     if (_playInBackground || _playWhenInactive || _paused) return; |  |  |  |     if (_playInBackground || _playWhenInactive || _paused) return; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     [_player pause]; |  |  |  |     [_player pause]; | 
			
		
	
		
		
			
				
					
					|  |  |  |     [_player setRate:0.0]; |  |  |  |     [_player setRate:0.0]; | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | - (void)applicationDidEnterBackground:(NSNotification *)notification |  |  |  | - (void)applicationDidEnterBackground:(NSNotification *)notification { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     if (_playInBackground) { |  |  |  |     if (_playInBackground) { | 
			
		
	
		
		
			
				
					
					|  |  |  |         // Needed to play sound in background. See https://developer.apple.com/library/ios/qa/qa1668/_index.html |  |  |  |         // Needed to play sound in background. See https://developer.apple.com/library/ios/qa/qa1668/_index.html | 
			
		
	
		
		
			
				
					
					|  |  |  |         [_playerLayer setPlayer:nil]; |  |  |  |         [_playerLayer setPlayer:nil]; | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | - (void)applicationWillEnterForeground:(NSNotification *)notification |  |  |  | - (void)applicationWillEnterForeground:(NSNotification *)notification { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     [self applyModifiers]; |  |  |  |     [self applyModifiers]; | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (_playInBackground) { |  |  |  |     if (_playInBackground) { | 
			
		
	
		
		
			
				
					
					|  |  |  |         [_playerLayer setPlayer:_player]; |  |  |  |         [_playerLayer setPlayer:_player]; | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -232,8 +221,7 @@ static int const RCTVideoUnset = -1; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | #pragma mark - Audio events |  |  |  | #pragma mark - Audio events | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | - (void)audioRouteChanged:(NSNotification *)notification |  |  |  | - (void)audioRouteChanged:(NSNotification *)notification { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     NSNumber *reason = [[notification userInfo] objectForKey:AVAudioSessionRouteChangeReasonKey]; |  |  |  |     NSNumber *reason = [[notification userInfo] objectForKey:AVAudioSessionRouteChangeReasonKey]; | 
			
		
	
		
		
			
				
					
					|  |  |  |     NSNumber *previousRoute = [[notification userInfo] objectForKey:AVAudioSessionRouteChangePreviousRouteKey]; |  |  |  |     NSNumber *previousRoute = [[notification userInfo] objectForKey:AVAudioSessionRouteChangePreviousRouteKey]; | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (reason.unsignedIntValue == AVAudioSessionRouteChangeReasonOldDeviceUnavailable) { |  |  |  |     if (reason.unsignedIntValue == AVAudioSessionRouteChangeReasonOldDeviceUnavailable) { | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -243,8 +231,7 @@ static int const RCTVideoUnset = -1; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | #pragma mark - Progress |  |  |  | #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) { | 
			
		
	
		
		
			
				
					
					|  |  |  |         return; |  |  |  |         return; | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -278,8 +265,7 @@ static int const RCTVideoUnset = -1; | 
			
		
	
		
		
			
				
					
					|  |  |  |  * |  |  |  |  * | 
			
		
	
		
		
			
				
					
					|  |  |  |  * \returns The playable duration of the current player item in seconds. |  |  |  |  * \returns The playable duration of the current player item in seconds. | 
			
		
	
		
		
			
				
					
					|  |  |  |  */ |  |  |  |  */ | 
			
		
	
		
		
			
				
					
					|  |  |  | - (NSNumber *)calculatePlayableDuration |  |  |  | - (NSNumber *)calculatePlayableDuration { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     AVPlayerItem *video = _player.currentItem; |  |  |  |     AVPlayerItem *video = _player.currentItem; | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (video.status == AVPlayerItemStatusReadyToPlay) { |  |  |  |     if (video.status == AVPlayerItemStatusReadyToPlay) { | 
			
		
	
		
		
			
				
					
					|  |  |  |         __block CMTimeRange effectiveTimeRange; |  |  |  |         __block CMTimeRange effectiveTimeRange; | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -298,18 +284,15 @@ static int const RCTVideoUnset = -1; | 
			
		
	
		
		
			
				
					
					|  |  |  |     return [NSNumber numberWithInteger:0]; |  |  |  |     return [NSNumber numberWithInteger:0]; | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | - (NSNumber *)calculateSeekableDuration |  |  |  | - (NSNumber *)calculateSeekableDuration { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     CMTimeRange timeRange = [self playerItemSeekableTimeRange]; |  |  |  |     CMTimeRange timeRange = [self playerItemSeekableTimeRange]; | 
			
		
	
		
		
			
				
					
					|  |  |  |   if (CMTIME_IS_NUMERIC(timeRange.duration)) |  |  |  |     if (CMTIME_IS_NUMERIC(timeRange.duration)) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |   { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |         return [NSNumber numberWithFloat:CMTimeGetSeconds(timeRange.duration)]; |  |  |  |         return [NSNumber numberWithFloat:CMTimeGetSeconds(timeRange.duration)]; | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     return [NSNumber numberWithInteger:0]; |  |  |  |     return [NSNumber numberWithInteger:0]; | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | - (void)addPlayerItemObservers |  |  |  | - (void)addPlayerItemObservers { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     [_playerItem addObserver:self forKeyPath:statusKeyPath options:0 context:nil]; |  |  |  |     [_playerItem addObserver:self forKeyPath:statusKeyPath options:0 context:nil]; | 
			
		
	
		
		
			
				
					
					|  |  |  |     [_playerItem addObserver:self forKeyPath:playbackBufferEmptyKeyPath options:0 context:nil]; |  |  |  |     [_playerItem addObserver:self forKeyPath:playbackBufferEmptyKeyPath options:0 context:nil]; | 
			
		
	
		
		
			
				
					
					|  |  |  |     [_playerItem addObserver:self forKeyPath:playbackLikelyToKeepUpKeyPath options:0 context:nil]; |  |  |  |     [_playerItem addObserver:self forKeyPath:playbackLikelyToKeepUpKeyPath options:0 context:nil]; | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -320,8 +303,7 @@ static int const RCTVideoUnset = -1; | 
			
		
	
		
		
			
				
					
					|  |  |  | /* Fixes https://github.com/brentvatne/react-native-video/issues/43 |  |  |  | /* Fixes https://github.com/brentvatne/react-native-video/issues/43 | 
			
		
	
		
		
			
				
					
					|  |  |  |  * Crashes caused when trying to remove the observer when there is no |  |  |  |  * Crashes caused when trying to remove the observer when there is no | 
			
		
	
		
		
			
				
					
					|  |  |  |  * observer set */ |  |  |  |  * observer set */ | 
			
		
	
		
		
			
				
					
					|  |  |  | - (void)removePlayerItemObservers |  |  |  | - (void)removePlayerItemObservers { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     if (_playerItemObserversSet) { |  |  |  |     if (_playerItemObserversSet) { | 
			
		
	
		
		
			
				
					
					|  |  |  |         [_playerItem removeObserver:self forKeyPath:statusKeyPath]; |  |  |  |         [_playerItem removeObserver:self forKeyPath:statusKeyPath]; | 
			
		
	
		
		
			
				
					
					|  |  |  |         [_playerItem removeObserver:self forKeyPath:playbackBufferEmptyKeyPath]; |  |  |  |         [_playerItem removeObserver:self forKeyPath:playbackBufferEmptyKeyPath]; | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -333,8 +315,7 @@ static int const RCTVideoUnset = -1; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | #pragma mark - Player and source |  |  |  | #pragma mark - Player and source | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | - (void)setSrc:(NSDictionary *)source |  |  |  | - (void)setSrc:(NSDictionary *)source { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     [self removePlayerLayer]; |  |  |  |     [self removePlayerLayer]; | 
			
		
	
		
		
			
				
					
					|  |  |  |     [self removePlayerTimeObserver]; |  |  |  |     [self removePlayerTimeObserver]; | 
			
		
	
		
		
			
				
					
					|  |  |  |     [self removePlayerItemObservers]; |  |  |  |     [self removePlayerItemObservers]; | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -407,8 +388,7 @@ static int const RCTVideoUnset = -1; | 
			
		
	
		
		
			
				
					
					|  |  |  |     return nil; |  |  |  |     return nil; | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | - (void)playerItemPrepareText:(AVAsset *)asset assetOptions:(NSDictionary * __nullable)assetOptions withCallback:(void(^)(AVPlayerItem *))handler |  |  |  | - (void)playerItemPrepareText:(AVAsset *)asset assetOptions:(NSDictionary *__nullable)assetOptions withCallback:(void (^)(AVPlayerItem *))handler { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     if (!_textTracks) { |  |  |  |     if (!_textTracks) { | 
			
		
	
		
		
			
				
					
					|  |  |  |         handler([AVPlayerItem playerItemWithAsset:asset]); |  |  |  |         handler([AVPlayerItem playerItemWithAsset:asset]); | 
			
		
	
		
		
			
				
					
					|  |  |  |         return; |  |  |  |         return; | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -458,8 +438,7 @@ static int const RCTVideoUnset = -1; | 
			
		
	
		
		
			
				
					
					|  |  |  |     handler([AVPlayerItem playerItemWithAsset:mixComposition]); |  |  |  |     handler([AVPlayerItem playerItemWithAsset:mixComposition]); | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | - (void)playerItemForSource:(NSDictionary *)source withCallback:(void(^)(AVPlayerItem *))handler |  |  |  | - (void)playerItemForSource:(NSDictionary *)source withCallback:(void (^)(AVPlayerItem *))handler { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     bool isNetwork = [RCTConvert BOOL:[source objectForKey:@"isNetwork"]]; |  |  |  |     bool isNetwork = [RCTConvert BOOL:[source objectForKey:@"isNetwork"]]; | 
			
		
	
		
		
			
				
					
					|  |  |  |     bool isAsset = [RCTConvert BOOL:[source objectForKey:@"isAsset"]]; |  |  |  |     bool isAsset = [RCTConvert BOOL:[source objectForKey:@"isAsset"]]; | 
			
		
	
		
		
			
				
					
					|  |  |  |     NSString *uri = [source objectForKey:@"uri"]; |  |  |  |     NSString *uri = [source objectForKey:@"uri"]; | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -561,8 +540,7 @@ static int const RCTVideoUnset = -1; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | #endif |  |  |  | #endif | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | - (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) { | 
			
		
	
		
		
			
				
					
					|  |  |  |         // When timeMetadata is read the event onTimedMetadata is triggered |  |  |  |         // When timeMetadata is read the event onTimedMetadata is triggered | 
			
		
	
		
		
			
				
					
					|  |  |  |         if ([keyPath isEqualToString:timedMetadata]) { |  |  |  |         if ([keyPath isEqualToString:timedMetadata]) { | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -608,8 +586,7 @@ static int const RCTVideoUnset = -1; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     if ((videoTrack.naturalSize.width == preferredTransform.tx |  |  |  |                     if ((videoTrack.naturalSize.width == preferredTransform.tx | 
			
		
	
		
		
			
				
					
					|  |  |  |                             && videoTrack.naturalSize.height == preferredTransform.ty) |  |  |  |                             && videoTrack.naturalSize.height == preferredTransform.ty) | 
			
		
	
		
		
			
				
					
					|  |  |  |               || (preferredTransform.tx == 0 && preferredTransform.ty == 0)) |  |  |  |                             || (preferredTransform.tx == 0 && preferredTransform.ty == 0)) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |           { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |                         orientation = @"landscape"; |  |  |  |                         orientation = @"landscape"; | 
			
		
	
		
		
			
				
					
					|  |  |  |                     } else { |  |  |  |                     } else { | 
			
		
	
		
		
			
				
					
					|  |  |  |                         orientation = @"portrait"; |  |  |  |                         orientation = @"portrait"; | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -673,8 +650,7 @@ static int const RCTVideoUnset = -1; | 
			
		
	
		
		
			
				
					
					|  |  |  |                 } |  |  |  |                 } | 
			
		
	
		
		
			
				
					
					|  |  |  |                 _playbackStalled = NO; |  |  |  |                 _playbackStalled = NO; | 
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |         } else if ([keyPath isEqualToString:externalPlaybackActive]) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     else if([keyPath isEqualToString:externalPlaybackActive]) { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |             if (self.onVideoExternalPlaybackChange) { |  |  |  |             if (self.onVideoExternalPlaybackChange) { | 
			
		
	
		
		
			
				
					
					|  |  |  |                 self.onVideoExternalPlaybackChange(@{@"isExternalPlaybackActive": [NSNumber numberWithBool:_player.isExternalPlaybackActive], |  |  |  |                 self.onVideoExternalPlaybackChange(@{@"isExternalPlaybackActive": [NSNumber numberWithBool:_player.isExternalPlaybackActive], | 
			
		
	
		
		
			
				
					
					|  |  |  |                         @"target": self.reactTag}); |  |  |  |                         @"target": self.reactTag}); | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -685,8 +661,7 @@ static int const RCTVideoUnset = -1; | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | - (void)attachListeners |  |  |  | - (void)attachListeners { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     // listen for end of file |  |  |  |     // listen for end of file | 
			
		
	
		
		
			
				
					
					|  |  |  |     [[NSNotificationCenter defaultCenter] removeObserver:self |  |  |  |     [[NSNotificationCenter defaultCenter] removeObserver:self | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                     name:AVPlayerItemDidPlayToEndTimeNotification |  |  |  |                                                     name:AVPlayerItemDidPlayToEndTimeNotification | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -705,16 +680,14 @@ static int const RCTVideoUnset = -1; | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                object:nil]; |  |  |  |                                                object:nil]; | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | - (void)playbackStalled:(NSNotification *)notification |  |  |  | - (void)playbackStalled:(NSNotification *)notification { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     if (self.onPlaybackStalled) { |  |  |  |     if (self.onPlaybackStalled) { | 
			
		
	
		
		
			
				
					
					|  |  |  |         self.onPlaybackStalled(@{@"target": self.reactTag}); |  |  |  |         self.onPlaybackStalled(@{@"target": self.reactTag}); | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     _playbackStalled = YES; |  |  |  |     _playbackStalled = YES; | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | - (void)playerItemDidReachEnd:(NSNotification *)notification |  |  |  | - (void)playerItemDidReachEnd:(NSNotification *)notification { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     if (self.onVideoEnd) { |  |  |  |     if (self.onVideoEnd) { | 
			
		
	
		
		
			
				
					
					|  |  |  |         self.onVideoEnd(@{@"target": self.reactTag}); |  |  |  |         self.onVideoEnd(@{@"target": self.reactTag}); | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -730,43 +703,34 @@ static int const RCTVideoUnset = -1; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | #pragma mark - Prop setters |  |  |  | #pragma mark - Prop setters | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | - (void)setResizeMode:(NSString*)mode |  |  |  | - (void)setResizeMode:(NSString *)mode { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  |     if (_controls) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |   if( _controls ) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   { |  |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |         _playerViewController.videoGravity = mode; |  |  |  |         _playerViewController.videoGravity = mode; | 
			
		
	
		
		
			
				
					
					|  |  |  |   } |  |  |  |     } else { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |   else |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |         _playerLayer.videoGravity = mode; |  |  |  |         _playerLayer.videoGravity = mode; | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     _resizeMode = mode; |  |  |  |     _resizeMode = mode; | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | - (void)setPlayInBackground:(BOOL)playInBackground |  |  |  | - (void)setPlayInBackground:(BOOL)playInBackground { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     _playInBackground = playInBackground; |  |  |  |     _playInBackground = playInBackground; | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | - (void)setAllowsExternalPlayback:(BOOL)allowsExternalPlayback |  |  |  | - (void)setAllowsExternalPlayback:(BOOL)allowsExternalPlayback { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     _allowsExternalPlayback = allowsExternalPlayback; |  |  |  |     _allowsExternalPlayback = allowsExternalPlayback; | 
			
		
	
		
		
			
				
					
					|  |  |  |     _player.allowsExternalPlayback = _allowsExternalPlayback; |  |  |  |     _player.allowsExternalPlayback = _allowsExternalPlayback; | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | - (void)setPlayWhenInactive:(BOOL)playWhenInactive |  |  |  | - (void)setPlayWhenInactive:(BOOL)playWhenInactive { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     _playWhenInactive = playWhenInactive; |  |  |  |     _playWhenInactive = playWhenInactive; | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | - (void)setIgnoreSilentSwitch:(NSString *)ignoreSilentSwitch |  |  |  | - (void)setIgnoreSilentSwitch:(NSString *)ignoreSilentSwitch { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     _ignoreSilentSwitch = ignoreSilentSwitch; |  |  |  |     _ignoreSilentSwitch = ignoreSilentSwitch; | 
			
		
	
		
		
			
				
					
					|  |  |  |     [self applyModifiers]; |  |  |  |     [self applyModifiers]; | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | - (void)setPaused:(BOOL)paused |  |  |  | - (void)setPaused:(BOOL)paused { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     if (paused) { |  |  |  |     if (paused) { | 
			
		
	
		
		
			
				
					
					|  |  |  |         [_player pause]; |  |  |  |         [_player pause]; | 
			
		
	
		
		
			
				
					
					|  |  |  |         [_player setRate:0.0]; |  |  |  |         [_player setRate:0.0]; | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -783,13 +747,11 @@ static int const RCTVideoUnset = -1; | 
			
		
	
		
		
			
				
					
					|  |  |  |     _paused = paused; |  |  |  |     _paused = paused; | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | - (float)getCurrentTime |  |  |  | - (float)getCurrentTime { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     return _playerItem != NULL ? CMTimeGetSeconds(_playerItem.currentTime) : 0; |  |  |  |     return _playerItem != NULL ? CMTimeGetSeconds(_playerItem.currentTime) : 0; | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | - (void)setCurrentTime:(float)currentTime |  |  |  | - (void)setCurrentTime:(float)currentTime { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     NSDictionary *info = @{ |  |  |  |     NSDictionary *info = @{ | 
			
		
	
		
		
			
				
					
					|  |  |  |             @"time": [NSNumber numberWithFloat:currentTime], |  |  |  |             @"time": [NSNumber numberWithFloat:currentTime], | 
			
		
	
		
		
			
				
					
					|  |  |  |             @"tolerance": [NSNumber numberWithInt:100] |  |  |  |             @"tolerance": [NSNumber numberWithInt:100] | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -797,8 +759,7 @@ static int const RCTVideoUnset = -1; | 
			
		
	
		
		
			
				
					
					|  |  |  |     [self setSeek:info]; |  |  |  |     [self setSeek:info]; | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | - (void)setSeek:(NSDictionary *)info |  |  |  | - (void)setSeek:(NSDictionary *)info { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     NSNumber *seekTime = info[@"time"]; |  |  |  |     NSNumber *seekTime = info[@"time"]; | 
			
		
	
		
		
			
				
					
					|  |  |  |     NSNumber *seekTolerance = info[@"tolerance"]; |  |  |  |     NSNumber *seekTolerance = info[@"tolerance"]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -840,26 +801,22 @@ static int const RCTVideoUnset = -1; | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | - (void)setRate:(float)rate |  |  |  | - (void)setRate:(float)rate { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     _rate = rate; |  |  |  |     _rate = rate; | 
			
		
	
		
		
			
				
					
					|  |  |  |     [self applyModifiers]; |  |  |  |     [self applyModifiers]; | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | - (void)setMuted:(BOOL)muted |  |  |  | - (void)setMuted:(BOOL)muted { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     _muted = muted; |  |  |  |     _muted = muted; | 
			
		
	
		
		
			
				
					
					|  |  |  |     [self applyModifiers]; |  |  |  |     [self applyModifiers]; | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | - (void)setVolume:(float)volume |  |  |  | - (void)setVolume:(float)volume { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     _volume = volume; |  |  |  |     _volume = volume; | 
			
		
	
		
		
			
				
					
					|  |  |  |     [self applyModifiers]; |  |  |  |     [self applyModifiers]; | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | - (void)applyModifiers |  |  |  | - (void)applyModifiers { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     if (_muted) { |  |  |  |     if (_muted) { | 
			
		
	
		
		
			
				
					
					|  |  |  |         [_player setVolume:0]; |  |  |  |         [_player setVolume:0]; | 
			
		
	
		
		
			
				
					
					|  |  |  |         [_player setMuted:YES]; |  |  |  |         [_player setMuted:YES]; | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -883,8 +840,7 @@ static int const RCTVideoUnset = -1; | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | - (void)setMediaSelectionTrackForCharacteristic:(AVMediaCharacteristic)characteristic |  |  |  | - (void)setMediaSelectionTrackForCharacteristic:(AVMediaCharacteristic)characteristic | 
			
		
	
		
		
			
				
					
					|  |  |  |                                    withCriteria:(NSDictionary *)criteria |  |  |  |                                    withCriteria:(NSDictionary *)criteria { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     NSString *type = criteria[@"type"]; |  |  |  |     NSString *type = criteria[@"type"]; | 
			
		
	
		
		
			
				
					
					|  |  |  |     AVMediaSelectionGroup *group = [_player.currentItem.asset |  |  |  |     AVMediaSelectionGroup *group = [_player.currentItem.asset | 
			
		
	
		
		
			
				
					
					|  |  |  |             mediaSelectionGroupForMediaCharacteristic:characteristic]; |  |  |  |             mediaSelectionGroupForMediaCharacteristic:characteristic]; | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -1055,16 +1011,14 @@ static int const RCTVideoUnset = -1; | 
			
		
	
		
		
			
				
					
					|  |  |  |     [_player.currentItem selectMediaOption:mediaOption inMediaSelectionGroup:group]; |  |  |  |     [_player.currentItem selectMediaOption:mediaOption inMediaSelectionGroup:group]; | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | - (void)setTextTracks:(NSArray*) textTracks; |  |  |  | - (void)setTextTracks:(NSArray *)textTracks; { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     _textTracks = textTracks; |  |  |  |     _textTracks = textTracks; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     // in case textTracks was set after selectedTextTrack |  |  |  |     // in case textTracks was set after selectedTextTrack | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (_selectedTextTrack) [self setSelectedTextTrack:_selectedTextTrack]; |  |  |  |     if (_selectedTextTrack) [self setSelectedTextTrack:_selectedTextTrack]; | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | - (NSArray *)getAudioTrackInfo |  |  |  | - (NSArray *)getAudioTrackInfo { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     NSMutableArray *audioTracks = [[NSMutableArray alloc] init]; |  |  |  |     NSMutableArray *audioTracks = [[NSMutableArray alloc] init]; | 
			
		
	
		
		
			
				
					
					|  |  |  |     AVMediaSelectionGroup *group = [_player.currentItem.asset |  |  |  |     AVMediaSelectionGroup *group = [_player.currentItem.asset | 
			
		
	
		
		
			
				
					
					|  |  |  |             mediaSelectionGroupForMediaCharacteristic:AVMediaCharacteristicAudible]; |  |  |  |             mediaSelectionGroupForMediaCharacteristic:AVMediaCharacteristicAudible]; | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -1086,8 +1040,7 @@ static int const RCTVideoUnset = -1; | 
			
		
	
		
		
			
				
					
					|  |  |  |     return audioTracks; |  |  |  |     return audioTracks; | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | - (NSArray *)getTextTrackInfo |  |  |  | - (NSArray *)getTextTrackInfo { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     // if sideloaded, textTracks will already be set |  |  |  |     // if sideloaded, textTracks will already be set | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (_textTracks) return _textTracks; |  |  |  |     if (_textTracks) return _textTracks; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -1113,17 +1066,14 @@ static int const RCTVideoUnset = -1; | 
			
		
	
		
		
			
				
					
					|  |  |  |     return textTracks; |  |  |  |     return textTracks; | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | - (BOOL)getFullscreen |  |  |  | - (BOOL)getFullscreen { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     return _fullscreenPlayerPresented; |  |  |  |     return _fullscreenPlayerPresented; | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | - (void)setFullscreen:(BOOL)fullscreen { |  |  |  | - (void)setFullscreen:(BOOL)fullscreen { | 
			
		
	
		
		
			
				
					
					|  |  |  |   if( fullscreen && !_fullscreenPlayerPresented && _player ) |  |  |  |     if (fullscreen && !_fullscreenPlayerPresented && _player) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |   { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |         // Ensure player view controller is not null |  |  |  |         // Ensure player view controller is not null | 
			
		
	
		
		
			
				
					
					|  |  |  |     if( !_playerViewController ) |  |  |  |         if (!_playerViewController) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |             [self usePlayerViewController]; |  |  |  |             [self usePlayerViewController]; | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |         // Set presentation style to fullscreen |  |  |  |         // Set presentation style to fullscreen | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -1131,17 +1081,14 @@ static int const RCTVideoUnset = -1; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         // Find the nearest view controller |  |  |  |         // Find the nearest view controller | 
			
		
	
		
		
			
				
					
					|  |  |  |         UIViewController *viewController = [self firstAvailableUIViewController]; |  |  |  |         UIViewController *viewController = [self firstAvailableUIViewController]; | 
			
		
	
		
		
			
				
					
					|  |  |  |     if( !viewController ) |  |  |  |         if (!viewController) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |             UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow]; |  |  |  |             UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow]; | 
			
		
	
		
		
			
				
					
					|  |  |  |             viewController = keyWindow.rootViewController; |  |  |  |             viewController = keyWindow.rootViewController; | 
			
		
	
		
		
			
				
					
					|  |  |  |       if( viewController.childViewControllers.count > 0 ) |  |  |  |             if (viewController.childViewControllers.count > 0) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |       { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |                 viewController = viewController.childViewControllers.lastObject; |  |  |  |                 viewController = viewController.childViewControllers.lastObject; | 
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |     if( viewController ) |  |  |  |         if (viewController) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |             _presentingViewController = viewController; |  |  |  |             _presentingViewController = viewController; | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (self.onVideoFullscreenPlayerWillPresent) { |  |  |  |             if (self.onVideoFullscreenPlayerWillPresent) { | 
			
		
	
		
		
			
				
					
					|  |  |  |                 self.onVideoFullscreenPlayerWillPresent(@{@"target": self.reactTag}); |  |  |  |                 self.onVideoFullscreenPlayerWillPresent(@{@"target": self.reactTag}); | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -1154,9 +1101,7 @@ static int const RCTVideoUnset = -1; | 
			
		
	
		
		
			
				
					
					|  |  |  |                 } |  |  |  |                 } | 
			
		
	
		
		
			
				
					
					|  |  |  |             }]; |  |  |  |             }]; | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |   } |  |  |  |     } else if (!fullscreen && _fullscreenPlayerPresented) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |   else if ( !fullscreen && _fullscreenPlayerPresented ) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |         [self videoPlayerViewControllerWillDismiss:_playerViewController]; |  |  |  |         [self videoPlayerViewControllerWillDismiss:_playerViewController]; | 
			
		
	
		
		
			
				
					
					|  |  |  |         [_presentingViewController dismissViewControllerAnimated:true completion:^{ |  |  |  |         [_presentingViewController dismissViewControllerAnimated:true completion:^{ | 
			
		
	
		
		
			
				
					
					|  |  |  |             [self videoPlayerViewControllerDidDismiss:_playerViewController]; |  |  |  |             [self videoPlayerViewControllerDidDismiss:_playerViewController]; | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -1208,10 +1153,8 @@ static int const RCTVideoUnset = -1; | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | - (void)usePlayerViewController |  |  |  | - (void)usePlayerViewController { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  |     if (_player) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |   if( _player ) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   { |  |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |         _playerViewController = [self createPlayerViewController:_player withPlayerItem:_playerItem]; |  |  |  |         _playerViewController = [self createPlayerViewController:_player withPlayerItem:_playerItem]; | 
			
		
	
		
		
			
				
					
					|  |  |  |         // to prevent video from being animated when resizeMode is 'cover' |  |  |  |         // to prevent video from being animated when resizeMode is 'cover' | 
			
		
	
		
		
			
				
					
					|  |  |  |         // resize mode must be set before subview is added |  |  |  |         // resize mode must be set before subview is added | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -1220,10 +1163,8 @@ static int const RCTVideoUnset = -1; | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | - (void)usePlayerLayer |  |  |  | - (void)usePlayerLayer { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  |     if (_player) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |   if( _player ) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   { |  |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |         _playerLayer = [AVPlayerLayer playerLayerWithPlayer:_player]; |  |  |  |         _playerLayer = [AVPlayerLayer playerLayerWithPlayer:_player]; | 
			
		
	
		
		
			
				
					
					|  |  |  |         _playerLayer.frame = self.bounds; |  |  |  |         _playerLayer.frame = self.bounds; | 
			
		
	
		
		
			
				
					
					|  |  |  |         _playerLayer.needsDisplayOnBoundsChange = YES; |  |  |  |         _playerLayer.needsDisplayOnBoundsChange = YES; | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -1239,18 +1180,13 @@ static int const RCTVideoUnset = -1; | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | - (void)setControls:(BOOL)controls |  |  |  | - (void)setControls:(BOOL)controls { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  |     if (_controls != controls || (!_playerLayer && !_playerViewController)) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |   if( _controls != controls || (!_playerLayer && !_playerViewController) ) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   { |  |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |         _controls = controls; |  |  |  |         _controls = controls; | 
			
		
	
		
		
			
				
					
					|  |  |  |     if( _controls ) |  |  |  |         if (_controls) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |             [self removePlayerLayer]; |  |  |  |             [self removePlayerLayer]; | 
			
		
	
		
		
			
				
					
					|  |  |  |             [self usePlayerViewController]; |  |  |  |             [self usePlayerViewController]; | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |         } else { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     else |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |             [_playerViewController.view removeFromSuperview]; |  |  |  |             [_playerViewController.view removeFromSuperview]; | 
			
		
	
		
		
			
				
					
					|  |  |  |             _playerViewController = nil; |  |  |  |             _playerViewController = nil; | 
			
		
	
		
		
			
				
					
					|  |  |  |             [self usePlayerLayer]; |  |  |  |             [self usePlayerLayer]; | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -1258,8 +1194,7 @@ static int const RCTVideoUnset = -1; | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | - (void)setProgressUpdateInterval:(float)progressUpdateInterval |  |  |  | - (void)setProgressUpdateInterval:(float)progressUpdateInterval { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     _progressUpdateInterval = progressUpdateInterval; |  |  |  |     _progressUpdateInterval = progressUpdateInterval; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (_timeObserver) { |  |  |  |     if (_timeObserver) { | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -1268,8 +1203,7 @@ static int const RCTVideoUnset = -1; | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | - (void)removePlayerLayer |  |  |  | - (void)removePlayerLayer { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     [_playerLayer removeFromSuperlayer]; |  |  |  |     [_playerLayer removeFromSuperlayer]; | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (_playerLayerObserverSet) { |  |  |  |     if (_playerLayerObserverSet) { | 
			
		
	
		
		
			
				
					
					|  |  |  |         [_playerLayer removeObserver:self forKeyPath:readyForDisplayKeyPath]; |  |  |  |         [_playerLayer removeObserver:self forKeyPath:readyForDisplayKeyPath]; | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -1280,18 +1214,14 @@ static int const RCTVideoUnset = -1; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | #pragma mark - RCTVideoPlayerViewControllerDelegate |  |  |  | #pragma mark - RCTVideoPlayerViewControllerDelegate | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | - (void)videoPlayerViewControllerWillDismiss:(AVPlayerViewController *)playerViewController |  |  |  | - (void)videoPlayerViewControllerWillDismiss:(AVPlayerViewController *)playerViewController { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  |     if (_playerViewController == playerViewController && _fullscreenPlayerPresented && self.onVideoFullscreenPlayerWillDismiss) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |   if (_playerViewController == playerViewController && _fullscreenPlayerPresented && self.onVideoFullscreenPlayerWillDismiss) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   { |  |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |         self.onVideoFullscreenPlayerWillDismiss(@{@"target": self.reactTag}); |  |  |  |         self.onVideoFullscreenPlayerWillDismiss(@{@"target": self.reactTag}); | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | - (void)videoPlayerViewControllerDidDismiss:(AVPlayerViewController *)playerViewController |  |  |  | - (void)videoPlayerViewControllerDidDismiss:(AVPlayerViewController *)playerViewController { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  |     if (_playerViewController == playerViewController && _fullscreenPlayerPresented) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |   if (_playerViewController == playerViewController && _fullscreenPlayerPresented) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   { |  |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |         _fullscreenPlayerPresented = false; |  |  |  |         _fullscreenPlayerPresented = false; | 
			
		
	
		
		
			
				
					
					|  |  |  |         _presentingViewController = nil; |  |  |  |         _presentingViewController = nil; | 
			
		
	
		
		
			
				
					
					|  |  |  |         _playerViewController = nil; |  |  |  |         _playerViewController = nil; | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -1304,54 +1234,41 @@ static int const RCTVideoUnset = -1; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | #pragma mark - React View Management |  |  |  | #pragma mark - React View Management | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | - (void)insertReactSubview:(UIView *)view atIndex:(NSInteger)atIndex |  |  |  | - (void)insertReactSubview:(UIView *)view atIndex:(NSInteger)atIndex { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     // We are early in the game and somebody wants to set a subview. |  |  |  |     // We are early in the game and somebody wants to set a subview. | 
			
		
	
		
		
			
				
					
					|  |  |  |     // That can only be in the context of playerViewController. |  |  |  |     // That can only be in the context of playerViewController. | 
			
		
	
		
		
			
				
					
					|  |  |  |   if( !_controls && !_playerLayer && !_playerViewController ) |  |  |  |     if (!_controls && !_playerLayer && !_playerViewController) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |   { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |         [self setControls:true]; |  |  |  |         [self setControls:true]; | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   if( _controls ) |  |  |  |     if (_controls) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |   { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |         view.frame = self.bounds; |  |  |  |         view.frame = self.bounds; | 
			
		
	
		
		
			
				
					
					|  |  |  |         [_playerViewController.contentOverlayView insertSubview:view atIndex:atIndex]; |  |  |  |         [_playerViewController.contentOverlayView insertSubview:view atIndex:atIndex]; | 
			
		
	
		
		
			
				
					
					|  |  |  |   } |  |  |  |     } else { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |   else |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |         RCTLogError(@"video cannot have any subviews"); |  |  |  |         RCTLogError(@"video cannot have any subviews"); | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     return; |  |  |  |     return; | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | - (void)removeReactSubview:(UIView *)subview |  |  |  | - (void)removeReactSubview:(UIView *)subview { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  |     if (_controls) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |   if( _controls ) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   { |  |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |         [subview removeFromSuperview]; |  |  |  |         [subview removeFromSuperview]; | 
			
		
	
		
		
			
				
					
					|  |  |  |   } |  |  |  |     } else { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |   else |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |         RCTLogError(@"video cannot have any subviews"); |  |  |  |         RCTLogError(@"video cannot have any subviews"); | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     return; |  |  |  |     return; | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | - (void)layoutSubviews |  |  |  | - (void)layoutSubviews { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     [super layoutSubviews]; |  |  |  |     [super layoutSubviews]; | 
			
		
	
		
		
			
				
					
					|  |  |  |   if( _controls ) |  |  |  |     if (_controls) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |   { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |         _playerViewController.view.frame = self.bounds; |  |  |  |         _playerViewController.view.frame = self.bounds; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         // also adjust all subviews of contentOverlayView |  |  |  |         // also adjust all subviews of contentOverlayView | 
			
		
	
		
		
			
				
					
					|  |  |  |         for (UIView *subview in _playerViewController.contentOverlayView.subviews) { |  |  |  |         for (UIView *subview in _playerViewController.contentOverlayView.subviews) { | 
			
		
	
		
		
			
				
					
					|  |  |  |             subview.frame = self.bounds; |  |  |  |             subview.frame = self.bounds; | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |   } |  |  |  |     } else { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |   else |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |         [CATransaction begin]; |  |  |  |         [CATransaction begin]; | 
			
		
	
		
		
			
				
					
					|  |  |  |         [CATransaction setAnimationDuration:0]; |  |  |  |         [CATransaction setAnimationDuration:0]; | 
			
		
	
		
		
			
				
					
					|  |  |  |         _playerLayer.frame = self.bounds; |  |  |  |         _playerLayer.frame = self.bounds; | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -1361,8 +1278,7 @@ static int const RCTVideoUnset = -1; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | #pragma mark - Lifecycle |  |  |  | #pragma mark - Lifecycle | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | - (void)removeFromSuperview |  |  |  | - (void)removeFromSuperview { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     [_player pause]; |  |  |  |     [_player pause]; | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (_playbackRateObserverRegistered) { |  |  |  |     if (_playbackRateObserverRegistered) { | 
			
		
	
		
		
			
				
					
					|  |  |  |         [_player removeObserver:self forKeyPath:playbackRate context:nil]; |  |  |  |         [_player removeObserver:self forKeyPath:playbackRate context:nil]; | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -1388,4 +1304,76 @@ static int const RCTVideoUnset = -1; | 
			
		
	
		
		
			
				
					
					|  |  |  |     [super removeFromSuperview]; |  |  |  |     [super removeFromSuperview]; | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | - (void)save:(NSDictionary *)options resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     AVAsset *asset = _playerItem.asset; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     if (asset != nil) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         AVAssetExportSession *exportSession = [AVAssetExportSession | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 exportSessionWithAsset:asset presetName:AVAssetExportPresetHighestQuality]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         if (exportSession != nil) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             NSString *path = nil; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             NSArray *array = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             path = [self generatePathInDirectory:[[self cacheDirectoryPath] stringByAppendingPathComponent:@"Filter"] | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                    withExtension:@".mp4"]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             NSURL *url = [NSURL fileURLWithPath:path]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             exportSession.outputFileType = AVFileTypeMPEG4; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             exportSession.outputURL = url; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             exportSession.videoComposition = _playerItem.videoComposition; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             exportSession.shouldOptimizeForNetworkUse = true; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             [exportSession exportAsynchronouslyWithCompletionHandler:^{ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 switch ([exportSession status]) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     case AVAssetExportSessionStatusFailed: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                         reject(@"ERROR_COULD_NOT_EXPORT_VIDEO", @"Could not export video", exportSession.error); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                         break; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     case AVAssetExportSessionStatusCancelled: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                         reject(@"ERROR_EXPORT_SESSION_CANCELLED", @"Export session was cancelled", exportSession.error); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                         break; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     default: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                         resolve(@{@"uri": url.absoluteString}); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                         break; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             }]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } else { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             reject(@"ERROR_COULD_NOT_CREATE_EXPORT_SESSION", @"Could not create export session", nil); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     } else { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         reject(@"ERROR_ASSET_NIL", @"Asset is nil", nil); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | - (BOOL)ensureDirExistsWithPath:(NSString *)path { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     BOOL isDir = NO; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     NSError *error; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     BOOL exists = [[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&isDir]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     if (!(exists && isDir)) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         [[NSFileManager defaultManager] createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:&error]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         if (error) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             return NO; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     return YES; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | - (NSString *)generatePathInDirectory:(NSString *)directory withExtension:(NSString *)extension { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     NSString *fileName = [[[NSUUID UUID] UUIDString] stringByAppendingString:extension]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     [self ensureDirExistsWithPath:directory]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     return [directory stringByAppendingPathComponent:fileName]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | - (NSString *)cacheDirectoryPath { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     NSArray *array = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     return array[0]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | @end |  |  |  | @end | 
			
		
	
	
		
		
			
				
					
					| 
						
						
						
						 |  |   |