使用AVQueuePlayer跳转到之前的更好方法?

时间:2016-01-24 03:21:46

标签: ios swift avqueueplayer avplayeritem

我在我的应用中使用了AVQueuePlayer。我有两个滑动手势跳到下一个跳过以前的avplayeritems。现在要跳到下一步我只是在avqueueplayer上调用advanceToNextItem,效果很好。

然而,跳到上一个我正在删除所有项目并将它们添加回前面的前一个视频,这在跳过前几次时非常慢。如何更快地调用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)

}

6 个答案:

答案 0 :(得分:21)

似乎AVQueuePlayer在调用advanceToNextItem时从播放队列中删除了当前项。从理论上讲,如果不重建队列,就无法恢复此项目。

你可以做的是使用一个标准的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()
    }
}

答案 1 :(得分:2)

replaceCurrentItemWithPlayerItem有限制,应尽可能避免,在Apple's document中,它声明“新项目必须与其替换的项目具有相同的合成器,或者没有合成器。”

使用循环逐个插入playerItems,只需创建一个AVQueuePlayer就会更快:

func skipToPrevious() {
    queuePlayer = AVQueuePlayer.queuePlayerWithItems(playerItem)
}

答案 2 :(得分:2)

队列是否能顺利处理多个跳过?如果是这样,您可以不断地将上一个视频重新插入到索引n + 2的队列中。当用户希望播放上一首曲目时,您将跳过两次。

如果在没有任何跳过的情况下从音轨A到F播放,则模式将如下所示:

var database = blogContext.Client.GetDatabase("dbName");
var collection = database.GetCollection<Post>("collectionName");
var recentPosts = await blogContext.Posts.FindOne()

使用此模式,您只能顺利地向后跳过一次,但可以修改它以允许更多。

绝对不是理想的解决方案,但可能会有效!

答案 3 :(得分:2)

我正在考虑一种非常不同的方法,实际上就advanceToNextItem方法而言。你说advanceToNextItem工作正常。所以我想知道你是否可以使用advanceToNextItem本身实现skip to previous,但是将队列指向当前播放项目的两个项目。

E.g。如果你的队列是这个,那么粗体是当前项目

A B C D E F G H

然后将当前项设置为C,然后使用advanceToNextItem使其播放D.

不确定您的advanceToNextItem是如何实现的。所以这取决于那个。

答案 4 :(得分:1)

您可以将当前项目替换为之前的项目,然后添加已替换的项目:

let previousItem = AVPlayerItem(url: url )
let currentItem = AVPlayerItem(url: currentUrl)

 player.replaceCurrentItem(with: previousItem)
    if player.canInsert(currentItem, after: previousItem) {
         player.insert(currentItem, after: previousItem)
    }

//或类似

 let previousItem = AVPlayerItem(url: url )
 if let currentItem = player.currentItem {
   player.replaceCurrentItem(with: previousItem)
     if player.canInsert(currentItem, after: previousItem) {
         player.insert(currentItem, after: previousItem)
     }
  }

答案 5 :(得分:-1)

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