将AudioBufferList转换为CMSampleBuffer会产生意外的结果

我试图将我从一个audio单元获得的AudioBufferList转换成一个CMSampleBuffer ,我可以传入一个AVAssetWriter来保存麦克风的audio。 这种转换的工作原理在于,我正在进行转换的调用不会失败,但是录制最终会失败,并且我在日志中看到一些输出,这似乎是令人担忧的。

我正在使用的代码如下所示:

 - (void)handleAudioSamples:(AudioBufferList*)samples numSamples:(UInt32)numSamples hostTime:(UInt64)hostTime { // Create a CMSampleBufferRef from the list of samples, which we'll own AudioStreamBasicDescription monoStreamFormat; memset(&monoStreamFormat, 0, sizeof(monoStreamFormat)); monoStreamFormat.mSampleRate = 48000; monoStreamFormat.mFormatID = kAudioFormatLinearPCM; monoStreamFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked | kAudioFormatFlagIsNonInterleaved; monoStreamFormat.mBytesPerPacket = 2; monoStreamFormat.mFramesPerPacket = 1; monoStreamFormat.mBytesPerFrame = 2; monoStreamFormat.mChannelsPerFrame = 1; monoStreamFormat.mBitsPerChannel = 16; CMFormatDescriptionRef format = NULL; OSStatus status = CMAudioFormatDescriptionCreate(kCFAllocatorDefault, &monoStreamFormat, 0, NULL, 0, NULL, NULL, &format); if (status != noErr) { // really shouldn't happen return; } CMSampleTimingInfo timing = { CMTimeMake(1, 48000), kCMTimeZero, kCMTimeInvalid }; CMSampleBufferRef sampleBuffer = NULL; status = CMSampleBufferCreate(kCFAllocatorDefault, NULL, false, NULL, NULL, format, numSamples, 1, &timing, 0, NULL, &sampleBuffer); if (status != noErr) { // couldn't create the sample buffer PTKLogError(@"Failed to create sample buffer"); CFRelease(format); return; } // add the samples to the buffer status = CMSampleBufferSetDataBufferFromAudioBufferList(sampleBuffer, kCFAllocatorDefault, kCFAllocatorDefault, 0, samples); if (status != noErr) { PTKLogError(@"Failed to add samples to sample buffer"); CFRelease(sampleBuffer); CFRelease(format); return; } NSLog(@"Original sample buf size: %ld for %d samples from %d buffers, first buffer has size %d", CMSampleBufferGetTotalSampleSize(sampleBuffer), numSamples, samples->mNumberBuffers, samples->mBuffers[0].mDataByteSize); NSLog(@"Original sample buf has %ld samples", CMSampleBufferGetNumSamples(sampleBuffer)); 

正如我所提到的,代码似乎没有失败,本身,但AVAssetWriter不喜欢它,我创build的CMSampleBuffer似乎有0的大小,基于事实,下面的日志条目logging:

 2015-07-09 19:34:00.710 xxxx[1481:271334] Original sample buf size: 0 for 1024 samples from 1 buffers, first buffer has size 2048 2015-07-09 19:34:00.710 xxxx[1481:271334] Original sample buf has 1024 samples 

奇怪的是,样本缓冲区报告它有1024个样本,但大小为0.原始的AudioBufferList有2048个字节的数据,这是我所期望的1024个2字节的样本。

我在初始化和填充CMSampleBuffer的方式上做错了什么?

事实certificate,样本量回到0的事实是一个红色的鲱鱼。 一旦我清理了一些东西 – 特别是,我正确设置时间戳,如下所示:

 uint64_t timeNS = (uint64_t)(hostTime * _hostTimeToNSFactor); CMTime presentationTime = CMTimeMake(timeNS, 1000000000); CMSampleTimingInfo timing = { CMTimeMake(1, 48000), presentationTime, kCMTimeInvalid }; 

录音开始工作。

因此,如果有人被报告的0个采样缓冲区大小抛出,请注意,这是可以的,至less在您将数据传送到AVAssetWriter