美文网首页
AVPlayer 出现黑屏但有声音,闪烁

AVPlayer 出现黑屏但有声音,闪烁

作者: 天空中的球 | 来源:发表于2020-05-23 17:32 被阅读0次

在调试我们项目中的某个页面时,发现 AVPlayerLayer 出现黑屏但有声音。

经过我们的经验和层次判断,问题应该是在 AVPlayerLayer 上。
毕竟 AVPlayerLayer:负责显示视频,如果没有添加该类,只有声音没有画面,比较符合。

网上常见的两种情况

  • 1、缺少 videoGravity 的设置
playerLayer.videoGravity = AVLayerVideoGravityResizeAspect
  • 2、viewDidLayoutSubviews 移到 loadPlayer方法中 执行
 self.playerLayer.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);

同上,就是 playerLayer.frame 的 frame 没有设置好。

暂停下,先回归下 基本概念

  • AVPlayerItem: 提供视频信息,一个AVPlayerItem对应着你提供的一个视频Url资源
  • AVPlayerLayer:它主要负责的就是视频的显示,继承自CALayer
  • AVPlayer:它主要负责的是管理视频播放,暂停等等,相当于一个视频管理器

根据URL创建AVPlayerItem , 把AVPlayerItem 提供给 AVPlayer, AVPlayerLayer 显示视频,AVPlayer 控制视频, 播放, 暂停, 跳转 等等, 播放过程中获取缓冲进度,获取播放进度。

那么出现闪黑屏和黑屏,很大概率是 AVPlayerLayer 这一块出问题,毕竟有声音的。随着我这进一步测试,准确的发现这个问题时:
第二次进入时才黑屏的。

最终发现第二次重新进入 self.playerLayer 为空,必须初始化就好了。

抓住关键点,问题就好了,确实是出现在 AVPlayerLayer 上的。

  • 然而黑屏解决了,发现还是不完美,每次都会闪烁下的

一个情况是,我们在 iOS 9 上为了一个过渡效果增加了间隔时间

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    [self.playView.playerLayer setPlayer:self.avPlayer];
});

然而在 iOS 13 上这个效果则让闪一下,发现将时间设置在 0.1 的间隔时间就好了。

// 添加预览图
 [self addPrImageView];
// 系统高点的设备间隔时间长了,会闪一下
CGFloat time = NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_9_x_Max ? 0.1 : 0.5;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(time * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    //去除预览图
    [self.preImageView removeFromSuperview];
     // 设置播放层
    [self.playView.playerLayer setPlayer:self.avPlayer];
 });

PS : 为了那个过渡效果,增加了一个预览图,获取画面的第一帧。

- (UIImage *)getVideoPreViewImage:(NSURL *)path {
    AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:path options:nil];
    AVAssetImageGenerator *assetGen = [[AVAssetImageGenerator alloc] initWithAsset:asset];
    
    assetGen.appliesPreferredTrackTransform = YES;
    CMTime time = CMTimeMakeWithSeconds(0.0, 600);
    NSError *error = nil;
    CMTime actualTime;
    CGImageRef image = [assetGen copyCGImageAtTime:time actualTime:&actualTime error:&error];
    UIImage *videoImage = [[UIImage alloc] initWithCGImage:image];
    CGImageRelease(image);
    return videoImage;
}

回归下:

  • 黑屏: 是因为 AVPlayerLayer 为空导致的
  • 闪烁:是因为不同系统版本上导致的,展示的间隔时间长了,AVPlayerLayer 效果不一样 。
    具体的 AVPlayerLayer 是哪些细节点不一样,还需要进一步研究。

PS:
1、有时如果是在 Cell 上用, AVPlayer 还有注意,复用的问题。
2、依然有黑屏的时候,注意等到缓冲好后再切换下显示的,注意这个 playbackLikelyToKeepUp 这个属性的监听就OK了。

相关文章

网友评论

      本文标题:AVPlayer 出现黑屏但有声音,闪烁

      本文链接:https://www.haomeiwen.com/subject/dnrbohtx.html