每当我将 AVAudioFile 设置framePosition
为当前 framePosition 以外的其他内容时,我都会崩溃:
错误 - 6658
我在 Apple Docs 中查找的是:
kExtAudioFileError_InvalidSeek:写入尝试或偏移量超出范围。
这对我来说很奇怪,因为我可以确认我尝试设置的framePosition
位置小于 AVAudioFile'slength
并且高于 0,因此帧不应该超出范围。
代码:
// Start Recording to file
func startRecording(atTimeInFile: TimeInterval) throws {
let tapNode: AVAudioNode = mixerNode
let format = tapNode.outputFormat(forBus: 0)
let semaphore = DispatchSemaphore(value: 0)
duration = 0
startTime = atTimeInFile
// Check to see if recording file already has content
let f: AVAudioFile? = {
if FileManager.default.fileExists(atPath: FileManagerHelper.recordingLocalURL().relativePath) {
return try? AVAudioFile(forReading: FileManagerHelper.recordingLocalURL())
} else {
return nil
}
}()
if let f = f {
// The file we opened for writing already has data written to it
// Let's load the buffer data in from that the file
guard let bufferData = AVAudioPCMBuffer(pcmFormat: f.processingFormat, frameCapacity: AVAudioFrameCount(f.length)) else {
throw NSError(domain: "Failed to load the content of the existing file.", code: -10, userInfo: nil)
}
bufferData.frameLength = bufferData.frameCapacity
do {
try f.read(into: bufferData)
} catch {
throw NSError(domain: "Failed to read from the content of the existing file.", code: -20, userInfo: nil)
}
// AVAudioFile uses the Core Audio Format (CAF) to write to disk.
// So we're using the caf file extension.
file = try AVAudioFile(forWriting: FileManagerHelper.recordingLocalURL(), settings: format.settings)
do {
file!.framePosition = 0
try self.file!.write(from: bufferData)
} catch {
throw NSError(domain: "Failed to write from the content of the existing file.", code: -30, userInfo: nil)
}
}
else {
file = try AVAudioFile(forWriting: FileManagerHelper.recordingLocalURL(), settings: format.settings)
}
if file!.duration == 0 {
file!.framePosition = AVAudioFramePosition(0)
} else {
let percentThrough = CGFloat(atTimeInFile) / CGFloat(file!.duration)
let pos = AVAudioFramePosition(percentThrough * CGFloat(file!.length))
file!.framePosition = pos // CRASH OCCURS HERE
}
tapNode.installTap(onBus: 0, bufferSize: bufferSize, format: format, block: {
(buffer, _) in
do {
buffer.frameLength = 1024 // Tap is now called every 40ms. By default, tap is called every 0.375s
try self.file!.write(from: buffer)
self.delegate?.recorderDidRecieveAudioBuffer(self, buffer: buffer)
semaphore.signal()
} catch {
log("Error writing mic data to file.", msgType: .error)
}
})
try engine.start()
semaphore.wait()
state = .recording
startObservingTime()
}
这是崩溃的完整描述:
ExtAudioFile.cpp:1084:Seek: about to throw -66568: seek to frame in audio file
2020-11-09 18:01:46.032612-0800 Application[15316:800908] [avae] AVAEInternal.h:109 [AVAudioFile.mm:515:-[AVAudioFile setFramePosition:]: (ExtAudioFileSeek(_imp->_extAudioFile, pos)): error -66568
2020-11-09 18:01:46.034491-0800 Application[15316:800908] *** Terminating app due to uncaught exception 'com.apple.coreaudio.avfaudio', reason: 'error -66568'
*** First throw call stack:
(0x187b1c878 0x19c072c50 0x187a22000 0x197aa3e48 0x197b4270c 0x1004fc164 0x10048b43c 0x10048b198 0x10048b254 0x18a010e54 0x18a01a7b8 0x18a0173f4 0x18a01696c 0x18a00aa98 0x18a009e44 0x18a5111b4 0x18a4ea4ec 0x18a574488 0x18a577440 0x18a56e8ec 0x187a9876c 0x187a98668 0x187a97960 0x187a91a8c 0x187a9121c 0x19eb10784 0x18a4ca200 0x18a4cfa74 0x10048f270 0x1877516c0)
libc++abi.dylib: terminating with uncaught exception of type NSException
*** Terminating app due to uncaught exception 'com.apple.coreaudio.avfaudio', reason: 'error -66568'
terminating with uncaught exception of type NSException
更新 1:我注意到我可以设置 的 framePosition f
,即为阅读而打开的 AVAudioFile,但我仍然无法设置 的file
framePosition ,为使用相同的 URL 编写打开的 AVAudioFile 。
更新 2:我尝试将文件写入一个单独的 URL,而不是通过替换读取它
file = try AVAudioFile(forWriting: FileManagerHelper.recordingLocalURL(), settings: format.settings)
和
file = try AVAudioFile(forWriting: FileManagerHelper.recordingLocalURL2(), settings: format.settings)
在if let f = f
街区。
但是,在设置成名位置时,我仍然会出现越界错误。