After looking at this question: AVAudioSession AVAudioSessionCategoryPlayAndRecord glitch, i tried to take a stab at trying to get video recording with background music playing working correctly. I'm settling for the audio glitch when recording starts, and when it ends, and it works fine the first time the recording happens. But if I try to record again, the music will stop.
Any ideas why?
Here's a snippet of my code:
captureSession = AVCaptureSession()
captureSession?.automaticallyConfiguresApplicationAudioSession = false
captureSession?.usesApplicationAudioSession = true
guard let captureSession = self.captureSession else {
print("Error making capture session")
return;
}
captureSession.sessionPreset = AVCaptureSessionPresetHigh
self.camera = self.defaultBackCamera()
self.audioDeviceInput = try? AVCaptureDeviceInput(device: getAudioDevice())
cameraInput = try AVCaptureDeviceInput(device: camera)
captureSession.beginConfiguration()
if captureSession.inputs.count > 0 {
return
}
if captureSession.canAddInput(cameraInput) {
captureSession.addInput(cameraInput)
if captureSession.outputs.count == 0 {
photoOutput = AVCapturePhotoOutput()
if captureSession.canAddOutput(photoOutput!) {
captureSession.addOutput(self.photoOutput!)
}
}
captureSession.commitConfiguration()
if !captureSession.isRunning {
captureSession.startRunning()
self.previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
self.previewLayer!.videoGravity = AVLayerVideoGravityResizeAspect
self.previewLayer!.connection.videoOrientation = .portrait
self.previewLayer!.frame = cameraView.layer.bounds
self.cameraView.layer.addSublayer(self.previewLayer!)
captureSession.beginConfiguration()
videoFileOut = AVCaptureMovieFileOutput()
if (captureSession.canAddOutput(videoFileOut)) {
captureSession.addOutput(videoFileOut)
if (videoFileOut?.connection(withMediaType: AVMediaTypeVideo).isVideoStabilizationSupported)! {
videoFileOut?.connection(withMediaType: AVMediaTypeVideo).preferredVideoStabilizationMode = .cinematic
}
}
captureSession.commitConfiguration()
}
This is the code to start recording:
let audioSession = AVAudioSession.sharedInstance()
try! audioSession.setCategory(AVAudioSessionCategoryPlayAndRecord,
with: [.mixWithOthers, .allowBluetoothA2DP, .allowAirPlay])
try! audioSession.setActive(true)
captureSession?.beginConfiguration()
if (captureSession?.canAddInput(audioDeviceInput!))! {
captureSession?.addInput(audioDeviceInput!)
}
captureSession?.commitConfiguration()
And to stop recording:
let audioSession = AVAudioSession.sharedInstance()
try! audioSession.setCategory(AVAudioSessionCategoryAmbient, with: [.mixWithOthers, .allowAirPlay])
captureSession?.beginConfiguration()
captureSession?.removeInput(audioDeviceInput)
captureSession?.commitConfiguration()
I'm working on a project where I have to do almost the same: record video with background audio playing. (in Xamarin)
In my code I do the AudioSession setup in the onViewLoad.
I also do audioSession.SetActive(false) before setting the catogory to PlayAndRecord. Maybe you should try this when starting/stopping the recording.
Benoit
It seems to me this has to do with your
AVAudioSession
. You do not set the audioSession to inactive when you are stopping the recording. This results in an immediate route change when you change theAVAudioSession
category when starting a new recording.Try setting the
AVAudioSession
inactive when stopping the recording.Also different
AVAudioSession
categories have different impact on AirPlay.Fetched from
https://developer.apple.com/documentation/avfoundation/avaudiosession/audio_session_categories
"The audio session category AVAudioSessionCategoryPlayAndRecord supports only the mirrored variant of AirPlay" and
"The audio session playback-only categories (AVAudioSessionCategoryAmbient, AVAudioSessionCategorySoloAmbient and AVAudioSessionCategoryPlayback) support both the mirrored and non-mirrored variants of AirPlay. "
I recommend a little reading on
AVAudioSession
in the Apple docs since just controlling theAVAudioSession
itself sometimes need to be really well thought-out.https://developer.apple.com/documentation/avfoundation/avaudiosession