Commit fbeca99c authored by Nicolas Gonzalez's avatar Nicolas Gonzalez
Browse files

undo code formatting

parent afba8245
Loading
Loading
Loading
Loading
+215 −131
Changes for ios/Video/RCTVideo.m: 215 added lines, 131 removed lines.
Original line number Diff line number Diff line
@@ -13,7 +13,6 @@ static NSString *const readyForDisplayKeyPath = @"readyForDisplay";
static NSString *const playbackRate = @"rate";
static NSString *const timedMetadata = @"timedMetadata";
static NSString *const externalPlaybackActive = @"externalPlaybackActive";
static NSDictionary *filters = nil;

static int const RCTVideoUnset = -1;

@@ -23,7 +22,8 @@ static int const RCTVideoUnset = -1;
#define DebugLog(...) (void)0
#endif

@implementation RCTVideo {
@implementation RCTVideo
{
    AVPlayer *_player;
    AVPlayerItem *_playerItem;
    BOOL _playerItemObserversSet;
@@ -73,18 +73,9 @@ static int const RCTVideoUnset = -1;
#endif
}

- (instancetype)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher {
- (instancetype)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher
{
    if ((self = [super init])) {

        filters = @{
                @"Normal": @"",
                @"Country": @"CISepiaTone",
                @"Winter": @"CIPhotoEffectProcess",
                @"Black N White": @"CIPhotoEffectNoir",
                @"Sunrise": @"CIPhotoEffectTransfer",
                @"Artistic": @"CIColorPosterize",
        };

        _eventDispatcher = eventDispatcher;

        _playbackRateObserverRegistered = NO;
@@ -148,40 +139,45 @@ static int const RCTVideoUnset = -1;
 **  Get the duration for a AVPlayerItem.
 ** ------------------------------------------------------- */

- (CMTime)playerItemDuration {
- (CMTime)playerItemDuration
{
    AVPlayerItem *playerItem = [_player currentItem];
    if (playerItem.status == AVPlayerItemStatusReadyToPlay) {
    if (playerItem.status == AVPlayerItemStatusReadyToPlay)
    {
        return([playerItem duration]);
    }

    return(kCMTimeInvalid);
}

- (CMTimeRange)playerItemSeekableTimeRange {
- (CMTimeRange)playerItemSeekableTimeRange
{
    AVPlayerItem *playerItem = [_player currentItem];
    if (playerItem.status == AVPlayerItemStatusReadyToPlay) {
    if (playerItem.status == AVPlayerItemStatusReadyToPlay)
    {
        return [playerItem seekableTimeRanges].firstObject.CMTimeRangeValue;
    }

    return (kCMTimeRangeZero);
}

- (void)addPlayerTimeObserver {
-(void)addPlayerTimeObserver
{
    const Float64 progressUpdateIntervalMS = _progressUpdateInterval / 1000;
    // @see endScrubbing in AVPlayerDemoPlaybackViewController.m
    // of https://developer.apple.com/library/ios/samplecode/AVPlayerDemo/Introduction/Intro.html
    __weak RCTVideo *weakSelf = self;
    _timeObserver = [_player addPeriodicTimeObserverForInterval:CMTimeMakeWithSeconds(progressUpdateIntervalMS, NSEC_PER_SEC)
                                                          queue:NULL
                                                     usingBlock:^(CMTime time) {
                                                         [weakSelf sendProgressUpdate];
                                                     }
                                                     usingBlock:^(CMTime time) { [weakSelf sendProgressUpdate]; }
    ];
}

/* Cancels the previously registered time observer. */
- (void)removePlayerTimeObserver {
    if (_timeObserver) {
-(void)removePlayerTimeObserver
{
    if (_timeObserver)
    {
        [_player removeTimeObserver:_timeObserver];
        _timeObserver = nil;
    }
@@ -189,7 +185,8 @@ static int const RCTVideoUnset = -1;

#pragma mark - Progress

- (void)dealloc {
- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    [self removePlayerLayer];
    [self removePlayerItemObservers];
@@ -198,21 +195,24 @@ static int const RCTVideoUnset = -1;

#pragma mark - App lifecycle handlers

- (void)applicationWillResignActive:(NSNotification *)notification {
- (void)applicationWillResignActive:(NSNotification *)notification
{
    if (_playInBackground || _playWhenInactive || _paused) return;

    [_player pause];
    [_player setRate:0.0];
}

- (void)applicationDidEnterBackground:(NSNotification *)notification {
- (void)applicationDidEnterBackground:(NSNotification *)notification
{
    if (_playInBackground) {
        // Needed to play sound in background. See https://developer.apple.com/library/ios/qa/qa1668/_index.html
        [_playerLayer setPlayer:nil];
    }
}

- (void)applicationWillEnterForeground:(NSNotification *)notification {
- (void)applicationWillEnterForeground:(NSNotification *)notification
{
    [self applyModifiers];
    if (_playInBackground) {
        [_playerLayer setPlayer:_player];
@@ -221,7 +221,8 @@ static int const RCTVideoUnset = -1;

#pragma mark - Audio events

- (void)audioRouteChanged:(NSNotification *)notification {
- (void)audioRouteChanged:(NSNotification *)notification
{
    NSNumber *reason = [[notification userInfo] objectForKey:AVAudioSessionRouteChangeReasonKey];
    NSNumber *previousRoute = [[notification userInfo] objectForKey:AVAudioSessionRouteChangePreviousRouteKey];
    if (reason.unsignedIntValue == AVAudioSessionRouteChangeReasonOldDeviceUnavailable) {
@@ -231,7 +232,8 @@ static int const RCTVideoUnset = -1;

#pragma mark - Progress

- (void)sendProgressUpdate {
- (void)sendProgressUpdate
{
    AVPlayerItem *video = [_player currentItem];
    if (video == nil || video.status != AVPlayerItemStatusReadyToPlay) {
        return;
@@ -265,7 +267,8 @@ static int const RCTVideoUnset = -1;
 *
 * \returns The playable duration of the current player item in seconds.
 */
- (NSNumber *)calculatePlayableDuration {
- (NSNumber *)calculatePlayableDuration
{
    AVPlayerItem *video = _player.currentItem;
    if (video.status == AVPlayerItemStatusReadyToPlay) {
        __block CMTimeRange effectiveTimeRange;
@@ -284,15 +287,18 @@ static int const RCTVideoUnset = -1;
    return [NSNumber numberWithInteger:0];
}

- (NSNumber *)calculateSeekableDuration {
- (NSNumber *)calculateSeekableDuration
{
    CMTimeRange timeRange = [self playerItemSeekableTimeRange];
    if (CMTIME_IS_NUMERIC(timeRange.duration)) {
    if (CMTIME_IS_NUMERIC(timeRange.duration))
    {
        return [NSNumber numberWithFloat:CMTimeGetSeconds(timeRange.duration)];
    }
    return [NSNumber numberWithInteger:0];
}

- (void)addPlayerItemObservers {
- (void)addPlayerItemObservers
{
    [_playerItem addObserver:self forKeyPath:statusKeyPath options:0 context:nil];
    [_playerItem addObserver:self forKeyPath:playbackBufferEmptyKeyPath options:0 context:nil];
    [_playerItem addObserver:self forKeyPath:playbackLikelyToKeepUpKeyPath options:0 context:nil];
@@ -303,7 +309,8 @@ static int const RCTVideoUnset = -1;
/* Fixes https://github.com/brentvatne/react-native-video/issues/43
 * Crashes caused when trying to remove the observer when there is no
 * observer set */
- (void)removePlayerItemObservers {
- (void)removePlayerItemObservers
{
    if (_playerItemObserversSet) {
        [_playerItem removeObserver:self forKeyPath:statusKeyPath];
        [_playerItem removeObserver:self forKeyPath:playbackBufferEmptyKeyPath];
@@ -315,7 +322,8 @@ static int const RCTVideoUnset = -1;

#pragma mark - Player and source

- (void)setSrc:(NSDictionary *)source {
- (void)setSrc:(NSDictionary *)source
{
    [self removePlayerLayer];
    [self removePlayerTimeObserver];
    [self removePlayerItemObservers];
@@ -388,7 +396,8 @@ static int const RCTVideoUnset = -1;
    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) {
        handler([AVPlayerItem playerItemWithAsset:asset]);
        return;
@@ -438,7 +447,8 @@ static int const RCTVideoUnset = -1;
    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 isAsset = [RCTConvert BOOL:[source objectForKey:@"isAsset"]];
    NSString *uri = [source objectForKey:@"uri"];
@@ -540,7 +550,8 @@ static int const RCTVideoUnset = -1;

#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) {
        // When timeMetadata is read the event onTimedMetadata is triggered
        if ([keyPath isEqualToString:timedMetadata]) {
@@ -586,7 +597,8 @@ static int const RCTVideoUnset = -1;

                    if ((videoTrack.naturalSize.width == preferredTransform.tx
                            && videoTrack.naturalSize.height == preferredTransform.ty)
                            || (preferredTransform.tx == 0 && preferredTransform.ty == 0)) {
                            || (preferredTransform.tx == 0 && preferredTransform.ty == 0))
                    {
                        orientation = @"landscape";
                    } else {
                        orientation = @"portrait";
@@ -650,7 +662,8 @@ static int const RCTVideoUnset = -1;
                }
                _playbackStalled = NO;
            }
        } else if ([keyPath isEqualToString:externalPlaybackActive]) {
        }
        else if([keyPath isEqualToString:externalPlaybackActive]) {
            if(self.onVideoExternalPlaybackChange) {
                self.onVideoExternalPlaybackChange(@{@"isExternalPlaybackActive": [NSNumber numberWithBool:_player.isExternalPlaybackActive],
                        @"target": self.reactTag});
@@ -661,7 +674,8 @@ static int const RCTVideoUnset = -1;
    }
}

- (void)attachListeners {
- (void)attachListeners
{
    // listen for end of file
    [[NSNotificationCenter defaultCenter] removeObserver:self
                                                    name:AVPlayerItemDidPlayToEndTimeNotification
@@ -680,14 +694,16 @@ static int const RCTVideoUnset = -1;
                                               object:nil];
}

- (void)playbackStalled:(NSNotification *)notification {
- (void)playbackStalled:(NSNotification *)notification
{
    if(self.onPlaybackStalled) {
        self.onPlaybackStalled(@{@"target": self.reactTag});
    }
    _playbackStalled = YES;
}

- (void)playerItemDidReachEnd:(NSNotification *)notification {
- (void)playerItemDidReachEnd:(NSNotification *)notification
{
    if(self.onVideoEnd) {
        self.onVideoEnd(@{@"target": self.reactTag});
    }
@@ -703,34 +719,43 @@ static int const RCTVideoUnset = -1;

#pragma mark - Prop setters

- (void)setResizeMode:(NSString *)mode {
    if (_controls) {
- (void)setResizeMode:(NSString*)mode
{
    if( _controls )
    {
        _playerViewController.videoGravity = mode;
    } else {
    }
    else
    {
        _playerLayer.videoGravity = mode;
    }
    _resizeMode = mode;
}

- (void)setPlayInBackground:(BOOL)playInBackground {
- (void)setPlayInBackground:(BOOL)playInBackground
{
    _playInBackground = playInBackground;
}

- (void)setAllowsExternalPlayback:(BOOL)allowsExternalPlayback {
- (void)setAllowsExternalPlayback:(BOOL)allowsExternalPlayback
{
    _allowsExternalPlayback = allowsExternalPlayback;
    _player.allowsExternalPlayback = _allowsExternalPlayback;
}

- (void)setPlayWhenInactive:(BOOL)playWhenInactive {
- (void)setPlayWhenInactive:(BOOL)playWhenInactive
{
    _playWhenInactive = playWhenInactive;
}

- (void)setIgnoreSilentSwitch:(NSString *)ignoreSilentSwitch {
- (void)setIgnoreSilentSwitch:(NSString *)ignoreSilentSwitch
{
    _ignoreSilentSwitch = ignoreSilentSwitch;
    [self applyModifiers];
}

- (void)setPaused:(BOOL)paused {
- (void)setPaused:(BOOL)paused
{
    if (paused) {
        [_player pause];
        [_player setRate:0.0];
@@ -747,11 +772,13 @@ static int const RCTVideoUnset = -1;
    _paused = paused;
}

- (float)getCurrentTime {
- (float)getCurrentTime
{
    return _playerItem != NULL ? CMTimeGetSeconds(_playerItem.currentTime) : 0;
}

- (void)setCurrentTime:(float)currentTime {
- (void)setCurrentTime:(float)currentTime
{
    NSDictionary *info = @{
            @"time": [NSNumber numberWithFloat:currentTime],
            @"tolerance": [NSNumber numberWithInt:100]
@@ -759,7 +786,8 @@ static int const RCTVideoUnset = -1;
    [self setSeek:info];
}

- (void)setSeek:(NSDictionary *)info {
- (void)setSeek:(NSDictionary *)info
{
    NSNumber *seekTime = info[@"time"];
    NSNumber *seekTolerance = info[@"tolerance"];

@@ -801,22 +829,26 @@ static int const RCTVideoUnset = -1;
    }
}

- (void)setRate:(float)rate {
- (void)setRate:(float)rate
{
    _rate = rate;
    [self applyModifiers];
}

- (void)setMuted:(BOOL)muted {
- (void)setMuted:(BOOL)muted
{
    _muted = muted;
    [self applyModifiers];
}

- (void)setVolume:(float)volume {
- (void)setVolume:(float)volume
{
    _volume = volume;
    [self applyModifiers];
}

- (void)applyModifiers {
- (void)applyModifiers
{
    if (_muted) {
        [_player setVolume:0];
        [_player setMuted:YES];
@@ -840,7 +872,8 @@ static int const RCTVideoUnset = -1;
}

- (void)setMediaSelectionTrackForCharacteristic:(AVMediaCharacteristic)characteristic
                                   withCriteria:(NSDictionary *)criteria {
                                   withCriteria:(NSDictionary *)criteria
{
    NSString *type = criteria[@"type"];
    AVMediaSelectionGroup *group = [_player.currentItem.asset
            mediaSelectionGroupForMediaCharacteristic:characteristic];
@@ -1011,14 +1044,16 @@ static int const RCTVideoUnset = -1;
    [_player.currentItem selectMediaOption:mediaOption inMediaSelectionGroup:group];
}

- (void)setTextTracks:(NSArray *)textTracks; {
- (void)setTextTracks:(NSArray*) textTracks;
{
    _textTracks = textTracks;

    // in case textTracks was set after selectedTextTrack
    if (_selectedTextTrack) [self setSelectedTextTrack:_selectedTextTrack];
}

- (NSArray *)getAudioTrackInfo {
- (NSArray *)getAudioTrackInfo
{
    NSMutableArray *audioTracks = [[NSMutableArray alloc] init];
    AVMediaSelectionGroup *group = [_player.currentItem.asset
            mediaSelectionGroupForMediaCharacteristic:AVMediaCharacteristicAudible];
@@ -1040,7 +1075,8 @@ static int const RCTVideoUnset = -1;
    return audioTracks;
}

- (NSArray *)getTextTrackInfo {
- (NSArray *)getTextTrackInfo
{
    // if sideloaded, textTracks will already be set
    if (_textTracks) return _textTracks;

@@ -1066,14 +1102,17 @@ static int const RCTVideoUnset = -1;
    return textTracks;
}

- (BOOL)getFullscreen {
- (BOOL)getFullscreen
{
    return _fullscreenPlayerPresented;
}

- (void)setFullscreen:(BOOL) fullscreen {
    if (fullscreen && !_fullscreenPlayerPresented && _player) {
    if( fullscreen && !_fullscreenPlayerPresented && _player )
    {
        // Ensure player view controller is not null
        if (!_playerViewController) {
        if( !_playerViewController )
        {
            [self usePlayerViewController];
        }
        // Set presentation style to fullscreen
@@ -1081,14 +1120,17 @@ static int const RCTVideoUnset = -1;

        // Find the nearest view controller
        UIViewController *viewController = [self firstAvailableUIViewController];
        if (!viewController) {
        if( !viewController )
        {
            UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow];
            viewController = keyWindow.rootViewController;
            if (viewController.childViewControllers.count > 0) {
            if( viewController.childViewControllers.count > 0 )
            {
                viewController = viewController.childViewControllers.lastObject;
            }
        }
        if (viewController) {
        if( viewController )
        {
            _presentingViewController = viewController;
            if(self.onVideoFullscreenPlayerWillPresent) {
                self.onVideoFullscreenPlayerWillPresent(@{@"target": self.reactTag});
@@ -1101,7 +1143,9 @@ static int const RCTVideoUnset = -1;
                }
            }];
        }
    } else if (!fullscreen && _fullscreenPlayerPresented) {
    }
    else if ( !fullscreen && _fullscreenPlayerPresented )
    {
        [self videoPlayerViewControllerWillDismiss:_playerViewController];
        [_presentingViewController dismissViewControllerAnimated:true completion:^{
            [self videoPlayerViewControllerDidDismiss:_playerViewController];
@@ -1109,43 +1153,6 @@ static int const RCTVideoUnset = -1;
    }
}

- (void)setFilter:(NSString *)filter {

    _filter = filter;

    AVAsset *asset = _playerItem.asset;

    if (asset != nil) {

        NSString *filterName = filters[filter];
        CIFilter *filter = [CIFilter filterWithName:filterName];

        _playerItem.videoComposition = [AVVideoComposition
                videoCompositionWithAsset:asset
             applyingCIFiltersWithHandler:^(AVAsynchronousCIImageFilteringRequest *_Nonnull request) {

                 if (filter == nil) {

                     [request finishWithImage:request.sourceImage context:nil];

                 } else {

                     CIImage *image = request.sourceImage.imageByClampingToExtent;

                     [filter setValue:image forKey:kCIInputImageKey];

                     CIImage *output = [filter.outputImage imageByCroppingToRect:request.sourceImage.extent];

                     [request finishWithImage:output context:nil];

                 }

             }];

    }

}

- (void)setFullscreenOrientation:(NSString *)orientation {
    _fullscreenOrientation = orientation;
    if (_fullscreenPlayerPresented) {
@@ -1153,8 +1160,10 @@ static int const RCTVideoUnset = -1;
    }
}

- (void)usePlayerViewController {
    if (_player) {
- (void)usePlayerViewController
{
    if( _player )
    {
        _playerViewController = [self createPlayerViewController:_player withPlayerItem:_playerItem];
        // to prevent video from being animated when resizeMode is 'cover'
        // resize mode must be set before subview is added
@@ -1163,8 +1172,10 @@ static int const RCTVideoUnset = -1;
    }
}

- (void)usePlayerLayer {
    if (_player) {
- (void)usePlayerLayer
{
    if( _player )
    {
        _playerLayer = [AVPlayerLayer playerLayerWithPlayer:_player];
        _playerLayer.frame = self.bounds;
        _playerLayer.needsDisplayOnBoundsChange = YES;
@@ -1180,13 +1191,18 @@ static int const RCTVideoUnset = -1;
    }
}

- (void)setControls:(BOOL)controls {
    if (_controls != controls || (!_playerLayer && !_playerViewController)) {
- (void)setControls:(BOOL)controls
{
    if( _controls != controls || (!_playerLayer && !_playerViewController) )
    {
        _controls = controls;
        if (_controls) {
        if( _controls )
        {
            [self removePlayerLayer];
            [self usePlayerViewController];
        } else {
        }
        else
        {
            [_playerViewController.view removeFromSuperview];
            _playerViewController = nil;
            [self usePlayerLayer];
@@ -1194,7 +1210,8 @@ static int const RCTVideoUnset = -1;
    }
}

- (void)setProgressUpdateInterval:(float)progressUpdateInterval {
- (void)setProgressUpdateInterval:(float)progressUpdateInterval
{
    _progressUpdateInterval = progressUpdateInterval;

    if (_timeObserver) {
@@ -1203,7 +1220,8 @@ static int const RCTVideoUnset = -1;
    }
}

- (void)removePlayerLayer {
- (void)removePlayerLayer
{
    [_playerLayer removeFromSuperlayer];
    if (_playerLayerObserverSet) {
        [_playerLayer removeObserver:self forKeyPath:readyForDisplayKeyPath];
@@ -1212,16 +1230,66 @@ static int const RCTVideoUnset = -1;
    _playerLayer = nil;
}

- (void)setFilter:(NSString *)filter {

    _filter = filter;

    AVAsset *asset = _playerItem.asset;

    if (asset != nil) {

        NSDictionary *filters = @{
                @"Normal": @"",
                @"Country": @"CISepiaTone",
                @"Winter": @"CIPhotoEffectProcess",
                @"Black N White": @"CIPhotoEffectNoir",
                @"Sunrise": @"CIPhotoEffectTransfer",
                @"Artistic": @"CIColorPosterize",
        };

        NSString *filterName = filters[filter];
        CIFilter *filter = [CIFilter filterWithName:filterName];

        _playerItem.videoComposition = [AVVideoComposition
                videoCompositionWithAsset:asset
             applyingCIFiltersWithHandler:^(AVAsynchronousCIImageFilteringRequest *_Nonnull request) {

                 if (filter == nil) {

                     [request finishWithImage:request.sourceImage context:nil];

                 } else {

                     CIImage *image = request.sourceImage.imageByClampingToExtent;

                     [filter setValue:image forKey:kCIInputImageKey];

                     CIImage *output = [filter.outputImage imageByCroppingToRect:request.sourceImage.extent];

                     [request finishWithImage:output context:nil];

                 }

             }];

    }

}

#pragma mark - RCTVideoPlayerViewControllerDelegate

- (void)videoPlayerViewControllerWillDismiss:(AVPlayerViewController *)playerViewController {
    if (_playerViewController == playerViewController && _fullscreenPlayerPresented && self.onVideoFullscreenPlayerWillDismiss) {
- (void)videoPlayerViewControllerWillDismiss:(AVPlayerViewController *)playerViewController
{
    if (_playerViewController == playerViewController && _fullscreenPlayerPresented && self.onVideoFullscreenPlayerWillDismiss)
    {
        self.onVideoFullscreenPlayerWillDismiss(@{@"target": self.reactTag});
    }
}

- (void)videoPlayerViewControllerDidDismiss:(AVPlayerViewController *)playerViewController {
    if (_playerViewController == playerViewController && _fullscreenPlayerPresented) {
- (void)videoPlayerViewControllerDidDismiss:(AVPlayerViewController *)playerViewController
{
    if (_playerViewController == playerViewController && _fullscreenPlayerPresented)
    {
        _fullscreenPlayerPresented = false;
        _presentingViewController = nil;
        _playerViewController = nil;
@@ -1234,41 +1302,54 @@ static int const RCTVideoUnset = -1;

#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.
    // That can only be in the context of playerViewController.
    if (!_controls && !_playerLayer && !_playerViewController) {
    if( !_controls && !_playerLayer && !_playerViewController )
    {
        [self setControls:true];
    }

    if (_controls) {
    if( _controls )
    {
        view.frame = self.bounds;
        [_playerViewController.contentOverlayView insertSubview:view atIndex:atIndex];
    } else {
    }
    else
    {
        RCTLogError(@"video cannot have any subviews");
    }
    return;
}

- (void)removeReactSubview:(UIView *)subview {
    if (_controls) {
- (void)removeReactSubview:(UIView *)subview
{
    if( _controls )
    {
        [subview removeFromSuperview];
    } else {
    }
    else
    {
        RCTLogError(@"video cannot have any subviews");
    }
    return;
}

- (void)layoutSubviews {
- (void)layoutSubviews
{
    [super layoutSubviews];
    if (_controls) {
    if( _controls )
    {
        _playerViewController.view.frame = self.bounds;

        // also adjust all subviews of contentOverlayView
        for (UIView* subview in _playerViewController.contentOverlayView.subviews) {
            subview.frame = self.bounds;
        }
    } else {
    }
    else
    {
        [CATransaction begin];
        [CATransaction setAnimationDuration:0];
        _playerLayer.frame = self.bounds;
@@ -1278,7 +1359,8 @@ static int const RCTVideoUnset = -1;

#pragma mark - Lifecycle

- (void)removeFromSuperview {
- (void)removeFromSuperview
{
    [_player pause];
    if (_playbackRateObserverRegistered) {
        [_player removeObserver:self forKeyPath:playbackRate context:nil];
@@ -1304,6 +1386,8 @@ static int const RCTVideoUnset = -1;
    [super removeFromSuperview];
}

#pragma mark - Export

- (void)save:(NSDictionary *)options resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {

    AVAsset *asset = _playerItem.asset;