#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
.