如何解决AudioKit AKPlayer 在 AVAudioTime 方法中停止
在 AudioKit 中,AKPlayer 有这个方法:
@objc dynamic public func play(at audioTime: AVAudioTime?)
我想要同样的停止方法,因为我希望能够在用户点击停止按钮时随时停止播放器。我正在制作一个音乐应用程序,我需要在 X 时间内停止声音,这是基于 BPM 等计算的。
这是我开始AKPlayer
的方式:
drums.play(at: AVAudioTime.now() + timeToClosestBeatGrid)
我想要与停止相同的 API:
drums.stop(at: AVAudioTime.now() + timeToClosestBeatGrid) // this api doesnt exist :(((
我尝试通过设置 endTime
属性来使用它,但它似乎没有做任何事情...
我怎样才能做到这一点?
PS:我不是在寻找计时器解决方案,这是因为计时器不是 100% 准确的。我希望我的停止方法像播放方法一样 100% 准确
解决方法
在 AudioKit 中安排事件的最准确方法是使用 AKSequencer。音序器可以连接到回调工具,这是一个将事件传递给用户定义函数的节点。
在您的情况下,您将在您希望玩家停止的时间添加一个事件。在您的回调函数中,您将停止播放器作为对该事件的响应。
这是应该做的事情的大纲:
- 使用 AKSequencer 的 addTrack 方法创建一个轨道以包含停止事件。将此轨道连接到 AKCallbackInstrument。请参阅this answer,了解如何将 AKCallbackInstrument 连接到 AKSequencer 轨道。
- 将停止事件添加到轨道,在您希望音乐停止的时间位置。由于您将使用回调函数自己解释事件,因此您使用什么类型的事件并不重要。您可以简单地使用
Note On
。 - 在回调函数中,当收到该事件时停止播放器。
这就是你的回调函数的样子:
func stopCallback(status:UInt8,note:MIDINoteNumber,vel:MIDIVelocity) -> () {
guard let status = AKMIDIStatus(byte: status),let type = status.type,type == .noteOn else { return }
drums.stop()
}
,
根据 AudioKit 文档,您可以尝试使用 schedule(at:)
方法:
您可以调用它来安排将来的播放,或者播放器会在调用 play() 加载音频数据时调用它
在 play()
方法之后,您应该使用偏移量 schedule(at:)
声明此 AVAudioTime.now() + timeToClosestBeatGrid
并指定 .dataPlayedBack
作为完成回调类型,因为在(来自文档)时调用此完成...
缓冲区或文件已播放完毕
现在(在完成块中)您可以调用 drums.stop()
但是...如果每次按下按钮都应该调用 .stop()
方法,为什么不使用某种形式的延迟(Timer 或 DispatchQueue),并将值 timeToClosestBeatGrid
作为偏移量?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。