2013-09-27 9 views
27

Mam następujący kod w mojej aplikacji:iOS 7 AVPlayer AVPlayerItem trwania niepoprawny w iOS 7

NSURL *url = [NSURL fileURLWithPath: [self.DocDir stringByAppendingPathComponent: self.FileName] isDirectory: NO]; 
self.avPlayer = [AVPlayer playerWithURL: url]; 

Float64 duration = CMTimeGetSeconds(self.avPlayer.currentItem.duration); 

To działało w porządku z iOS 6, ale z iOS 7 z jakiegoś powodu zwraca NaN. Podczas inspekcji self.avPlayer.currentItem.duration obiekt CMTime ma 0 z flagą 17.

Co ciekawe, odtwarzacz działa dobrze, tylko czas trwania jest zły.

Czy ktoś jeszcze doświadczył tych samych problemów? Jestem importowanie następujące:

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

Odpowiedz

48

Po zabawy z różnych sposobów inicjowania obiektów przyjechałem w roztworze roboczym: Wydaje

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

wartość czas nie zawsze jest od razu dostępne z AVPlayerItem, ale wydaje się, że działa poprawnie z AVAsset natychmiast.

+0

Witam To nie działa dla mnie. jakiejkolwiek innej alternatywy? – Nitesh

+0

Cześć Nitesh, zadaj pytanie w nowym wątku, pokazując część kodu i błędy/błędy, które otrzymujesz. –

+2

Używałem także [[AVPlayer currentItem] duration], który zwraca NaN w iOS 7 dla poprawnych plików multimedialnych. W systemie iOS 6, jeśli zwrócono NaN, oznaczało to, że pliku nie można odtworzyć. Przejście do pomysłu AVURLAsset rozwiązuje ten problem. – Deminetix

24

w iOS 7, dla AVPlayerItem już utworzone, można również uzyskać czas z pod nią aktywów:

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

Zamiast dostać bezpośrednio z AVPlayerItem, co daje NaN:

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

Dzięki za to! – JKoko

+0

fantastyczne! DZIĘKI – SpaceDog

4

Zalecanym sposobem postępowania zgodnie z opisem w dokumencie the manual jest obserwowanie statusu elementu odtwarzacza:

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

Następnie wewnątrz 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); 
     // ... 
    } 
} 

Ponadto, upewnij się, że usunąć obserwatora przy zmianie pozycji gracza:

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

Btw, można również obserwować właściwość duration bezpośrednio; jednak moim osobistym doświadczeniem było to, że wyniki nie są tak wiarygodne, jak powinny ;-)

+0

Niestety to nie działa w iOS 10.x – user3069232

+0

@ user3069232 przez "nie działa", co masz na myśli? jakie są twoje spostrzeżenia? –

+0

Zwraca nan ... Skończyło się na użyciu kombinacji zestawu AVURLAsset i statusu AVPlayer, który tu użyto, aby działał. – user3069232