🐈
AVPlayerのdurationが正しく取得できない
AVPlayerのdurationが正しく取得できない
解決策
AVPlayerからではなく、AVAssetからdurationを取得する。
# これで正しい値が取得できました。
let asset = AVURLAsset(url: validURL, options: [AVURLAssetPreferPreciseDurationAndTimingKey: true])
let assetDuration = try await CMTimeGetSeconds(asset.load(.duration))
print ("asset duration :", assetDuration)
背景と試したこと
AVPlayerでmp3のdurationを取得したかったのですが、
以下のコードではdurationの値が大きくなったり小さくなったりして正しく取得できませんでした。
# 試したコード1
do {
if let currentItem = self.audioPlayer?.currentItem {
let durationSeconds = try await CMTimeGetSeconds(currentItem.asset.load(.duration))
print ("durationSeconds :", durationSeconds)
}
} catch {
print("Error: \(error)")
}
# 試したコード2
# 読み込みのタイミング関連しているかもしれないと思い以下のコードを試しましたが同じ結果でした。
func loadDuration(of url: URL) async {
let asset = AVAsset(url: url)
// Create an array containing the asset keys we need to be loaded
let keys = ["duration"]
await withCheckedContinuation { continuation in
// Load the asset's keys asynchronously
asset.loadValuesAsynchronously(forKeys: keys) {
// The keys are loaded, now access the duration
var error: NSError?
let status = asset.statusOfValue(forKey: "duration", error: &error)
if status == .loaded {
let duration = asset.duration
let durationSeconds = CMTimeGetSeconds(duration)
DispatchQueue.main.async {
print("Duration seconds:", self.timeString(time: durationSeconds))
continuation.resume()
}
} else if status == .failed {
print("Failed to load duration with error: \(String(describing: error))")
continuation.resume(throwing: (error ?? NSError(domain: "AVAssetDurationError", code: 0, userInfo: nil)) as! Never)
} else {
print("Duration not available yet.")
continuation.resume()
}
}
}
}
環境
Xcode Version 15.2
Discussion