基于此处的示例https://github.com/pinlunhuang/Voice-Recorder/blob/master/Voice%20Recorder/AudioRecorder.swift我创建了自己的音频录制类。它似乎工作正常,没有抛出错误并且创建了 m4a 文件,但如果我尝试重播它,则听不到声音,即使我将文件放入音频编辑器中,它也不会显示声波。请注意,我使用真实设备而不是模拟器进行测试。 有人有什么建议吗?
class SoundManager: ObservableObject {
@Published var isError = false
private var session: AVAudioSession
private var recorder: AVAudioRecorder?
init() {
session = AVAudioSession.sharedInstance()
do {
try session.setCategory(.playAndRecord, mode: .default)
try session.setActive(true)
AVAudioApplication.requestRecordPermission(completionHandler: { granted in
guard granted else {
self.isError = true
return
}
})
let fileUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first?.appendingPathComponent("TapMeRecording.m4a", conformingTo: .audio)
let settings = [AVFormatIDKey : Int(kAudioFormatMPEG4AAC),
AVSampleRateKey : 12000,
AVNumberOfChannelsKey : 1,
AVEncoderAudioQualityKey : AVAudioQuality.high.rawValue]
try recorder = AVAudioRecorder(url: fileUrl!, settings: settings)
} catch {
isError = true
}
}
func startRecording() {
recorder!.record()
}
func stopRecording() {
recorder!.stop()
}
}
}
首先请注意,您的
requestRecordPermission
代码是错误的;此方法异步调用其完成处理程序,因此您甚至在实际确定权限之前就开始记录(或尝试)。
其次,不要在代码中使用感叹号。你“认为”你不会崩溃,但你可能会崩溃。使用问号和防护装置安全地打开包装。 第三,此类问题通常是由于格式设置不当造成的。通过实验,尝试使用已知的良好设置(即使它们不是您想要的设置)。
所以,我会写:
init() {
session = AVAudioSession.sharedInstance()
do {
try session.setCategory(.playAndRecord, mode: .default)
try session.setActive(true)
AVAudioApplication.requestRecordPermission(completionHandler: { granted in
guard granted else {
self.isError = true
return
}
self.configureRecorder()
})
} catch {
print(error)
isError = true
}
}
func configureRecorder() {
guard let fileUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first?.appendingPathComponent("TapMeRecording.m4a") else {
print("no url")
return
}
let settings = [
AVFormatIDKey : Int(kAudioFormatMPEG4AAC),
AVSampleRateKey : 44100.0,
AVEncoderBitRateKey : 192000,
AVNumberOfChannelsKey : 2
]
do {
try recorder = AVAudioRecorder(url: fileUrl, settings: settings)
catch {
print(error)
isError = true
}
}
func startRecording() {
recorder?.record()
}
func stopRecording() {
recorder?.stop()
}