badhanganesh
badhanganesh

Reputation: 3463

iOS 10 - AVPlayer shows black screen when playing video

Here I have a method that adds the video layer to the UIView that I have setup in IB:

 -(void)loadPlayer{
        self.asset = [AVAsset assetWithURL:url];

        AVPlayerItem *item = [AVPlayerItem playerItemWithAsset:self.asset];

        self.player = [AVPlayer playerWithPlayerItem:item];
        self.playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];
        self.playerLayer.contentsGravity = AVLayerVideoGravityResizeAspect;
        self.player.actionAtItemEnd = AVPlayerActionAtItemEndNone;

        item.videoComposition = [AVVideoComposition videoCompositionWithPropertiesOfAsset:self.asset];

        [self.player pause];
        [self.player addObserver:self forKeyPath:@"status" options:0 context:nil];

        dispatch_async(dispatch_get_main_queue(), ^{
            [self.videoLayer.layer addSublayer:self.playerLayer];
        });
}

The above method gets called in the viewDidAppear of the View Controller, so each time the current View Controller loads, the video should start to play.

Here I check for the player status and play the asset if ready:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
                        change:(NSDictionary *)change context:(void *)context {
    if (object == self.player && [keyPath isEqualToString:@"status"]) {
        if (self.player.status == AVPlayerStatusReadyToPlay) {
            [self.player play];
        }
    }
}

The problem is that the view did appear, the video starts playing, but only the audio, not video. All I get is black screen in the place of video. Audio is playing back fine, but it does not seem to render the video frames for some reason unknown.

This happens only on iOS 10 devices, the same code when run on a iOS 9 devices, works like a charm. The video shows up as expected.

Is there anything that is changed in the AVFoundation framework for iOS 10 in terms of AVPlayer or so? Or is there anything that I am missing here, coz iOS 9 plays it good.

If anyone has faced this issue, and if you have solved it, please post your solution. It would be helpful.

Thanks.


THE SOLUTION

Thanks for your replies! I just found that, for some reason in iOS 10 the viewDidLayoutSubviews did not get called as it was in iOS 9. Actually I was setting the player layer's frame in the viewDidLayoutSubviews method. Since it didn't get called, I was not able to see the player on screen. What I did was, set the player layer's frame in the loadPlayer method above. And it works fine. Hope this helps someone.

This is the line of code that I moved from viewDidLayoutSubviews to my loadPlayer method and it worked:

self.playerLayer.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);

Upvotes: 7

Views: 13332

Answers (6)

Duck
Duck

Reputation: 36003

The solutions on this page did not work for me.

I found another solution to this problem. In my case the video was being played in black but the sound was ok.

I discovered that changing the time slider to scrub the video would make the video appear.

So, my solution was to make the video go the the last frame, then to the first before playing:

Float64 duration = [self.player duration];    
[self.player goToTime:duration];
[self.player goToTime:0.0f];

Upvotes: 2

Nike Kov
Nike Kov

Reputation: 13751

In my case this problem was because i started playing simultaneously with UIView.animate with view.layoutIfNeeded() in animation block.

The fix for that is to not animate layout changes when not needed and not animate when starting playing video.

Upvotes: 2

badhanganesh
badhanganesh

Reputation: 3463

Thanks for your replies! I just found that, for some reason in iOS 10 the viewDidLayoutSubviews did not get called as it was in iOS 9. Actually I was setting the player layer's frame in the viewDidLayoutSubviews method. Since it didn't get called, I was not able to see the player on screen. What I did was, set the player layer's frame in the loadPlayer method above.And it works fine. Thanks! Hope this helps someone.

EDIT

This is the line of code that I moved from viewDidLayoutSubviews to my loadPlayer method and it worked:

self.playerLayer.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);

Upvotes: 0

Dhanas Manian
Dhanas Manian

Reputation: 516

The black color is background color of the AVPlayerViewController. so change the background color of the AVPlayerViewController as superview color. So the black flash will not be visible.

   self.view.backgroundColor =[UIColor whiteColor];
   avMoviePlayer.view.backgroundColor=[UIColor whiteColor];
   [self.view addSubview:avMoviePlayer.view];

Upvotes: 0

yu xiao
yu xiao

Reputation: 1

here is what I recently studied for AVPlayer

you can try it

XYAVMoviePlayer

enjoy your day :)

Upvotes: -5

Matloob Hasnain
Matloob Hasnain

Reputation: 1037

You need to retain your instance of AVPlayerItem i.e. as a property or an instance variable. The reference to the movie player is lost if you do not retain it. Even some time this rubish happens in ARC as well.Please make it property.

Upvotes: 3

Related Questions