使用 AVAudioRecorder 录制后 AVAudioPlayer 不通过扬声器播放
AVAudioPlayer NOT playing through speaker after recording with AVAudioRecorder
我正在开发一款可以录制和播放录制音频的应用程序。我正在使用 AVAudioSession
将类别更改为 playAndRecord
并将其传递给 defaultToSpeaker
.
我的问题是,如果我启动该应用程序,播放较早的录音,它会按照我的意愿通过底部(声音更大的)扬声器播放,但如果我启动应用程序并开始录制新备忘录然后播放它,无论我做什么,它都会始终使用前置摄像头旁边更安静的(phone 通话)扬声器。我需要它从更响亮的扬声器(如果可能的话,实际上是所有扬声器)播放。
注意:我是 运行 iOS 14.2.1,虽然我也尝试了其他设置,但我的 phone 设置为静音模式(通常)。我正在 iPhone 12 上进行测试。理想情况下,我并不是真的在寻找第 3 方 SDK 或库解决方案,因为我希望回放简单且本地完成。
这就是我在 viewModel 中设置 audioSession 的方式(从 viewController 初始化):
private func setupAudioSession() {
do {
let session = AVAudioSession.sharedInstance()
try session.setCategory(.playAndRecord, options: [.defaultToSpeaker, .allowBluetooth])
try session.setActive(true)
session.requestRecordPermission({ [weak self] allowed in
guard let self = self else { return }
if allowed == false {
self.settingsAlert?()
}
})
} catch {
debugPrint("error setting up AVAudioSession")
}
}
我是这样录音的:
func startRecording() {
guard let audioFileDir = getAudioFilePath(songId: songModel!.id) else { return }
let audioURLString = audioFileDir.absoluteString + ".m4a"
guard let audioURL = URL(string: audioURLString) else { return }
let recordingSettings: [String: Any] = [
AVFormatIDKey: Int(kAudioFormatLinearPCM),
AVLinearPCMIsNonInterleaved: false,
AVSampleRateKey: 44_100.0,
AVNumberOfChannelsKey: isStereoSupported ? 2 : 1,
AVLinearPCMBitDepthKey: 16
]
do {
audioRecorder = try AVAudioRecorder(url: audioURL, settings: recordingSettings)
audioUrl = audioURL
audioRecorder?.delegate = self
audioRecorder?.prepareToRecord()
audioRecorder?.record()
} catch {
audioRecorder = nil
debugPrint("Problem recording audio: \(error.localizedDescription)")
}
}
我什至包含了一些来自 WWDC 2020 的立体声录音代码,这就是 isStereoSupported 所做的。
这就是我播放的方式
do {
if let data = songDoc?.data?.audioData {
audioPlayer = try AVAudioPlayer(data: data)
} else if let url = audioUrl {
audioPlayer = try AVAudioPlayer(contentsOf: url)
}
audioPlayer?.delegate = self
audioPlayer?.play()
isPlaying = true
} catch {
audioPlayer = nil
debugPrint("playback error: \(error.localizedDescription)")
}
当然,我尝试添加如下内容:
try session.overrideOutputAudioPort(AVAudioSession.PortOverride.speaker)
以及每次播放或录制时设置 AVAudioSession。我已经尝试了很多其他类似的方法来解决这个问题,但似乎没有任何效果。
您应该将音频会话模式设置为 AVAudioSessionModeVideoRecording
并将会话类别选项设置为 AVAudioSessionCategoryOptionDefaultToSpeaker
[会话 setMode:AVAudioSessionModeVideoRecording 错误:&e]
我正在开发一款可以录制和播放录制音频的应用程序。我正在使用 AVAudioSession
将类别更改为 playAndRecord
并将其传递给 defaultToSpeaker
.
我的问题是,如果我启动该应用程序,播放较早的录音,它会按照我的意愿通过底部(声音更大的)扬声器播放,但如果我启动应用程序并开始录制新备忘录然后播放它,无论我做什么,它都会始终使用前置摄像头旁边更安静的(phone 通话)扬声器。我需要它从更响亮的扬声器(如果可能的话,实际上是所有扬声器)播放。
注意:我是 运行 iOS 14.2.1,虽然我也尝试了其他设置,但我的 phone 设置为静音模式(通常)。我正在 iPhone 12 上进行测试。理想情况下,我并不是真的在寻找第 3 方 SDK 或库解决方案,因为我希望回放简单且本地完成。
这就是我在 viewModel 中设置 audioSession 的方式(从 viewController 初始化):
private func setupAudioSession() {
do {
let session = AVAudioSession.sharedInstance()
try session.setCategory(.playAndRecord, options: [.defaultToSpeaker, .allowBluetooth])
try session.setActive(true)
session.requestRecordPermission({ [weak self] allowed in
guard let self = self else { return }
if allowed == false {
self.settingsAlert?()
}
})
} catch {
debugPrint("error setting up AVAudioSession")
}
}
我是这样录音的:
func startRecording() {
guard let audioFileDir = getAudioFilePath(songId: songModel!.id) else { return }
let audioURLString = audioFileDir.absoluteString + ".m4a"
guard let audioURL = URL(string: audioURLString) else { return }
let recordingSettings: [String: Any] = [
AVFormatIDKey: Int(kAudioFormatLinearPCM),
AVLinearPCMIsNonInterleaved: false,
AVSampleRateKey: 44_100.0,
AVNumberOfChannelsKey: isStereoSupported ? 2 : 1,
AVLinearPCMBitDepthKey: 16
]
do {
audioRecorder = try AVAudioRecorder(url: audioURL, settings: recordingSettings)
audioUrl = audioURL
audioRecorder?.delegate = self
audioRecorder?.prepareToRecord()
audioRecorder?.record()
} catch {
audioRecorder = nil
debugPrint("Problem recording audio: \(error.localizedDescription)")
}
}
我什至包含了一些来自 WWDC 2020 的立体声录音代码,这就是 isStereoSupported 所做的。
这就是我播放的方式
do {
if let data = songDoc?.data?.audioData {
audioPlayer = try AVAudioPlayer(data: data)
} else if let url = audioUrl {
audioPlayer = try AVAudioPlayer(contentsOf: url)
}
audioPlayer?.delegate = self
audioPlayer?.play()
isPlaying = true
} catch {
audioPlayer = nil
debugPrint("playback error: \(error.localizedDescription)")
}
当然,我尝试添加如下内容:
try session.overrideOutputAudioPort(AVAudioSession.PortOverride.speaker)
以及每次播放或录制时设置 AVAudioSession。我已经尝试了很多其他类似的方法来解决这个问题,但似乎没有任何效果。
您应该将音频会话模式设置为 AVAudioSessionModeVideoRecording 并将会话类别选项设置为 AVAudioSessionCategoryOptionDefaultToSpeaker
[会话 setMode:AVAudioSessionModeVideoRecording 错误:&e]