1

我正在使用AVAudioPlayerNode附加到一个AVAudioEngine来播放声音。

要获得我正在这样做的玩家的当前时间:

extension AVAudioPlayerNode {
var currentTime: TimeInterval {
    get {
        if let nodeTime: AVAudioTime = self.lastRenderTime, let playerTime: AVAudioTime = self.playerTime(forNodeTime: nodeTime) {
            return Double(playerTime.sampleTime) / playerTime.sampleRate
        }
        return 0
    }
 }

}

我有一个滑块,指示音频的当前时间。当用户更改滑块值时,.ended我必须将播放器的当前时间更改为滑块中指示的时间。为此:

extension AVAudioPlayerNode {

func seekTo(value: Float, audioFile: AVAudioFile, duration: Float) {
    if let nodetime = self.lastRenderTime{
        let playerTime: AVAudioTime = self.playerTime(forNodeTime: nodetime)!
        let sampleRate = self.outputFormat(forBus: 0).sampleRate
        let newsampletime = AVAudioFramePosition(Int(sampleRate * Double(value)))
        let length = duration - value
        let framestoplay = AVAudioFrameCount(Float(playerTime.sampleRate) * length)
        self.stop()

        if framestoplay > 1000 {
            self.scheduleSegment(audioFile, startingFrame: newsampletime, frameCount: framestoplay, at: nil,completionHandler: nil)
        }
    }
    self.play()
}

但是,我的函数seekTo无法正常工作(我在函数之前和之后打印 currentTime,它始终显示负值 ~= -0.02)。我做错了什么,我能找到一种更简单的方法来更改播放器的 currentTime 吗?

4

1 回答 1

0

我遇到了同样的问题。显然framestoplay总是 0,这是因为sampleRate. 在我的情况下,值playerTime.sampleRate始终为 0。

所以,

let framestoplay = AVAudioFrameCount(Float(playerTime.sampleRate) * length)

必须替换为

let framestoplay = AVAudioFrameCount(Float(sampleRate) * length)
于 2020-01-02T10:47:52.710 回答