and*_*lin 5 core-audio swift avaudioengine avaudiofile
我正在创建一个AVAudioFile,用于将声音写入声音文件.如果文件已经存在,我想将framePosition移动到文件的末尾,以便在最后继续写入,而不是替换现有文件.
我做了一些测试,尝试将文件中的缓冲区读入一个具有不同URL的新文件,以便它不会覆盖原始文件.当我尝试将缓冲区读入新文件时,我遇到了崩溃:
let audioFile = try AVAudioFile(forReading: [URL to existing .caf file])
let audioFrameCount = AVAudioFrameCount(UInt32(audioFile.length))
let audioBuffer = AVAudioPCMBuffer(PCMFormat: audioFile.processingFormat, frameCapacity: audioFrameCount)
let newAudioFile = try AVAudioFile(forWriting: [another URL], settings: self.engine.mainMixerNode.outputFormatForBus(0).settings)
try newAudioFile.readIntoBuffer(audioBuffer, frameCount: audioFrameCount!) <-- CRASHES ON THIS LINE
Run Code Online (Sandbox Code Playgroud)
崩溃日志:因未捕获的异常'com.apple.coreaudio.avfaudio'而终止应用程序,原因:'error -50'
伙计,我真的很讨厌CoreAudio崩溃日志.他们绝对没有告诉我!
是不是可以将数据读入为写入而创建的文件中?
UPDATE
好的,所以经过一些建议我做了一些改变.基本上,这些是我正在采取的步骤:
但是,写入后,新文件的长度为0.
这是我的代码:
//Check if a file already exists. If so continue to record at the end of it
var audioBuffer : AVAudioPCMBuffer!
var audioFrameCount : AVAudioFrameCount!
if (NSFileManager.defaultManager().fileExistsAtPath(self.audioRecordURL.path!)) {
do {
let existingAudioFile = try AVAudioFile(forReading: self.audioRecordURL)
audioFrameCount = AVAudioFrameCount(existingAudioFile.length)
if (audioFrameCount > 0) {
audioBuffer = AVAudioPCMBuffer(PCMFormat: existingAudioFile.processingFormat, frameCapacity: audioFrameCount)
}
} catch let error as NSError {
NSLog("Error reading buffer from file %@", error.localizedDescription)
}
}
//Create a new file. This will replace the old file
do {
self.audioFile = try AVAudioFile(forWriting: self.audioRecordURL, settings: self.engine.mainMixerNode.outputFormatForBus(0).settings)
} catch let error as NSError {
NSLog("Error creating AVAudioFile %@", error.localizedDescription)
}
//Read the audio buffer from the old file into the new file
if (audioBuffer != nil) {
do {
try self.audioFile.writeFromBuffer(audioBuffer)
self.audioFile.framePosition = self.audioFile.length
} catch let error as NSError {
NSLog("Error reading buffer into file %@", error.localizedDescription)
}
}
Run Code Online (Sandbox Code Playgroud)
顺便说一句,readIntoBuffer的命名对我来说非常混乱.听起来好像你应该使用该方法将文件读入缓冲区,但根据文档,您应该使用它来将缓冲区读入文件中?那么为什么我不能使用该方法将缓冲区添加到我的文件中呢?为什么我必须使用writeFromBuffer?
更新2
所以,我设法解决了它.显然我必须先调用readIntoBuffer来实际用数据填充缓冲区才能使用它.所以我添加了这一行
try existingAudioFile.readIntoBuffer(audioBuffer)
Run Code Online (Sandbox Code Playgroud)
后
audioBuffer = AVAudioPCMBuffer(PCMFormat: existingAudioFile.processingFormat, frameCapacity: audioFrameCount)
Run Code Online (Sandbox Code Playgroud)
不确定这是否只是您在此处提供的代码中的拼写错误,而且我不是该领域的专家,但想必您的意思是让崩溃的行是:
try audioFile.readIntoBuffer(audioBuffer, frameCount: audioFrameCount!)
Run Code Online (Sandbox Code Playgroud)
因为按理说您无法从打开用于写入的文件(newAudioFile)中读取内容。
然后填充该缓冲区后,您需要使用 writeFromBuffer https://developer.apple.com/library/ios/documentation/AVFoundation/Reference/AVAudioFile_Class/#//apple_ref/occ/instm/AVAudioFile/写入新文件 writeFromBuffer:错误: