AVQueuePlayer返回音频时长为nan通常是因为AVPlayerItem还没有准备好获取音频时长。解决方法是使用AVPlayerItem的KVO观察者模式,等待AVPlayerItem准备好后再获取音频时长。
以下是一个使用KVO观察者模式的示例代码:
import AVFoundation
class ViewController: UIViewController {
var player: AVQueuePlayer?
override func viewDidLoad() {
super.viewDidLoad()
// 创建AVPlayerItem对象
let url = URL(fileURLWithPath: Bundle.main.path(forResource: "audio", ofType: "mp3")!)
let playerItem = AVPlayerItem(url: url)
// 观察AVPlayerItem的status属性
playerItem.addObserver(self, forKeyPath: "status", options: .new, context: nil)
// 创建AVQueuePlayer对象
player = AVQueuePlayer(playerItem: playerItem)
}
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if keyPath == "status", let playerItem = object as? AVPlayerItem {
if playerItem.status == .readyToPlay {
// AVPlayerItem准备好后获取音频时长
let duration = playerItem.asset.duration
let durationInSeconds = CMTimeGetSeconds(duration)
print("音频时长: \(durationInSeconds) 秒")
// 移除观察者
playerItem.removeObserver(self, forKeyPath: "status")
}
}
}
}
在上面的代码中,我们首先创建了一个AVPlayerItem对象,并观察其status属性的变化。当AVPlayerItem的status变为.readyToPlay时,说明AVPlayerItem已经准备好可以获取音频时长了。在这个时候,我们可以通过playerItem.asset.duration
来获取音频的时长,然后使用CMTimeGetSeconds
方法将时长转换为秒。
注意:在获取到音频时长后,我们移除了观察者,以防止内存泄漏。