美文网首页
AVPlayer踩坑小记

AVPlayer踩坑小记

作者: 小球why | 来源:发表于2021-05-17 14:14 被阅读0次

AVPlayer是苹果平台上常用的视频播放器组件。使用简单,性能好;但是使用过程中会遇到一些坑。

一、缓冲状态判断

有以下三个属性判断视频能否进行播放

isPlaybackBufferEmpty  // 缓冲空了
isPlaybackLikelyToKeepUp // 可以进行播放
isPlaybackBufferFull // 缓冲满了

一开始的写法是:

if playerItem.isPlaybackLikelyToKeepUp {
    self.loadState = .playable
}
if playerItem.isPlaybackBufferEmpty {
    self.loadState = .loading
}

后来发现有些高码率的视频,会出现一直加载,无法播放的情况。后来发现是因为缓存满了isPlaybackBufferFull的值为true, 但是isPlaybackLikelyToKeepUp的值还是为false。

所以改成是下面的写法:

if playerItem.isPlaybackLikelyToKeepUp || playerItem.isPlaybackBufferFull {
    self.loadState = .playable
}
if playerItem.isPlaybackBufferEmpty {
    self.loadState = .loading
} 

最后发现有些视频会频繁的切换状态,分析了之后。发现 isPlaybackBufferFullisPlaybackBufferEmpty会同时为true。从字面上理解这两个值应该是要互斥的,但是结果是相反。

所以最后正确的写法应该是:

if playerItem.isPlaybackBufferEmpty {
    self.loadState = .loading
} else if playerItem.isPlaybackLikelyToKeepUp || playerItem.isPlaybackBufferFull {
    self.loadState = .playable
}

二、视频播放黑屏

有些mp4视频在AVPlayer播放有声音,但是画面黑屏。但是放在自研播放器ijkplayer就可以有声音又有画面了。所以解决方案就是能判断异常视频,并自动切换到ijkplayer

通过分析视频流发现帧率是25,视频帧的格式是yuv444p。猜测应该是无法硬解yuv444p。所以导致视频帧无法显示,后来通过增加AVPlayerItemOutput,发现确实没有输出视频帧。

通过对每个属性进行尝试,发现可以通过assetTrack的isPlayable属性来判断是否能输出视频帧

代码如下:

let videoTrack = item.tracks.first { $0.assetTrack?.mediaType.rawValue == AVMediaType.video.rawValue }
if let videoTrack = videoTrack, videoTrack.assetTrack?.isPlayable == false {
    error = NSError(domain: AVFoundationErrorDomain, code: -1, userInfo: [NSLocalizedDescriptionKey: "can't player"])
    return
}

三、多音轨

AVPlayer播放多音轨的时候。默认所有的音轨都会打开的。所以要改成只打开一个音轨

代码如下:

// 默认选择第一个声道
item.tracks.filter { $0.assetTrack?.mediaType.rawValue == AVMediaType.audio.rawValue }.dropFirst().forEach { $0.isEnabled = false }

四、AVQueuePlayer

AVQueuePlayer是AVPlayer的子类,主要是用来实现视频顺序播放。也可以搭配AVPlayerLooper实现视频循环播放。

AVQueuePlayer默认是播放完一个视频,就会自动切换到下个视频了。

这样就会导致一个问题,如果只是播放单个资源的话。那视频播放播放完之后,你就无法从头开始播放了。因为currentItem这个属性被重置为nil了。

这时你可以通过修改属性actionAtItemEnd的值。来改变视频播放完之后的行为。默认是.advance。直接改成是.pause或是.none就可以了

相关文章

  • AVPlayer踩坑小记

    AVPlayer是苹果平台上常用的视频播放器组件。使用简单,性能好;但是使用过程中会遇到一些坑。 一、缓冲状态判断...

  • CocoaPods 踩坑小记

    记一些工作中遇到的小问题,给需要的人。 模块化项目应该都会遇到类似的问题,业务库经常变动必须在功能开发完成...

  • AVPlayer播放网络视频踩坑记录

    2019年1月16日更新: 13, 想了很久player状态定义的问题,现在感觉AVFoundation的AVPl...

  • docker mongodb 踩坑小记

    公司一台服务器因为docker导致磁盘空间不足,mongodb容器也无法启动了,后来折腾半天才搞定。备忘一下。 下...

  • Android 踩坑小记(一)

    文件保存路径不要含有特殊符号,建议只包含英文、数字和下划线,否则在某些手机上会出现访问文件错误。特别是根据时间来保...

  • JavaScrip-StepPitGuide《JavaScrip

    《JavaScript踩坑指南》JavaScrip-StepPitGuide? 《JavaScript踩坑指南》 ...

  • 算法踩坑6-二叉搜索树排序

    背景 接上面五篇文章算法踩坑-快速排序 算法踩坑2-插入排序 算法踩坑3-堆排序 算法踩坑4-冒泡排序 ...

  • 算法踩坑5-归并排序

    背景 接上面四篇文章算法踩坑-快速排序 算法踩坑2-插入排序 算法踩坑3-堆排序 算法踩坑4-冒泡排序 来...

  • D1094:踩坑的价值最大化

    是人就会踩坑,不踩坑理论上就不属于人类,踩坑是人之常情,能回头站在坑边反思,才是对踩过的的坑价值最大化的体现,要不...

  • AVPlayer那些坑

    AVPlayer是iOS上常用的视频播放器组件,支持常见的音视频格式。对于一般应用而言,使用AVPlayer和一套...

网友评论

      本文标题:AVPlayer踩坑小记

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