I have created a Camera using AVFoundation which is able to record video and audio using AVCaptureVideoDataOutput
and AVCaptureAudioDataOutput
. I create my capture session, attach all inputs and the video- and audio-data outputs, and the Camera then sits idle. The user is now able to start a video recording.
The problem with this is that immediately after I start the capture session (captureSession.startRunning()
), the background music stutters. I assume this is because once the capture session starts running, the AVCaptureAudioDataOutput
internally activates the AVAudioSession (AVAudioSession.setActive(...)
), which I don't want it doing. I want it sitting idle (and not providing any audio output buffers) until I explicitly activate the Audio Session (once the user starts recording).
This is really annoying, since the Camera is the start-screen in our app and everytime the user opens or closes the app his music stutters.
I know that this is somehow possible because Snapchat works that way - you open the App and background audio smoothly continues to play. Once you start recording, there is a small stutter on the background music, but the Camera smoothly operates and starts recording once the short stutter is over.
My code:
func configureSession() {
captureSession.beginConfiguration()
// Video, Photo and Audio Inputs
...
// Video Output
...
// Audio Output
audioOutput = AVCaptureAudioDataOutput()
guard captureSession.canAddOutput(audioOutput!) else {
throw CameraError.parameter(.unsupportedOutput(outputDescriptor: "audio-output"))
}
audioOutput!.setSampleBufferDelegate(self, queue: audioQueue)
captureSession.addOutput(audioOutput!)
try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playAndRecord,
options: [.mixWithOthers,
.allowBluetoothA2DP,
.defaultToSpeaker,
.allowAirPlay])
captureSession.commitConfiguration()
}
AVAudioSession.sharedInstance()
I tried to first configure the AVAudioSession.sharedInstance
with the category AVAudioSession.Category.playback
, and switch to .playAndRecord
once I want to start recording audio.
This didn't work and the AVCaptureSessionRuntimeError
event gets invoked immediately after starting the Camera with the Error code -10851
, which means kAudioUnitErr_InvalidPropertyValue
. I think this means that the AVCaptureAudioDataOutput
is not allowed to record from the Audio Session, but I don't event want to do that right now - it should just be idle.
AVCaptureAudioDataOutput
outputI tried to not add the audio output (AVCaptureAudioDataOutput
) in the beginning, and only add it "on-demand" once the user starts recording, and while that worked fine for the background music (no stutter when starting, only short stutter once the user starts recording, exactly how I want it), it made the Preview freeze for a short amount of time (because the Capture Session is being reconfigured via beginConfiguration
+ audio output adding + commitConfiguration
)
Does anyone know how it's possible to achieve what I'm trying to do here - or how Snapchat does it? Any help appreciated, thanks!
Finally figured it out. I simply created a separate AVCaptureSession
specifically for the audio input/output which I synchronize with the main capture session's masterClock
. I can then start/stop the secondary capture session on the fly (shortly before start recording)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With