如何解决AudioKit AKPlayer 无法环回以 setPosition 开头
在 v4 中,如果您将 <a class="carousel-control-prev" href="#carouselExampleControls" ...
与循环一起使用并使用 AKPlayer
API,则播放器在使用 setPosition
设置的位置和播放器总持续时间之间循环。我需要的是从 setPosition
API 设置的位置开始,并在循环发生时循环到开头。我不确定这是否是故意的,但我需要能够在播放器中寻找某个点并循环到开头,现在看来这不是 AudioKit 中的功能。
有没有办法或解决方法来实现这一目标?我需要将其作为一项要求来完成。
在这里重现一个完整的操场示例:
setPosition
预期行为 我预计它会循环回到开头。
详情:
- AudioKit 4.11.2 版
解决方法
如果您打算开发某种循环播放器应用程序,我认为该方法是使用音序器来协调音频文件的播放。在应该开始播放声音的每个位置,您向序列添加一个事件。
音序器可以连接到回调工具,这是一个将事件传递给用户定义函数的节点。在您的回调函数中,您将开始播放由该事件指示的音频文件。
这是应该做的事情的大纲:
- 使用 AKSequencer 的 addTrack 方法创建一个轨道以包含播放事件。将此轨道连接到 AKCallbackInstrument。请参阅 this answer 了解如何将 AKCallbackInstrument 连接到 AKSequencer 轨道。将音序器和曲目的
length
设置为歌曲的总持续时间(注意这些属性以节拍而不是秒表示)。根据需要设置音序器的loopEnabled
。 - 将播放事件添加到轨道,在您希望播放每个声音的时间位置。由于您将使用回调函数自己解释事件,因此使用什么类型的事件并不重要。您可以简单地使用
Note On
。 - 在回调函数中,当收到该事件时开始播放相应的声音。
您需要几个类来表示有关每个样本在歌曲中出现的位置的一些基本信息:
class Beat {
var sample: Sample!
var onsetTime: Double
var endTime {
get {
return onsetTime + sample.duration
}
}
}
class Sample {
var url: URL!
var duration: Double
}
class ViewController: UIViewController {
var samples: [Sample] = []
var beats: [Beat] = []
var player: AKPlayer!
var sequencer: AKSequencer!
}
在音符的音高上,您将存储要播放的样本的索引。这是您的回调函数的样子:
func playCallback(status:UInt8,note:MIDINoteNumber,vel:MIDIVelocity) -> () {
guard let status = AKMIDIStatus(byte: status),let type = status.type,type == .noteOn else { return }
DispatchQueue.main.async {
player.load(samples[note].url)
player.play()
}
}
您可以使用 AKSequencer
的 seek
方法在任意位置开始播放您的歌曲。
有一种特殊情况,即音序器在节拍中间开始播放。在这种情况下,您必须手动开始播放该样本。
func play(at time: Double = 0) {
sequencer.seek(time)
sequencer.play()
for beat in beats {
if beat.onsetTime < time && time < beat.endTime {
player.load(beat.sample.url)
player.play(from: time - beat.onsetTime)
}
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。