使用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是如何实现的。 所以这取决于那个。

  1. 在第一项之后插入第一项:
    player.insert(player.items()[0], after: player.items()[0])
  2. 在第一项后插入重新创建的上一项:
    player.insert(prevItem, after: player.items()[0])
  3. 调用player.advanceToNextItem()