2012-01-25 16 views
5

La documentazione delle mele allude ad esso, ma come si imposta l'osservazione valore-chiave per la proprietà loadedTimeRanges di AVPlayerItem? Quella proprietà è un NSArray che non cambia, quindi non puoi semplicemente usare playerItem addObserver:self forKeyPath:@"loadedTimeRanges ...È possibile KVO su AVPlayerItem.loadedTimeRanges?

Oppure c'è un altro modo per ricevere notifiche o aggiornamenti quando questo cambia?

risposta

6

In realtà, sto utilizzando KVO per LoadTimeRanges senza alcun problema. Forse non stai semplicemente impostando le opzioni giuste? Quanto segue è una lievissima modifica di parte del codice in Apple AVPlayerDemo, e funziona abbastanza bene per me.

//somewhere near the top of the file 
NSString * const kLoadedTimeRangesKey = @"loadedTimeRanges"; 
static void *AudioControllerBufferingObservationContext = &AudioControllerBufferingObservationContext; 


- (void)someFunction 
{ 
    // ... 

    //somewhere after somePlayerItem has been initialized 
    [somePlayerItem addObserver:self 
         forKeyPath:kLoadedTimeRangesKey 
          options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew 
          context:AudioControllerBufferingObservationContext]; 

    // ... 
} 

- (void)observeValueForKeyPath:(NSString*) path 
        ofObject:(id)object 
        change:(NSDictionary*)change 
        context:(void*)context 
{ 
    if (context == AudioControllerBufferingObservationContext) 
    { 
     NSLog(@"Buffering status: %@", [object loadedTimeRanges]); 
    } 
} 
+0

Sì, erano le opzioni, stavo lasciando impostato su 0. Grazie! –

+0

Ho provato questa soluzione alla lettera. Sfortunatamente, ricevo una chiamata KVO iniziale per loadTimeRanges che restituisce un NSArray vuoto e quindi nulla. – GnarlyDog

+2

Si scopre che l'unica opzione che potrei ottenere per funzionare con loadTimeRanges era NSKeyValueObservingOptionInitial. Il mio compito consisteva nell'usare un Timer (CADisplayLink in realtà) per controllare la proprietà loadedTimeRanges quando UIProgressView era sullo schermo. Funziona, ma sembra triste per me. Preferirei KVO qualsiasi nuovo valore. – GnarlyDog

2

Diritto. loadedTimeRanges non cambia ma cambiano gli oggetti al suo interno. È possibile impostare un timer per eseguire ogni secondo (o così) e ispezionare i valori all'interno di loadedTimeRanges. Quindi vedrai le modifiche che stai cercando.

dispatch_queue_t queue = dispatch_queue_create("playerQueue", NULL); 

[player addPeriodicTimeObserverForInterval:CMTimeMake(1, 1) 
              queue:queue 
            usingBlock:^(CMTime time) { 
             for (NSValue *time in player.currentItem.loadedTimeRanges) { 
              CMTimeRange range; 
              [time getValue:&range]; 
              NSLog(@"loadedTimeRanges: %f, %f", CMTimeGetSeconds(range.start), CMTimeGetSeconds(range.duration)); 
             } 
            }]; 
+0

Questo non si attiva quando AVPlayer è in pausa. – Andy

+0

@Andy Non sei sicuro di cosa intendi. Questo funziona perfettamente per me. Quando viene messo in pausa, i LoadTimeRanges interromperanno la registrazione, ma non appena riprenderanno continueranno a registrare e sarà ovvio che i valori sono stati aggiornati durante la pausa. – user3344977