I'm using AudioConverter
to convert uncompressed CMSampleBuffer
being captured via AVCaptureSession
to AudioBufferList
:
let status: OSStatus = AudioConverterFillComplexBuffer(
converter,
inputDataProc,
Unmanaged.passUnretained(self).toOpaque(),
&ioOutputDataPacketSize,
outOutputData.unsafeMutablePointer,
nil
)
My output asbd is set up as follows:
AudioStreamBasicDescription
- mSampleRate : 44100.0
- mFormatID : 1633772320
- mFormatFlags : 2
- mBytesPerPacket : 0
- mFramesPerPacket : 1024
- mBytesPerFrame : 0
- mChannelsPerFrame : 1
- mBitsPerChannel : 0
- mReserved : 0
I'd like to convert AudioBufferList
back to a CMSampleBuffer
containing compressed data so that I can then write it to an mp4 file using AVAssetWriter
(I have already figured out how to do it with video), but so far with little. I've tried consulting this answer but in that case there's PCM data and it doesn't seem to be usable here.
I have access to AudioBufferList
as well as the presentationTimeStamp of the original sample. I've tried the following but I'm not quite sure how to calculate numSamples and whether this approach makes any sense or not:
func createCMSampleBuffer(_ data: UnsafeMutableAudioBufferListPointer, presentationTimeStamp: CMTime) -> CMSampleBuffer? {
let numSamples = // not sure how to get this
var status: OSStatus = noErr
var sampleBuffer: CMSampleBuffer?
var timing: CMSampleTimingInfo = CMSampleTimingInfo(
duration: CMTime(value: CMTimeValue(numSamples), timescale: presentationTimeStamp.timescale),
presentationTimeStamp: presentationTimeStamp,
decodeTimeStamp: CMTime.invalid
)
status = CMSampleBufferCreate(
allocator: kCFAllocatorDefault,
dataBuffer: nil,
dataReady: false,
makeDataReadyCallback: nil,
refcon: nil,
formatDescription: formatDescription,
sampleCount: CMItemCount(numSamples),
sampleTimingEntryCount: 1,
sampleTimingArray: &timing,
sampleSizeEntryCount: 0,
sampleSizeArray: nil,
sampleBufferOut: &sampleBuffer
)
guard status == noErr else {
return nil
}
status = CMSampleBufferSetDataBufferFromAudioBufferList(
sampleBuffer!,
blockBufferAllocator: kCFAllocatorDefault,
blockBufferMemoryAllocator: kCFAllocatorDefault,
flags: 0,
bufferList: data.unsafePointer
)
guard status == noErr else {
return nil
}
return sampleBuffer
}
In the end I did manage to create a CMSampleBuffer
, but when I try finishing writing, I get the following error:
Error Domain=AVFoundationErrorDomain Code=-11800 "The operation could not be completed" UserInfo={NSUnderlyingError=0x174442ac0 {Error Domain=NSOSStatusErrorDomain Code=-12735 "(null)"}, NSLocalizedFailureReason=An unknown error occurred (-12735), NSLocalizedDescription=The operation could not be completed}
I can share some research work on this may it will help you ...
CMSampleBufferSetDataBufferFromAudioBufferList returned error: -12731
solution :- https://lists.apple.com/archives/coreaudio-api/2014/Mar/msg00008.html
or also Converting AudioBuffer to CMSampleBuffer with accurate CMTime
may it will help you ...:)