尝试在iOS 11.1上使用AudioKit 4.0,Swift 4渲染一系列AKAudioPlayers时获得一些奇怪的结果
我知道开发分支(https://github.com/AudioKit/AudioKit/commit/09aedf7c119a399ab00026ddfb91ae6778570176)上的AudioKit.renderToFile替代方案,但如果可能的话,我想覆盖iOS 9+
预期结果: 一个长音频文件,每个文件(URL)按顺序呈现
实际结果: 仅渲染最后一个计划文件(在生成的wav文件中的正确偏移处)
奇怪的是,如果我将它们全部安排在0偏移处,它们都会被渲染。另外,如果我在没有渲染的情况下回放东西,听起来是正确的(尽管我必须调整AVAudioTime以使用mach_absolute_time)
似乎安排AKAudioPlayer取消前一个。
设定:
class func initialize (){
// ....
do {
try AKSettings.setSession(category: .playAndRecord, with: .allowBluetoothA2DP)
} catch {
AKLog("Could not set session category.")
}
//AKSettings.playbackWhileMuted = true
AKSettings.defaultToSpeaker = true
mainMixer = AKMixer()
offlineRender = AKOfflineRenderNode()
mainMixer! >>> offlineRender!
AudioKit.output = offlineRender!
AudioKit.start()
// ....
渲染:
class func testRender(urls: [URL], dest: URL, offset: TimeInterval = 2){
// Stop / Start AudioKit when switching internalRenderEnabled, otherwise I get the following error:
// *** Terminating app due to uncaught exception 'com.apple.coreaudio.avfaudio', reason: 'player started when engine not running'
AudioKit.stop()
var players = [AKAudioPlayer]()
var scheduleTime : TimeInterval = 0
// create players
for url in urls {
do {
let file = try AKAudioFile(forReading: url)
let player = try AKAudioPlayer(file: file)
players.append(player)
player.connect(to: mainMixer!)
print("Connecting player")
} catch {
print("error reading")
}
}
offlineRender!.internalRenderEnabled = false
AudioKit.start()
for player in players{
do {
// 0 instead of mach_absolute_time(), otherwise the result is silent
let avTime = AKAudioPlayer.secondsToAVAudioTime(hostTime: 0, time: scheduleTime)
// schedule and play according to:
// https://stackoverflow.com/questions/45799686/how-to-apply-audio-effect-to-a-file-and-write-to-filesystem-ios/45807586#45807586
player.schedule(from: 0, to: player.duration, avTime: nil)
player.play(at: avTime);
scheduleTime += offset
} catch {
print("error reading")
}
}
// add some padding
scheduleTime += 3
let duration = scheduleTime
do {
try offlineRender!.renderToURL(dest, seconds: duration)
} catch {
print("error rendering")
}
// cleanup
players.forEach { $0.schedule(from: 0, to: $0.duration, avTime: nil)}
players.forEach({$0.stop()})
players.forEach({$0.disconnectOutput()})
offlineRender!.internalRenderEnabled = true
}
感谢任何帮助!
答案 0 :(得分:3)
从iOS 11.0开始,不推荐使用AKOfflineRenderNode。版本4.0.4有一个AudioKit.renderToFile方法来替换它。它最近更新(2017年底)。
答案 1 :(得分:3)
所以看起来AKOFflineRednerNode确实在即将推出的AudioKit版本中被弃用,而且不适用于iOS11。阅读GitHub上讨论问题的评论听起来好像计划是将新的(iOS11 +)离线渲染和旧的(iOS9-10)封装在一个通用接口(AudioKit.renderToFile)下。但是现在它似乎只是iOS11。
使用dev版本进行一些测试(在此处安装说明:https://github.com/audiokit/AudioKit/blob/master/Frameworks/README.md)后,我获得了以下代码:
try AudioKit.renderToFile(outputFile, seconds: duration, prerender: {
var scheduleTime : TimeInterval = 0
for player in players{
let dspTime = AVAudioTime(sampleTime: AVAudioFramePosition(scheduleTime * AKSettings.sampleRate), atRate: AKSettings.sampleRate)
player.play(at: dspTime)
scheduleTime += offset
}
})
除非有人能够提供使得OnlineRenderNode在iOS11上运行的解决方法,并且直到正式发布带有renderToFile的AudioKit,这才是我能找到的最佳答案。