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);
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With