iOS 10 - AVPlayer shows black screen when playing video
Asked Answered
E

6

7

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);
Eastwards answered 27/10, 2016 at 11:33 Comment(0)
E
0

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);

Eastwards answered 29/10, 2016 at 5:29 Comment(2)
It's not working for me. I got to crash in the "self.playerLayer.frame".Footbridge
@Bandhan Ganesh Pls suggest here : #54745859Freund
O
3

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.

Overscore answered 27/10, 2016 at 12:1 Comment(2)
I have got same error , But I am not sure It will help you. apologiesOverscore
Thanks, Matloob. I tried changing it to property before finding my solution. Didn't work. Please try my answer to see if it works.Eastwards
P
2

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.

Pappas answered 7/3, 2019 at 18:6 Comment(0)
I
2

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];
Interjacent answered 11/11, 2019 at 17:6 Comment(0)
E
0

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);

Eastwards answered 29/10, 2016 at 5:29 Comment(2)
It's not working for me. I got to crash in the "self.playerLayer.frame".Footbridge
@Bandhan Ganesh Pls suggest here : #54745859Freund
R
0

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];
Roberto answered 13/2, 2017 at 11:53 Comment(1)
Thanks! I got the solution. Please check my answer.Eastwards
S
-5

here is what I recently studied for AVPlayer

you can try it

XYAVMoviePlayer

enjoy your day :)

Secretary answered 28/10, 2016 at 10:5 Comment(1)
Opinion and comment about why you are providing a link would be usefulWylma

© 2022 - 2024 — McMap. All rights reserved.