Cómo precargar un AVPlayerItem

Entiendo que cuando se utiliza un AVQueuePlayer para reproducir una list de objects AVPlayerItem , el jugador precarga el siguiente elemento en la queue para recargarlo más rápido cuando el usuario llega a este elemento.

El problema es que necesito tener más control sobre qué precarga de elementos, por ejemplo, quiero que las 3 canciones siguientes y las 2 canciones anteriores se precarguen y se preparen para una carga rápida.

Por lo tanto, creo que para administrar los objects AVPlayerItem yo mismo, no estoy seguro de cómo puedo precargar un AVPlayerItem ?
¿Cómo puedo cargar los primeros 30 segundos, por ejemplo?

Controlar la precarga de los activos es un problema diferente al de controlar los elementos anteriores. Tan pronto como AVQueuePlayer termine un elemento, lo liberará de la memory junto con su caching. Para solucionarlo, puede agregar AVPlayerItems a una matriz al mismo time que los agrega al reproductor. De esta manera, una vez que el jugador quita el elemento, ARC sabrá que todavía hay una reference a ese object y no la liberará. Entonces, simplemente puede volver a colocar el elemento de la matriz en el reproductor y ya se cargará todo el contenido. NOTA: es posible que desee limitar el tamaño de esta matriz de caching, de lo contrario, crecerá indefinidamente si los elementos nunca se eliminan de ella.

Si desea tener más control sobre la precarga, puede hacerlo cargando el activo de forma asíncrona y luego creando 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]; }); }];