AVPlayer 项目的持续时间为 nan

Posted

技术标签:

【中文标题】AVPlayer 项目的持续时间为 nan【英文标题】:AVPlayer Item get a nan duration 【发布时间】:2014-05-26 16:46:03 【问题描述】:

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

 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");

        
    

我什么都试过了。

[item duration]; /// Fail

[[item asset] duration]; /// Fail

没有任何效果

有人知道为什么吗?

【问题讨论】:

我也有同样的问题。你想出来了吗?你是怎么做到的 ?即使我已经尝试了一切。所以帮我解决这个问题。 我也有同样的问题。你找到解决方案了吗?请与我们分享。 【参考方案1】:

duration 属性的值将报告为kCMTimeIndefinite,直到基础资产的持续时间已加载。有两种方法可以确保持续时间的值只有在它可用后才被访问:

    等到AVPlayerItem 的状态为AVPlayerItemStatusReadyToPlay

    注册duration属性的键值观察,请求初始值。如果初始值报告为kCMTimeIndefinite,则AVPlayerItem 将在其值已知后立即通过键值观察通知您该项目的持续时间的可用性。

【讨论】:

为了透明度 - 正是来自文档。【参考方案2】:

对于迅捷:

if player.currentItem.status == .readyToPlay 

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


【讨论】:

【参考方案3】:

我在 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
    

请参阅 macOS 的此答案:https://***.com/a/52668213/7132300 看起来它对 iOS 12 也有效。

【讨论】:

【参考方案4】:

@voromax 是正确的。我将asset 添加到playerItem 没有首先获得duration 并且持续时间为nan

let asset = AVAsset(url: videoUrl)
self.playerItem = AVPlayerItem(asset: asset)

当我首先加载 asset.loadValuesAsynchronously 时,没有更多 nan 并且我得到了正确的 duration

let assetKeys = ["playable", "duration"]

let asset = AVAsset(url: url)
asset.loadValuesAsynchronously(forKeys: assetKeys, completionHandler: 
    DispatchQueue.main.async  [weak self] in
        self?.playerItem = AVPlayerItem(asset: asset, automaticallyLoadedAssetKeys: assetKeys)
    
)

【讨论】:

很高兴能帮上忙! ? ? ?【参考方案5】:

您可以使用资产属性。它会给你持续时间。

self.player.currentItem?.asset.duration.seconds ?? 0

【讨论】:

【参考方案6】:

我遇到了同样的问题,但我能够使用不同的方法获得持续时间。请在此处查看我的答案:https://***.com/a/38406295/3629481

【讨论】:

以上是关于AVPlayer 项目的持续时间为 nan的主要内容,如果未能解决你的问题,请参考以下文章

使用 MPRemoteCommandCenter 为 AVPlayer 和 AVAudioPlayer 添加当前时间和持续时间的位置

持续时间不是来自AVPlayer currentItem

AVPlayer url持续时间Xcode 12 [关闭]

iOS 7中的iOS 7 AVPlayer AVPlayerItem持续时间不正确

传递给不同控制器时 AVPlayer 持续时间会发生变化

AVPlayer 项目缓冲区为空