iosavfoundationavassetwriter

AVAssetWriter audio settings failure with compression settings


I have the following audio compression settings which fail with AVAssetWriter (mov container, HEVC codec, kAudioFormatMPEG4AAC format ID):

["AVSampleRateKey": 48000,  "AVFormatIDKey": 1633772320, "AVNumberOfChannelsKey": 1, "AVEncoderBitRatePerChannelKey": 128000, "AVChannelLayoutKey": <02006500 00000000 00000000 00000000 00000000 00000000 00000000 00000000>]

Want to understand what is wrong? I can not reproduce it at my end (only reproducible on user's device with a particular microphone).

Here is the code line that fails:

 if _assetWriter?.canApply(outputSettings: audioSettings!, forMediaType: AVMediaType.audio) ?? false {

 } else {
     /* Failure */
 }

I need to know if it is mandatory to provide value for AVChannelLayoutKey in the dictionary with kAudioFormatMPEG4AAC? That could be a possible culprit.

Another set of settings that fail with lpcm codec for same hevc and mov is following:

   ["AVSampleRateKey": 48000, "AVChannelLayoutKey": <02006500 00000000 00000000 00000000 00000000 00000000 00000000 00000000>, "AVLinearPCMIsFloatKey": 0, "AVLinearPCMBitDepthKey": 16, "AVLinearPCMIsNonInterleaved": 0, "AVLinearPCMIsBigEndianKey": 0, "AVNumberOfChannelsKey": 0, "AVFormatIDKey": 1819304813]

EDIT: I fixed the issue by defining my own AudioChannelLayout as opposed to getting it from incoming CMSampleBuffers in the audio stream.

        var channelLayout = AudioChannelLayout()
        channelLayout.mChannelLayoutTag = kAudioChannelLayoutTag_MPEG_2_0
        
        let numChannels = 2 //Stereo Audio
        let currentChannelLayoutData = Data(bytes: &channelLayout, count: MemoryLayout.size(ofValue: channelLayout))

The code above seems to convert all kinds of audio streams to stereo. Not sure how mono to stereo (or 4 channel to stereo) works.


Solution

  • The AudioChannelLayout contains the tag kAudioChannelLayoutTag_Stereo (0x02006500 in little endian memory order), which disagrees with the AVNumberOfChannelsKey count of 1.

    Sounds like your user has a stereo microphone and you're expecting mono.

    The code above seems to convert all kinds of audio streams to stereo. Not sure how mono to stereo (or 4 channel to stereo) works.

    IIRC, in general, Apple audio channel conversion discards extra channels. AVAssetWriter might add zero samples if you don't provide enough channels. Try it and let us know!