使用 AVAudioRecorder 录制后,AVAudioPlayer 不通过扬声器播放

Posted

技术标签:

【中文标题】使用 AVAudioRecorder 录制后,AVAudioPlayer 不通过扬声器播放【英文标题】:AVAudioPlayer NOT playing through speaker after recording with AVAudioRecorder 【发布时间】:2020-12-04 06:25:22 【问题描述】:

我正在开发一个应用程序,该应用程序可以进行音频录制和回放录制的音频。我正在使用AVAudiosession 将类别更改为playAndRecord,并将其传递给defaultToSpeaker

我的问题是,如果我启动应用程序,播放较早的录音,它会按照我的意愿通过底部(更响亮的)扬声器播放,但如果我启动应用程序并开始录音,它会按预期播放一个新的备忘录然后播放它,无论我做什么,它总是会使用前置摄像头旁边的更安静的(电话呼叫)扬声器。我需要它从更大的扬声器播放(如果可能的话,实际上是所有扬声器)。

注意:我运行的是 iOS 14.2.1,虽然我也尝试了其他设置,但我的手机(通常)设置为静音模式。我正在 iPhone 12 上进行测试。理想情况下,我并不是真的在寻找 3rd 方 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。我已经尝试了很多其他类似的方法来解决这个问题,但似乎没有任何效果。

【问题讨论】:

这能回答你的问题吗? How to get AVAudioPlayer output to the speaker 【参考方案1】:

您应该将音频会话模式设置为 AVAudioSessionModeVideoRecording 并将会话类别选项设置为 AVAudioSessionCategoryOptionDefaultToSpeaker

[会话设置模式:AVAudioSessionModeVideoRecording 错误:&e]

【讨论】:

是的!就是这样!非常感谢。我在 *** 或在线搜索中的任何地方都没有看到这个 AVAudioSessionModeVideoRecording。

以上是关于使用 AVAudioRecorder 录制后,AVAudioPlayer 不通过扬声器播放的主要内容,如果未能解决你的问题,请参考以下文章

使用 AVAudioRecorder 录制语音后的空文件

使用 AVAudioRecorder 录制后,AVAudioPlayer 不通过扬声器播放

AVAudioRecorder - 用户通过离开应用程序停止录制后继续录制到文件,然后重新打开它

AVAudioRecorder 设置录音开始时间

iPhone AVAudioRecorder,AudioQueueServices,检测到声音时如何自动录制音频

iOS音频与视频的开发- 使用AVAudioRecorder进行录制音频