SwiftUI中实现录音与设备媒体音频同时播放的问题咨询
在SwiftUI iPad应用中实现录音与背景音频共存
我刚好处理过类似的需求——在录音时让设备上的背景音乐/视频音频继续播放,类似Snap的带音乐短视频录制场景。你用AVAudioSession.Category.playAndRecord配合.mixWithOthers的方向是对的,但在iOS 15.5上,还需要补充几个关键配置才能让它正常工作。
核心配置要点
完整的会话选项组合
除了.mixWithOthers,建议添加.defaultToSpeaker选项,确保录音时音频从扬声器输出(默认情况下playAndRecord会使用听筒,可能导致背景音频被压低或中断)。另外,激活会话时使用.notifyOthersOnDeactivation,能让你的应用结束录音后,其他音频会话自动恢复正常。正确的权限申请
别忘了在Info.plist中添加NSMicrophoneUsageDescription,否则录音权限会被拒绝,间接导致音频会话配置失效。
完整代码示例
下面是一个可直接使用的音频录音管理器类,配合SwiftUI视图实现功能:
import AVFoundation import SwiftUI class AudioRecorderManager: NSObject, ObservableObject { private var audioRecorder: AVAudioRecorder? /// 配置音频会话并激活 func setupAudioSession() { let session = AVAudioSession.sharedInstance() do { // 使用playAndRecord分类,搭配mixWithOthers和defaultToSpeaker选项 try session.setCategory(.playAndRecord, mode: .default, options: [.mixWithOthers, .defaultToSpeaker]) // 激活会话时通知其他音频应用 try session.setActive(true, options: .notifyOthersOnDeactivation) } catch { print("会话配置失败:\(error.localizedDescription)") } } /// 开始录音 func startRecording() { // 生成录音文件存储路径 let docsDir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] let audioURL = docsDir.appendingPathComponent("background_recording.m4a") // 录音设置(使用AAC编码,保证音质和兼容性) let recordingSettings: [String: Any] = [ AVFormatIDKey: Int(kAudioFormatMPEG4AAC), AVSampleRateKey: 44100.0, AVNumberOfChannelsKey: 1, AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue ] do { audioRecorder = try AVAudioRecorder(url: audioURL, settings: recordingSettings) audioRecorder?.record() print("开始录音,文件路径:\(audioURL.path)") } catch { print("启动录音失败:\(error.localizedDescription)") } } /// 停止录音 func stopRecording() { audioRecorder?.stop() audioRecorder = nil let session = AVAudioSession.sharedInstance() do { try session.setActive(false, options: .notifyOthersOnDeactivation) } catch { print("停用会话失败:\(error.localizedDescription)") } print("录音已停止") } } // SwiftUI视图示例 struct AudioRecordingView: View { @StateObject private var recorderManager = AudioRecorderManager() var body: some View { VStack(spacing: 20) { Button("开始录音(保留背景音频)") { recorderManager.setupAudioSession() recorderManager.startRecording() } .buttonStyle(.borderedProminent) Button("停止录音") { recorderManager.stopRecording() } .buttonStyle(.bordered) } .padding() .onAppear { // 提前申请录音权限 AVAudioSession.sharedInstance().requestRecordPermission { granted in if granted { print("录音权限已获取") } else { print("录音权限被拒绝,无法正常录音") } } } } }
额外优化建议
- 如果你的场景更偏向“视频录制+背景音频”,可以把会话模式改成
.videoRecording,这个模式是苹果专门为视频录制场景优化的,能更好地平衡录音和背景音频的播放效果:try session.setCategory(.playAndRecord, mode: .videoRecording, options: [.mixWithOthers, .defaultToSpeaker]) - 测试时先启动第三方音乐/视频应用播放音频,再打开你的应用点击录音按钮,验证背景音频是否继续播放。
内容的提问来源于stack exchange,提问作者Amélie Mouillac
相关产品推荐
相关产品推荐

