2014-06-08 9 views
9

Capisco che quando si utilizza unper riprodurre un elenco di oggetti AVPlayerItem, il lettore precarica il prossimo elemento in coda per ricaricare più rapidamente quando l'utente accede a questo elemento.Come precaricare un AVPlayerItem

Il problema è che ho bisogno di avere più controllo su quali elementi precaricare, ad esempio voglio che il 3 brano successivo e il 2 brano precedente vengano precaricati e preparati per un caricamento veloce.

Quindi penso di gestire gli oggetti AVPlayerItem personalmente, ma non sono sicuro di come preload un AVPlayerItem?
Come posso precaricare i primi 30 secondi, ad esempio?

risposta

12

Controllare il precarico delle risorse è un problema diverso rispetto al controllo delle voci precedenti. Non appena AVQueuePlayer termina un oggetto, lo rilascerà dalla memoria insieme alla sua cache. Per aggirare questo, è possibile aggiungere gli AVPlayerItem in un array nello stesso momento in cui li si aggiunge al lettore. In questo modo, una volta che il giocatore rimuove l'oggetto, ARC saprà che c'è ancora un riferimento a quell'oggetto e non lo rilascerà. Quindi puoi semplicemente rimettere l'elemento dall'array nel player e tutto il contenuto verrà già caricato. NOTA: è possibile limitare la dimensione di questo array di cache altrimenti esso crescerà indefinitamente se gli elementi non vengono mai rimossi da esso.

Se si desidera avere maggiore controllo sul precarico, è possibile farlo caricando il bene in modo asincrono e quindi la creazione del 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]; 
    }); 

}];