ios ios7 avfoundation avplayer avasset

iOS 7 AVPlayer AVPlayerItem duración incorrecta en iOS 7



ios7 avfoundation (3)

Después de jugar con diferentes formas de inicializar los objetos, llegué a una solución de trabajo:

AVURLAsset *asset = [AVURLAsset assetWithURL: url]; Float64 duration = CMTimeGetSeconds(asset.duration); AVPlayerItem *item = [AVPlayerItem playerItemWithAsset: asset]; self.avPlayer = [[AVPlayer alloc] initWithPlayerItem: item];

Parece que el valor de duración no siempre está disponible inmediatamente desde un AVPlayerItem pero parece funcionar bien con un AVAsset inmediatamente.

Tengo el siguiente código en mi aplicación:

NSURL *url = [NSURL fileURLWithPath: [self.DocDir stringByAppendingPathComponent: self.FileName] isDirectory: NO]; self.avPlayer = [AVPlayer playerWithURL: url]; Float64 duration = CMTimeGetSeconds(self.avPlayer.currentItem.duration);

Esto funcionó bien con iOS 6, pero con iOS 7 por alguna razón devuelve NaN. Al inspeccionar self.avPlayer.currentItem.duration, el objeto CMTime tiene 0 con un indicador de 17.

Curiosamente el jugador trabaja bien, solo que la duración es incorrecta.

¿Alguien más ha experimentado los mismos problemas? Estoy importando lo siguiente:

#import <Foundation/Foundation.h> #import <AVFoundation/AVFoundation.h> #import <MediaPlayer/MediaPlayer.h> #import <CoreMedia/CoreMedia.h> #import <AVFoundation/AVAsset.h>


En iOS 7, para AVPlayerItem ya creado, también puede obtener la duración del activo subyacente:

CMTimeGetSeconds([[[[self player] currentItem] asset] duration]);

En lugar de obtenerlo directamente de AVPlayerItem, que le da un NaN:

CMTimeGetSeconds([[[self player] currentItem] duration]);


La forma recomendada de hacer esto, como se describe en el manual, es observar el estado del elemento del jugador:

[self.avPlayer.currentItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionInitial context:nil];

Luego, dentro de observeValueForKeyPath:ofObject:change:context :

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { // TODO: use either keyPath or context to differentiate between value changes if (self.avPlayer.currentItem.status == AVPlayerStatusReadyToPlay) { Float64 duration = CMTimeGetSeconds(self.avPlayer.currentItem.duration); // ... } }

Además, asegúrese de eliminar el observador cuando cambie el elemento del jugador:

if (self.avPlayer.currentItem) { [self.avPlayer.currentItem removeObserver:self forKeyPath:@"status"]; }

Por cierto, también puede observar la propiedad de duration directamente; sin embargo, ha sido mi experiencia personal que los resultados no son tan confiables como deberían ser ;-)