-->

跳至上一AVPlayerItem上AVQueuePlayer /从队列中播放所选项目(Skip to

2019-06-27 12:54发布

我在玩一个电视节目已被切成不同的章节上使用AVQueuePlayer我的项目。 我也想提供给跳至上一首/下一章节或选择在运行不同章节的可能性,而AVQueuePlayer正在播放。

跳到下一个项目是与没有问题advanceToNextItem由AVQueuePlayer提供,但并没有什么都跳过回或播放队列中的certainitem。

所以我不太清楚什么是最好的方法在这里:

  1. 使用AVPlayer代替AVQueuePlayer,调用replaceCurrentItemWithPlayerItem:actionAtItemEnd发挥nextItem,只需使用“replaceCurrentItemWithPlayerItem”让用户选择特定的章节

要么

  1. 重组队列或通过使用当前玩家insertItem:afterItem:“和“removeAllItems”

其他信息:我存储的路径在它们应该出现在一个NSArray中假设用户通过按压代表章按钮跳到某些章节的顺序不同的视频。 按键有标签,而且这些阵列中的相应视频的索引。

希望我能讲得清楚吗? 任何人有这个情况的经验吗? 如果有谁知道哪里可以买到一个很好的IOS VideoPlayerFramework它提供的功能,我还希望该链接。

Answer 1:

如果你希望你的程序可以播放上一个项目,发挥您的playeritems(NSArray中)所选择的项目,你可以做到这一点。

- (void)playAtIndex:(NSInteger)index
{
    [player removeAllItems];
    for (int i = index; i <playerItems.count; i ++) {
        AVPlayerItem* obj = [playerItems objectAtIndex:i];
        if ([player canInsertItem:obj afterItem:nil]) {
        [obj seekToTime:kCMTimeZero];
        [player insertItem:obj afterItem:nil];
        }
    }
}

编辑:playerItems是存储您的AVPlayerItems的NSMutableArray的(NSArray的)。



Answer 2:

第一个答案去除AVQueuePlayer的所有项目,并重新填充队列开始迭代为指标ARG通过。 这将启动新填充的队列前一个项目(假设你通过正确的索引),以及从该点向前现有playerItems阵列的其余项目,但不允许多次挫折,例如,你已经上了轨道10和希望回去和重放轨道9,然后重播5道以上不能完成的任务。 但在这里,你可以...

-(IBAction) prevSongTapped: (id) sender
{
    if (globalSongCount>1){ //keep running tally of items already played
    [self resetAVQueue]; //removes all items from AVQueuePlayer

        for (int i = 1; i < globalSongCount-1; i++){
            [audioQueuePlayer advanceToNextItem];
        }
   globalSongCount--;
   [audioQueuePlayer play];


    }
}


Answer 3:

下面的代码可以让你跳转到任何物品在你的。 没有playerhead推进。 干净利落。 playerItemList是你的NSArray与AVPlayerItem对象。

- (void)playAtIndex:(NSInteger)index
{
    [audioPlayer removeAllItems];
    AVPlayerItem* obj = [playerItemList objectAtIndex:index];
    [obj seekToTime:kCMTimeZero];
    [audioPlayer insertItem:obj afterItem:nil];
    [audioPlayer play];
}


Answer 4:

djiovann创建的子类AVQueuePlayer那正好提供了这种功能。

你可以找到它的github上 。

我没有测试它尚未但通过代码浏览它似乎把工作做好。 同样的代码是有据可查的,所以它至少应该作为的功能自定义实现一个很好的参考服务(我建议使用一个类别,而不是子类的虽然)。



Answer 5:

@ saiday的回答对我的作品,这里是他的回答迅速版

 func play(at index: Int) {
    queue.removeAllItems()
    for i in index..<items.count {
        let obj: AVPlayerItem? = items[i]
        if queue.canInsert(obj!, after: nil) {
            obj?.seek(to: kCMTimeZero, completionHandler: nil)
            queue.insert(obj!, after: nil)
        }
    }
}


Answer 6:

这应该是AVQueuePlayer对象的责任,而不是您的视图控制器本身,因此,你应该使其可重复使用,并通过扩展暴露其他的答案实现和advanceToNextItem()的类似的方式来使用它:

extension AVQueuePlayer {
func advanceToPreviousItem(for currentItem: Int, with initialItems: [AVPlayerItem]) {
    self.removeAllItems()
    for i in currentItem..<initialItems.count {
        let obj: AVPlayerItem? = initialItems[i]
        if self.canInsert(obj!, after: nil) {
            obj?.seek(to: kCMTimeZero, completionHandler: nil)
            self.insert(obj!, after: nil)
        }
    }
}
}

用法(你只需要存储的索引和初始队列玩家项目的引用):

self.queuePlayer.advanceToPreviousItem(for: self.currentIndex, with: self.playerItems)

维持指数的一个办法就是观察AVPlayerItemDidPlayToEndTime通知每个视频项目:

func addDidFinishObserver() {
    queuePlayer.items().forEach { item in
        NotificationCenter.default.addObserver(self, selector: #selector(playerDidFinishPlaying), name: Notification.Name.AVPlayerItemDidPlayToEndTime, object: item)
    }
}

func removeDidFinishObserver() {
    queuePlayer.items().forEach { item in
        NotificationCenter.default.removeObserver(self, name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: item)
    }
}

@objc func playerDidFinishPlaying(note: NSNotification) {
    if queuePlayer.currentItem == queuePlayer.items().last {
        print("last item finished")
    } else {
        print("item \(currentIndex) finished")
        currentIndex += 1
    }
}

这一观察也可用于其他用途的情况(进度条,当前视频定时器复位......)真的很有用。



Answer 7:

如果你想使用AVQueuePlayer.Then任何索引播放一首歌曲这下面的代码可以帮助。

NSMutableArray *musicListarray (add song that you want to play in queue);
AVQueuePlayer *audioPlayer;
AVPlayerItem *item;

-(void) nextTapped
{
  nowPlayingIndex = nowPlayingIndex + 1;

  if (nowPlayingIndex > musicListarray.count)
  {
  }
  else
  {
    [self playTrack];
  }
}

-(void) playback
{
  if (nowPlayingIndex < 0)
  {
  }
  else
  {
    nowPlayingIndex = nowPlayingIndex - 1;
    [self playTrack];
  }
}

-(void) playTrack
{
  @try
  {
    if (musicArray.count > 0)
    {
      item =[[AVPlayerItem alloc] initWithURL: [NSURL URLWithString:musicListarray
      [nowPlayingIndex]]];
      [audioPlayer replaceCurrentItemWithPlayerItem:item];
      [audioPlayer play];
    }
  }
  @catch (NSException *exception)
  {
  }
}

-(void) PlaySongAtIndex
{
  //yore code...
  nowPlayingIndex = i (stating index from queue)[audioPlayer play];
  [self playTrack];
}

当你要播放一首歌曲在这里PlaySongAtIndex调用。



文章来源: Skip to Previous AVPlayerItem on AVQueuePlayer / Play selected Item from queue