我使用的是AVQueuePlayer
的子类,当我添加新的AVPlayerItem
和流URL时,应用程序会冻结大约一两秒。冻结是指它不会对用户界面上的触摸做出响应。此外,如果我已经有一首歌在播放,然后又添加了另一首歌到队列中,AVQueuePlayer
在播放第一首歌曲时会自动开始预加载歌曲。这会使应用程序在两秒钟内不响应用户界面上的触摸,就像添加第一首歌曲时一样,但歌曲仍然所以这意味着AVQueuePlayer
正在主线程中做一些导致明显“冻结”的事情。
我正在使用insertItem:afterItem:
来添加我的AVPlayerItem
。我测试并确定这是导致延迟的方法。可能是AVPlayerItem
在将其添加到队列时被AVQueuePlayer
激活时所做的事情。
必须指出的是,我使用Dropbox API v1测试版通过以下方法调用来获取流URL:
[[self restClient] loadStreamableURLForFile:metadata.path];
字符串
然后,当我收到流URL,我发送它到AVQueuePlayer
如下:
[self.player insertItem:[AVPlayerItem playerItemWithURL:url] afterItem:nil];
型
所以我的问题是:我该如何避免这种情况?我应该在没有AVPlayer
的帮助下自己预加载音频流吗?如果是,我该怎么做?
谢谢.
4条答案
按热度按时间9nvpjoqh1#
不要使用
playerItemWithURL
,它是同步的。当你收到带有URL的响应时,试试这个:字符串
i2byvkas2#
碰撞,因为这是一个高度评价的问题和类似的问题在线要么有过时的答案或不是很好.整个想法是相当直接的与
AVKit
和AVFoundation
,这意味着没有更多的依赖于第三方库.唯一的问题是,它采取了一些修修补补,把碎片在一起.使用
url
初始化AVFoundation
的Player()
显然不是线程安全的,或者说它不应该是线程安全的。这意味着,无论你如何在后台线程中初始化它,播放器属性都会被加载到主队列中,导致UI冻结,特别是在UITableView
s和UICollectionViews
中。为了解决这个问题,Apple提供了AVAsset
,它需要一个URL,并协助加载媒体属性,如轨道,播放,持续时间等,并可以异步进行,最好的部分是,这个加载过程是可取消的(不像其他Dispatch队列后台线程那样结束任务可能不那么直接)。这意味着,当您在表视图或集合视图上快速滚动时,无需担心后台中的延迟僵尸线程,cancellable
的这个特性非常棒,它允许我们取消任何正在进行的AVAsset
xmlc加载,但只能在信元出队期间取消。xmlc加载过程可以由loadValuesAsynchronously
方法调用,并且可以在以后的任何时间(如果仍在进行中)取消(随意)。别忘了使用
loadValuesAsynchronously
的结果正确处理异常。在**Swift(3/4)**中,你将如何异步加载视频,以及如何处理如果UVC进程失败(由于网络速度慢等原因)的情况-TL;DR
播放视频
字符串
注意事项:
根据你的应用想要实现的目标,你可能仍然需要做一些修改来调整它,以在
UITableView
或UICollectionView
中获得更平滑的滚动。你可能还需要在AVPlayerItem
属性上实现一些KVO,以便它工作,SO中有很多文章详细讨论了AVPlayerItem
KVO。通过资产循环(视频循环/GIF)
要循环视频,您可以使用上面介绍的相同方法并引入
AVPlayerLooper
。这里有一个循环视频(或GIF风格的短视频)的示例代码。注意使用duration
键,这是我们视频循环所需的。型
编辑:根据documentation,
AVPlayerLooper
需要完全加载资产的duration
属性,以便能够循环播放视频。此外,如果你想要一个无限循环,在AVPlayerLooper
初始化中带有开始和结束时间范围的timeRange: timeRange
真的是可选的。自从我发布了这个答案,我也意识到AVPlayerLooper
仅仅是关于70-80%的准确率在循环视频,特别是如果你的AVAsset
需要从一个URL流视频。为了解决这个问题,有一个完全不同的(但简单的)方法来循环视频-型
ao218c7q3#
Gigisommo对Swift 3的回答,包括评论中的反馈:
字符串
pkwftd7m4#
iOS 15+,请等待
字符串