Fix cannotSetupAudioInputs when external USB audio device is connected before app launch#54
Open
mpogra wants to merge 1 commit into
Conversation
…t launch
When an external USB audio device (e.g. a microphone via Lightning or
USB-C adapter) is connected before the app launches, AVCaptureSession
initialises its audio subsystem in a degraded state. The resulting
CMSampleBuffer format description has no AudioChannelLayout and may
carry zero values for sample rate and channel count in its ASBD.
The original code unconditionally wrote:
audioSettings[AVChannelLayoutKey] = Data() // empty when layout absent
AVAssetWriter.canApply(outputSettings:forMediaType:audio) rejects an
explicitly empty Data value for AVChannelLayoutKey, so it returned false
and threw cannotSetupAudioInputs on every audio frame. The recording
failed completely with no output file written.
Fix (three-layer defence in appendAudioSampleBuffers):
1. Omit AVChannelLayoutKey entirely when layout data is absent.
Per AVAssetWriterInput docs, AVChannelLayoutKey is only required for
channel counts > 2; AVAssetWriter infers mono/stereo from
AVNumberOfChannelsKey when the key is absent.
2. Guard zero ASBD values — fall back to 44100 Hz / 1 ch when
mSampleRate or mChannelsPerFrame are zero (degraded state).
Valid non-zero values from a healthy format description are
used unchanged, so normal recording is unaffected.
3. Last-resort canApply retry with hardcoded 44100 Hz mono AAC
and nil format hint, ensuring recording never silently fails
from any remaining unacceptable values.
Tested with a USB microphone (Lightning adapter) plugged in both
before and after launch: video, photo, and boomerang sessions all
record successfully in both cases.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
When an external USB audio device (e.g. a microphone via Lightning or USB-C adapter) is connected before the app launches,
AVCaptureSessioninitialises its audio subsystem in a degraded state. TheCMSampleBufferformat description produced in this state has:AudioChannelLayout(CMAudioFormatDescriptionGetChannelLayoutreturnsnil)The original code always set:
AVAssetWriter.canApply(outputSettings:forMediaType:audio)rejects an explicitly emptyDatavalue forAVChannelLayoutKeyand returnsfalse, which throwscannotSetupAudioInputson every audio frame. The recording fails completely — no output file is written.Steps to reproduce
cannotSetupAudioInputsConnecting the microphone after launch works fine because
AVCaptureSessioninitialises audio normally in that case.Hardware reference
[photo of USB mic connected via Lightning adapter — showing the exact setup that triggers the degraded audio state]
Fix
Three-layer defence in
appendAudioSampleBuffers:1. Omit
AVChannelLayoutKeywhen layout data is absentPer AVAssetWriterInput docs,
AVChannelLayoutKeyis only required for channel counts > 2. For ≤2 channels,AVAssetWritercorrectly infers mono/stereo fromAVNumberOfChannelsKeywhen the key is absent.2. Guard zero ASBD values
Fall back to 44100 Hz / 1 ch when
mSampleRateormChannelsPerFrameare zero. Valid non-zero values from a healthy format description are used unchanged — normal recording is completely unaffected.3. Last-resort
canApplyretryIf the format-description-derived settings are still rejected, retry with hardcoded 44100 Hz mono AAC and
nilformat hint. This combination is unconditionally accepted byAVAssetWriterfor AAC output.Testing
Tested with a USB microphone (Lightning adapter) plugged in both before and after launch: