2012-01-25 16 views
5

La documentación de las manzanas alude a ella, pero ¿cómo se configura la observación de valores-clave para la propiedad loadedTimeRanges de AVPlayerItem? Esa propiedad es una NSArray que no cambia, por lo que no puede usar playerItem addObserver:self forKeyPath:@"loadedTimeRanges ...¿Es posible utilizar KVO en AVPlayerItem.loadedTimeRanges?

¿O existe otra forma de recibir notificaciones o actualizaciones cada vez que esto cambie?

Respuesta

6

En realidad, estoy usando KVO para loadedTimeRanges sin ningún problema. ¿Tal vez simplemente no estás configurando las opciones correctas? La siguiente es una modificación muy leve de algunos de los códigos en el AVPlayerDemo de Apple, y está funcionando muy bien para mí.

//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í, eran las opciones, lo dejaba en 0. ¡Gracias! –

+0

Probé esta solución al pie de la letra. Desafortunadamente, recibo una llamada inicial de KVO para loadedTimeRanges que devuelve un NSArray vacío y luego nada. – GnarlyDog

+2

Resulta que la única opción que pude obtener para trabajar con loadedTimeRanges fue NSKeyValueObservingOptionInitial. El trabajo para mí fue usar un temporizador (CADisplayLink en realidad) para verificar la propiedad loadedTimeRanges cuando un UIProgressView estaba en pantalla. Esto funciona pero me parece kludgy. Preferiría que KVO tuviera nuevos valores. – GnarlyDog

2

Derecha. loadedTimeRanges no cambia pero los objetos dentro de él cambian. Puede configurar un temporizador para ejecutar cada segundo (más o menos) e inspeccionar los valores dentro de loadedTimeRanges. Entonces verá los cambios que está buscando.

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

Esto no se disparará cuando AVPlayer pausó sin embargo. – Andy

+0

@Andy No estoy seguro de lo que quiere decir. Esto funciona perfectamente para mi. Cuando esté en pausa, loadedTimeRanges dejará de iniciar sesión, pero tan pronto como reanude continuará registrando y será obvio que los valores se han actualizado mientras estaba en pausa. – user3344977

Cuestiones relacionadas