将 URL 转换为 AVAsset - Swift
Converting URL to AVAsset - Swift
我正在尝试将我的音频播放器中的 url 转换为 AVAsset,以便我能够根据自己的喜好操纵音轨。 (我只想 trim 文件)。不幸的是,我 运行 遇到了资产未正确转换的问题。当我在转换之前打印音频 url 的持续时间时,它会正确打印出持续时间。不幸的是,当我将它转换为 AVAsset 时,它说持续时间为 0。这是怎么回事?任何指导将不胜感激!
func trimmingFunc() {
try? audioPlayer = AVAudioPlayer(contentsOf: audioURL!)
passingTime = audioPlayer.duration
audioPlayer.delegate = self
let currentDuration = audioPlayer.duration
print(currentDuration) //correctly prints duration
let filePath = URL(fileURLWithPath: (("\(String(describing: audioPlayer.url!))")))
print(filePath) //correctly prints filePath
let currentAsset = AVAsset(url: filePath)
print(CMTimeGetSeconds(currentAsset.duration) //This is printing 0
}
加载 AVAsset
是异步操作。你应该等到它准备好。 "wait" 最有效的方法是使用 KVO。
在你的 class 中,让它成为 ViewController
,让 AVAsset
成为成员并在某处给你的 trimmingFunc
打电话:
class ViewController: UIViewController {
var currentAsset: AVAsset?
override func viewDidLoad() {
super.viewDidLoad()
self.trimmingFunc()
}
....
在您的 trimmingFunc
中,订阅 以获得 currentAsset
的通知:
func trimmingFunc() {
let audioURL = URL.init(fileURLWithPath: Bundle.main.path(forResource: "Be That Man", ofType: "mp3")!)
print("audioURL=\(audioURL)")
currentAsset = AVAsset(url: audioURL)
let options = NSKeyValueObservingOptions([.new, .old, .initial, .prior])
currentAsset!.addObserver(self, forKeyPath: "duration", options: options, context: nil)
}
要接收该通知,请覆盖 NSObject
的 observeValue
函数:
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
print("\(keyPath): \(change?[.newKey])")
print(CMTimeGetSeconds(currentAsset!.duration)) //This is printing 0
}
因此,如果资源中有文件 "Be That Man.mp3",几毫秒后您会看到持续时间 = 202.945306122449
ViewController 的完整代码是 here。
我正在尝试将我的音频播放器中的 url 转换为 AVAsset,以便我能够根据自己的喜好操纵音轨。 (我只想 trim 文件)。不幸的是,我 运行 遇到了资产未正确转换的问题。当我在转换之前打印音频 url 的持续时间时,它会正确打印出持续时间。不幸的是,当我将它转换为 AVAsset 时,它说持续时间为 0。这是怎么回事?任何指导将不胜感激!
func trimmingFunc() {
try? audioPlayer = AVAudioPlayer(contentsOf: audioURL!)
passingTime = audioPlayer.duration
audioPlayer.delegate = self
let currentDuration = audioPlayer.duration
print(currentDuration) //correctly prints duration
let filePath = URL(fileURLWithPath: (("\(String(describing: audioPlayer.url!))")))
print(filePath) //correctly prints filePath
let currentAsset = AVAsset(url: filePath)
print(CMTimeGetSeconds(currentAsset.duration) //This is printing 0
}
加载 AVAsset
是异步操作。你应该等到它准备好。 "wait" 最有效的方法是使用 KVO。
在你的 class 中,让它成为 ViewController
,让 AVAsset
成为成员并在某处给你的 trimmingFunc
打电话:
class ViewController: UIViewController {
var currentAsset: AVAsset?
override func viewDidLoad() {
super.viewDidLoad()
self.trimmingFunc()
}
....
在您的 trimmingFunc
中,订阅 以获得 currentAsset
的通知:
func trimmingFunc() {
let audioURL = URL.init(fileURLWithPath: Bundle.main.path(forResource: "Be That Man", ofType: "mp3")!)
print("audioURL=\(audioURL)")
currentAsset = AVAsset(url: audioURL)
let options = NSKeyValueObservingOptions([.new, .old, .initial, .prior])
currentAsset!.addObserver(self, forKeyPath: "duration", options: options, context: nil)
}
要接收该通知,请覆盖 NSObject
的 observeValue
函数:
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
print("\(keyPath): \(change?[.newKey])")
print(CMTimeGetSeconds(currentAsset!.duration)) //This is printing 0
}
因此,如果资源中有文件 "Be That Man.mp3",几毫秒后您会看到持续时间 = 202.945306122449
ViewController 的完整代码是 here。