使用AVQueuePlayer跳转到之前的更好方法?
我在我的应用程序中使用AVQueuePlayer
。 我有两个滑动手势跳到下一个跳过以前的avplayeritems。 现在要跳到下一步我只是在avqueueplayer上调用advanceToNextItem,效果很好。
然而,跳到上一个我正在删除所有项目并将它们添加回前面的前一个video,这在跳过前几次时非常慢。 如何调用advanceToNextItem
更快?
我的代码如下所示:
func skipToPrevious() { queuePlayer.removeAllItems() // move the previous playerItem to the front of the list then add them all back in for playerItem in playerItems: queuePlayer.insertItem(playerItem, afterItem: nil) }
看起来AVQueuePlayer
在调用AVQueuePlayer
会从播放队列中删除当前项。 从理论上讲,如果不重建队列,就无法恢复此项目。
你可以做的是使用标准的AVPlayer
,有一个AVPlayerItems
数组,以及一个保持当前轨道索引的整数索引。
斯威夫特3:
let player = AVPlayer() let playerItems = [AVPlayerItem]() // your array of items var currentTrack = 0 func previousTrack() { if currentTrack - 1 < 0 { currentTrack = (playerItems.count - 1) < 0 ? 0 : (playerItems.count - 1) } else { currentTrack -= 1 } playTrack() } func nextTrack() { if currentTrack + 1 > playerItems.count { currentTrack = 0 } else { currentTrack += 1; } playTrack() } func playTrack() { if playerItems.count > 0 { player.replaceCurrentItem(with: playerItems[currentTrack]) player.play() } }
Swift 2.x:
func previousTrack() { if currentTrack-- < 0 { currentTrack = (playerItems.count - 1) < 0 ? 0 : (playerItems.count - 1) } else { currentTrack-- } playTrack() } func nextTrack() { if currentTrack++ > playerItems.count { currentTrack = 0 } else { currentTrack++; } playTrack() } func playTrack() { if playerItems.count > 0 { player.replaceCurrentItemWithPlayerItem(playerItems[currentTrack]) player.play() } }
队列是否能顺利处理多个向前跳过? 如果是这样,您可以不断地将之前的video重新插入到索引n + 2的队列中。 当用户希望播放上一首曲目时,您将向前跳过两次。
如果从轨道A到F播放没有任何跳过,模式将如下所示:
ABCDEF BCDEF // re-insert A after next track BCADEF CADEF // remove A then re-insert B CDEF CDBEF DBEF // remove B then re-insert C DEF DECF ECF // remove C then re-insert D EF EFD FD // remove D then re-insert E F FE
使用这种模式你只能顺利地向后跳过一次,但可以修改它以允许更多。
绝对不是一个理想的解决方案,但可能有用!
replaceCurrentItemWithPlayerItem
有限制,应该尽可能避免,在Apple的文档中 ,它声明“新项目必须与它替换的项目具有相同的合成器,或者没有合成器”。
而是使用循环逐个插入playerItems,只需创建一个AVQueuePlayer
会更快:
func skipToPrevious() { queuePlayer = AVQueuePlayer.queuePlayerWithItems(playerItem) }
我正在考虑一种非常不同的方法,实际上就advanceToNextItem方法而言。 你说advanceToNextItem运行正常。 所以我想知道你是否可以使用advanceToNextItem本身实现skip to previous,而是将队列指向当前播放项目的两个项目。
例如,如果您的队列是这个,那么粗体是当前项目
ABCD E FGH
然后将当前项设置为C,然后使用advanceToNextItem使其播放D.
不知道你的advanceToNextItem是如何实现的。 所以这取决于那个。
- 在第一项之后插入第一项:
player.insert(player.items()[0], after: player.items()[0])
。 - 在第一项后插入重新创建的上一项:
player.insert(prevItem, after: player.items()[0])
- 调用
player.advanceToNextItem()
。