2
votes

Assuming the queue has already been initialized, the only method I see to add items into the queue is:

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

The documentation says Pass nil to append the item to the queue.

So then is it not possible to add an item into the top of the queue? I want to be able to replay what was previously played without removing and requeueing everything up again.

2
What about: AVPlayerItem *currentItem = [yourAVPlayer currentItem]; [yourAVPlayer insertItem:currentItem afterItem:currentItem];? Note that you may have to do ` [yourAVPlayer insertItem:[currentItem copy] afterItem:currentItem];`.Larme
I'm not sure how that works because my new item hasn't been inserted into the queue yet. But you actually got me thinking and I was able to figure it out. See my answer below.Oren

2 Answers

5
votes

Larme's comment above got me thinking and I was actually able to mimic the behavior I was looking for by doing the following:

// 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];

This worked great! I think the only downside is the player has to buffer again the next item which we removed and inserted back in. However the remaining items in the queue will stay buffered so that's better than having to reset the entire queue.

0
votes

I know this is an old question but I hit the same problem again today. Oren's solution didn't do the trick for me so I went with an even more radical approach. My case is also different since I only ever have two items in the queue (hence I use 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)
}

Note: It wasn't enough to insert the same currentItem again after it was removed because afterwards the player's items() still just returned 1 item (item) even though calling canInsert(currentItem, after: item) returned true.