Можно ли вставить элемент в начало очереди с помощью AVQueuePlayer?

#ios #avplayer #avqueueplayer

#iOS #avplayer #avqueueplayer

Вопрос:

Предполагая, что очередь уже инициализирована, единственный метод, который я вижу для добавления элементов в очередь, это:

- (void)insertItem:(AVPlayerItem *)item afterItem:(AVPlayerItem *)afterItem

В документации говорится Pass nil to append the item to the queue.

Итак, тогда невозможно добавить элемент в начало очереди? Я хочу иметь возможность воспроизводить то, что было воспроизведено ранее, без удаления и повторной постановки всего в очередь.

Комментарии:

1. Как насчет: AVPlayerItem *currentItem = [yourAVPlayer currentItem]; [yourAVPlayer insertItem:currentItem afterItem:currentItem]; ? Обратите внимание, что вам, возможно, придется выполнить ` [yourAVPlayer insertItem:[CurrentItem copy] afterItem:CurrentItem];`.

2. Я не уверен, как это работает, потому что мой новый элемент еще не был вставлен в очередь. Но вы действительно заставили меня задуматься, и я смог это выяснить. Смотрите мой ответ ниже.

Ответ №1:

Комментарий Ларме выше заставил меня задуматься, и я действительно смог имитировать поведение, которое я искал, выполнив следующее:

 // pause the player since we're messing with the currently playing item
[_avQueuePlayer pause];

// get current first item
id firstItem = [_avQueuePlayer.items objectAtIndex:0];

// add new item in 2nd spot
[_avQueuePlayer insertItem:newItem afterItem:firstItem];

// remove our first item so the new item becomes first in line
[_avQueuePlayer removeItem:firstItem];

// now add the original first item back in after the newly insert item
[_avQueuePlayer insertItem:firstItem afterItem:newItem];

// continue playing again
[_avQueuePlayer play];
  

Это сработало отлично! Я думаю, что единственным недостатком является то, что проигрывателю приходится снова буферизировать следующий элемент, который мы удалили и вставили обратно. Однако остальные элементы в очереди останутся буферизованными, так что это лучше, чем сброс всей очереди.

Ответ №2:

Я знаю, что это старый вопрос, но сегодня я снова столкнулся с той же проблемой. Решение Орена не сработало для меня, поэтому я выбрал еще более радикальный подход. Мой случай также отличается, поскольку у меня в очереди только два элемента (следовательно, я использую removeAll ):

 if let currentItem = player.currentItem {
    player.removeAllItems()
    player.insert(item, after: nil)
    player.insert(AVPlayerItem(asset: currentItem.asset), after: item)
} else {
    player.insert(item, after: nil)
}
  

Примечание: Было недостаточно вставить то же самое currentItem снова после его удаления, потому что после этого проигрыватель items() все еще просто вернул 1 элемент ( item ), даже несмотря на то, что вызов canInsert(currentItem, after: item) вернулся true .