我試圖將我從音頻單元獲得的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函數什麼價值? –