AVPlayer项目获得持续时间

Ped*_*dro 9 objective-c ios avplayer

我正在播放文件.来自url的mp3流.我正在使用AVPlayer,当我试图获得构建进度条的总时间时,只要时间是南,我就会得到.

 NSError *setCategoryError = nil;
    if ([ [AVAudioSession sharedInstance] isOtherAudioPlaying]) { // mix sound effects with music already playing
        [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategorySoloAmbient error:&setCategoryError];
    } else {
        [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:&setCategoryError];
    }
    if (setCategoryError) {
        NSLog(@"Error setting category! %ld", (long)[setCategoryError code]);
    }
    NSURL *url = [NSURL URLWithString:@"http://..//46698"];

    AVPlayer *player = [AVPlayer playerWithURL:url];
    songPlayer=player;
    [songPlayer addObserver:self forKeyPath:@"status" options:0 context:nil];



- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {

    if (object == songPlayer && [keyPath isEqualToString:@"status"]) {
        if (songPlayer.status == AVPlayerStatusFailed) {
            NSLog(@"AVPlayer Failed");

        } else if (songPlayer.status == AVPlayerStatusReadyToPlay) {
            NSLog(@"AVPlayerStatusReadyToPlay");
            [songPlayer play];
            [songPlayer addPeriodicTimeObserverForInterval:CMTimeMake(1, 1) queue:dispatch_get_main_queue() usingBlock:^(CMTime time){
                CMTime aux = [songPlayer currentTime];
                AVPlayerItem *item=[songPlayer currentItem];
                CMTime dur=[item duration];
                NSLog(@"%f/%f", CMTimeGetSeconds(aux),  CMTimeGetSeconds(dur));
            }];
        } else if (songPlayer.status == AVPlayerItemStatusUnknown) {
            NSLog(@"AVPlayer Unknown");

        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我已经尝试了一切.

[item duration]; /// Fail

[[item asset] duration]; /// Fail
Run Code Online (Sandbox Code Playgroud)

什么都行不通

谁知道为什么?

vor*_*max 8

duration财产价值将被报告为kCMTimeIndefinite加载标的资产的持续时间.有两种方法可以确保只有在可用时才访问持续时间的值:

  1. 等到状态AVPlayerItemAVPlayerItemStatusReadyToPlay.

  2. 注册duration属性的键值观察,请求初始值.如果初始值报告为kCMTimeIndefinite,则AVPlayerItem一旦其值已知,将通过键值观察通知您项目持续时间的可用性.


小智 6

对于快速:

if player.currentItem.status == .readyToPlay {

    print(currentItem.duration.seconds) // it't not nan

}
Run Code Online (Sandbox Code Playgroud)


alg*_*rid 5

我在 iOS 12 上遇到这个问题(对于 iOS 13 一切都按预期工作)。当前项目的持续时间始终是不确定的。我通过使用解决它player.currentItem?.asset.duration。像这样的东西:

private var currentItemDuration: CMTime? {
    if #available(iOS 13.0, *) {
        return player?.currentItem?.duration
    } else {
        return player?.currentItem?.asset.duration
    }
}
Run Code Online (Sandbox Code Playgroud)

请参阅适用于 macOS 的答案:/sf/answers/3686774941/看起来它也适用于 iOS 12。