iOS 7 AVPlayer AVPlayerItem durée incorrecte Dans iOS 7

j'ai le code suivant dans mon application:

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

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

cela a bien fonctionné avec iOS 6 mais avec iOS 7 pour une raison quelconque il retourne NaN. Lors de l'inspection de l'auto.avPlayer.currentItem.durée L'objet CMTime a des 0 avec un drapeau de 17.

il est intéressant de noter que le joueur fonctionne bien, juste la durée est fausse.

quelqu'un d'autre A connu les mêmes problèmes? Je suis d'importer les éléments suivants:

#import <Foundation/Foundation.h>
#import <AVFoundation/AVFoundation.h>
#import <MediaPlayer/MediaPlayer.h>
#import <CoreMedia/CoreMedia.h>
#import <AVFoundation/AVAsset.h>
28
demandé sur Matt Wolfe 2013-09-28 00:13:55

3 réponses

après avoir joué avec différentes façons d'initialiser les objets, je suis arrivé à une solution de travail:

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

il semble que la valeur de la durée n'est pas toujours immédiatement disponible à partir D'un AVPlayerItem mais elle semble fonctionner correctement avec un AVAsset immédiatement.

49
répondu Matt Wolfe 2013-09-27 20:24:17

Dans iOS 7, pour AVPlayerItem déjà créé, vous pouvez également obtenir la durée de la sous-jacente de l'actif:

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

au lieu de l'obtenir directement de AVPlayerItem, ce qui vous donne un NaN:

CMTimeGetSeconds([[[self player] currentItem] duration]);
26
répondu Derek Li 2013-12-27 07:17:55

recommandé de le faire, comme décrit dans manuel est en observant le joueur statut du poste:

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

Puis, à l'intérieur 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);
        // ...
    }
}

assurez-vous également de supprimer l'observateur lorsque vous changez l'élément du lecteur:

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

Btw, vous pouvez également observer les duration propriété directement; cependant, d'après mon expérience personnelle, les résultats ne sont pas aussi fiables qu'ils devraient l'être; -)

4
répondu Ja͢ck 2015-01-06 11:25:32