IOS AVFOUNDATION播放基准
通过安德烈·波波夫 ( Andrey Popov)
随着iOS 11的引入,AVFoundation框架进行了一些更改,并扩展了新功能 。 因此,为了更好地理解和利用框架功能,以下是对去年在Apple WWDC上首次引入的AVFoundation Playback基准测试进展的介绍和评论。
AVFoundation功能
AVFoundation提供了用于多种多媒体操作的API,包括回放,图像捕获,导出和大量的编辑选项。
播放类型:
从本地存储: file:///.../example.MOV.
从将文件上传到的Web服务器,然后进行逐步下载: https://example.com/example.MOV.
: https://example.com/example.MOV.
一种更动态的方法是HTTP Live Streaming(HLS)。 HLS播放播放列表。 播放列表是.txt文件。 它包含#EXTINF标签。 标签包含段(segment1.ts等),每个段的长度为10秒(#EXTINF 10.001)。
视频6Mbit播放列表;
影片4Mbit播放清单;
视频2Mbit播放列表音频立体声播放列表;
音频环绕播放列表;
playlist.txt文件:
#EXTM3U
#EXT-X-VERSION:4
#EXT-X-TARGETDURATION:10
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-MAP:URI="patpmt.ts"
#EXTINF 10.001
segment1.ts
#EXTINF 10.001
segment2.ts
通常,默认URL与基本播放列表相关,该基本播放列表包含相同内容的多个播放列表,但根据传输速度,格式(有时甚至是语言)进行配置。
通过网络播放
今天, AVPlayerItem
具有三个属性: playbackLikelyToKeepUp
, playbackBufferFull
和playbackBufferEmpty
。
在iOS 9及之前的版本中,AVFoundation客户端应控制渐进式下载属性,并等到它们设置AVPlayer.rate = 1
之前,直到playbackLikelyToKeepUp
和playbackBufferEmpty
属性为true。
对于HTTP Live Streaming,您可以在用户开始播放后立即将AVPlayer.rate
设置为1,并自动等待数据足够缓冲以开始播放。
在iOS 10,macOS Sierra和tvOS 10中,将应用与渐进式下载和HTTP实时流传输相同的规则。 您可以在敲击播放事件上设置AVPlayer.rate = 1
或请求播放方法–同样。 在这种情况下,AVFoundation会自动等待以避免缓冲。
如果在播放期间网络连接丢失,则保留AVPlayer.rate = 1
值。 缓冲会继续进行,只要加载了足够的数据,便会继续播放。
如果您将AVKit和MediaPlayer用于UI,则它们已经支持自动缓冲等待。 使用AVFoundation的应用程序直接使用新的API(automaticallyWaitsToMinimizeStalling)。 如果AVPlayer.automaticallyWaitsToMinimizeStalling
值为false,则立即开始播放。
通过网络播放具有三种状态:暂停,等待和播放。 初始状态被暂停。
AVPlayer.rate
是请求的应用程序回放速度。
AVPlayerItem.timebase.rate
是播放速度。
iOS 10 AVFoundation主食
自动, AVPlayer.automaticallyWaitsToMinimizeStalling
参数值为true。 AVPlayer.timeControlStatus - (Paused, WaitingToPlayAtSpecifiedRate, Playing)
是播放器的状态。 在等待模式(WaitingToPlayAtSpecifiedRate)
, AVPlayer.reasonForWaitingToPlay
参数报告此等待的原因。
AVQueuePlayer
是回放队列,用于优化不同元素(AVPlaerItem)
之间的过渡。 如果发生循环,则可以在一个AVAsset中创建多个AVPlayer元素。 AVQueuePlayer
提供有关要播放的元素以及这些过渡的AVFoundation优化的信息。
跑步机效应
创建AVPlayerItem
元素并将其添加到AVQueuePlayer
队列中,同时设置.end
属性。 当播放到达元素的末尾时,随着列表移至下一项,它将从队列中删除。 收到发生这种情况的通知后,您可以获取此元素,将其当前时间设置为开始,然后将其放置在队列的末尾。 使用stopObserving
和startObserving
方法来避免递归。
覆盖函数funcValueValue(forKeyPath keyPath:String ?,对象:AnyObject ?,更改: [NSKeyValueChangeKey:AnyObject] ?,上下文:UnsafeMutablePointer ?){ 如果context ==&ObserverContexts.currentItem { 后卫让玩家=玩家其他{返回} 如果player.items()。isEmpty { //由于播放器项目不正确,播放队列被清空。 结束循环。 } 其他{ 如果让itemRemoved =更改?[。oldKey]为? AVPlayerItem { itemRemoved.seek(至:kCMTimeZero) stopObserving() player.insert(itemRemoved,after:nil) startObserving() }} } //其他...}
AVPlayerLooper
AVplayerLoop
实现了跑步机效果,创建了多个AVPleyerItem
副本, AVPleyerItem
副本在播放队列中循环移动。
播放器= AVQueuePlayer() playerLayer = AVPlayerLayer(玩家:玩家) playerItem = AVPlayerItem(URL:videoURL) playerLooper = AVPlayerLooper(玩家:玩家,templateItem:playerItem) player.play()