Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to preload a AVPlayerItem

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?

like image 452
Eyal Avatar asked Jun 08 '14 16:06

Eyal


1 Answers

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];
     });

 }];
like image 182
Oren Avatar answered Nov 15 '22 04:11

Oren