美文网首页
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