我尝试将我从音频单元获得的AudioBufferList
转换为CMSampleBuffer
,我可以将AVAssetWriter
转换为- (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
正如我所提到的,代码本身似乎没有失败,但是CMSampleBuffer
并不喜欢它,以及我创建的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
似乎是大小为0,基于以下日志条目被记录的事实:
CMSampleBuffer
奇怪的是,样本缓冲区报告它有1024个样本,但是大小为0.原始的AudioBufferList有2048个字节的数据,这是我对1024个2字节样本所期望的。
我在初始化和填充{{1}}的方式上做错了吗?
答案 0 :(得分:1)
事实证明,样本大小为0的事实是红鲱鱼。一旦我清理了一些东西 - 值得注意的是,我正确地设置了时间戳,如下所示:
uint64_t timeNS = (uint64_t)(hostTime * _hostTimeToNSFactor);
CMTime presentationTime = CMTimeMake(timeNS, 1000000000);
CMSampleTimingInfo timing = { CMTimeMake(1, 48000), presentationTime, kCMTimeInvalid };
记录开始工作了。
因此,如果其他人被报告的0样本缓冲区大小抛弃,请注意这是正常的,至少在您将数据输入AVAssetWriter
的情况下。