I understand that when using a AVQueuePlayer
to play a list of AVPlayerItem
objects the player preload the next item in queue for faster reload when user get to this item.
The problem is that I need to have more control of which items preload, for example I want that the 3 next song and the 2 previous song be preloaded and prepare for fast loading.
So I think to manage the AVPlayerItem
objects myself, I just not sure how do I preload a AVPlayerItem
?
How can I preload the first 30 seconds for example?
Controlling the preload of the assets is a different problem than controlling the previous items. As soon as the AVQueuePlayer finishes an item, it'll release it from memory along with its cache. To get around that, you can add the AVPlayerItems into an array at the same time you add them into the player. This way once the Player removes the item, ARC will know there's still a reference to that object and not release it. Then you can simply put the item from the array back into the player and all the content will be loaded already. NOTE: you may want to limit the size of this cache array otherwise it will grow indefinitely if items are never removed from it.
If you want to have more control over the preloading, you can do so by loading the asset asynchronously and then creating the AVPlayerItem:
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:[NSURL URLWithString:url] options:nil];
NSArray *keys = @[@"playable", @"tracks",@"duration" ];
[asset loadValuesAsynchronouslyForKeys:keys completionHandler:^()
{
// make sure everything downloaded properly
for (NSString *thisKey in keys) {
NSError *error = nil;
AVKeyValueStatus keyStatus = [asset statusOfValueForKey:thisKey error:&error];
if (keyStatus == AVKeyValueStatusFailed) {
return ;
}
}
AVPlayerItem *item = [[AVPlayerItem alloc] initWithAsset:asset];
dispatch_async(dispatch_get_main_queue(), ^ {
[player insertItem:item afterItem:nil];
});
}];
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With