I am trying to add multiple audio AVCaptureDeviceInputs to an AVCaptureSession (macOS).
My understanding is that AVCaptureConnections are automatically created between compatible inputs and outputs.
I can successfully add a single camera and audio device absolutely fine. My problem comes when adding a second audio device. I would like to overlay the audio from multiple sources.
Audio inputs are added as follows:
for device in newDevices {
do {
let newAudioDeviceInput = try AVCaptureDeviceInput(device: device)
if self.captureSession.canAddInput(newAudioDeviceInput) {
self.captureSession.addInput(newAudioDeviceInput)
self.audioDeviceInputs.append(newAudioDeviceInput)
}
} catch {
errors.append(error)
}
}
print(captureSession.inputs.count)
successfully shows the correct number of inputs
Output is added as follows:
let audioDataOutput = AVCaptureAudioDataOutput()
audioDataOutput.setSampleBufferDelegate(delegate, queue: queue)
if self.captureSession.canAddOutput(audioDataOutput) {
self.captureSession.addOutput(audioDataOutput)
self.audioDataOutput = audioDataOutput
} else {
throw Error.cannotAddOutput
}
A single AVCaptureConnection is created between the first input added and the output, but no subsequent inputs are added to the connection.
I'm really struggling to find any decent documentation on this, so any suggestions much appreciated. My expectation would be each additional AVCaptureDeviceInput would be added to the same connection inputs array.
CodePudding user response:
I thought multiple audio and video AVCaptureInput
s were unsupported, yet I couldn't find any documentation on that either.
A while ago this person cleverly managed to create multiple video inputs and outputs by using addOutputWithNoConnections()
, then manually creating the connections to the inputs (but why no addInputWithNoConnections()
?):
https://stackoverflow.com/a/30191013/22147
That could be worth trying with audio! Please report back with your results if you try this!
However I like to wrap the input devices in an aggregate audio device and then configure the AVCaptureSession
to use that. This gives you the convenience of working with a single "device" and you don't have to worry about multiple clocks and timestamps because both devices are synchronised.
You can create an aggregate audio device manually in Audio MIDI Setup.app
: https://stackoverflow.com/a/65704755/22147
or programmatically, using AudioHardwareCreateAggregateDevice()
:
https://stackoverflow.com/a/56415699/22147
If you use the programmatic route you can hide the resulting aggregate device by setting kAudioAggregateDeviceIsPrivateKey
to true
. You might want to do this to stop users messing with it.