我正在播放文件。来自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");
}
}
}
我已经尝试了一切。
[item duration]; /// Fail
[[item asset] duration]; /// Fail
并且没有任何作用
任何人都知道为什么?
答案 0 :(得分:8)
duration
属性的值将报告为kCMTimeIndefinite
,直到加载基础资产的持续时间为止。有两种方法可以确保只有在可用时才访问持续时间值:
等到AVPlayerItem
的状态为AVPlayerItemStatusReadyToPlay
。
注册duration
属性的键值观察,请求初始值。如果初始值报告为kCMTimeIndefinite
,则AVPlayerItem
会在知道其值后立即通过键值观察通知您项目持续时间的可用性。
答案 1 :(得分:4)
要迅速:
if player.currentItem.status == .readyToPlay {
print(currentItem.duration.seconds) // it't not nan
}
答案 2 :(得分:1)
我遇到了同样的问题,但我能够用不同的方法获得持续时间。请在此处查看我的回答:https://stackoverflow.com/a/38406295/3629481
答案 3 :(得分:1)
您可以使用资产属性。它会给你持续时间。
self.player.currentItem?.asset.duration.seconds ?? 0
答案 4 :(得分:0)
我在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://stackoverflow.com/a/52668213/7132300似乎也适用于iOS 12。
答案 5 :(得分:0)
@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)
}
})