// Convert AVAudioPCMBuffer to CMSampleBuffer import AVFoundation extension AVAudioPCMBuffer { func toCMSampleBuffer(presentationTime: CMTime) -> CMSampleBuffer? { var buffer: CMSampleBuffer? let duration = CMTimeMake(value: 1, timescale: Int32(format.sampleRate)) var timing = CMSampleTimingInfo(duration: duration, presentationTimeStamp: presentationTime, decodeTimeStamp: .invalid) guard CMSampleBufferCreate(allocator: kCFAllocatorDefault, dataBuffer: nil, dataReady: false, makeDataReadyCallback: nil, refcon: nil, formatDescription: format.formatDescription, sampleCount: CMItemCount(frameLength), sampleTimingEntryCount: 1, sampleTimingArray: &timing, sampleSizeEntryCount: 0, sampleSizeArray: nil, sampleBufferOut: &buffer) == noErr, let buffer = buffer, CMSampleBufferSetDataBufferFromAudioBufferList(buffer, blockBufferAllocator: kCFAllocatorDefault, blockBufferMemoryAllocator: kCFAllocatorDefault, flags: 0, bufferList: mutableAudioBufferList) == noErr else { return nil } return buffer } }