我试图将我从音频单元获得的AudioBufferList
转换为CMSampleBuffer
,我可以将其传递到AVAssetWriter
以保存来自麦克风的音频。这种转换很有效,因为我为执行转换所做的调用不会失败,但录制最终会失败,而且我在日志中看到一些似乎引起关注的输出。将AudioBufferList转换为CMSampleBuffer产生意外结果
的代码我使用看起来像这样:
- (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
那我创建似乎基于这样的事实,被记录以下日志条目有大小为0,:
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
的方式做错了什么?
什么是_hostTimeToNSFactor?谢谢 –
@PabloMartinez我们通过调用'mach_timebase_info'和这个数学来计算它:'_hostTimeToNSFactor =(double)tinfo.numer/tinfo.denom'。 但是,可能有更好的方法:https://developer.apple.com/library/ios/qa/qa1643/_index.html –
感谢吉姆,你传递给hostTime函数什么价值? –