Eri*_*sen 16 iphone cocoa-touch objective-c avfoundation
你如何通过AVAssetReader读取音频样本?我找到了使用AVAssetReader进行复制或混合的示例,但这些循环始终由AVAssetWriter循环控制.是否可以创建一个AVAssetReader并读取它,获取每个样本并将每个音频样本的int32抛入一个数组?
谢谢.
Rog*_*ger 26
要扩展@ amrox的答案,您可以从CMBlockBufferRef获取AudioBufferList,例如
CMItemCount numSamplesInBuffer = CMSampleBufferGetNumSamples(buffer);
AudioBufferList audioBufferList;
CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer(
buffer,
NULL,
&audioBufferList,
sizeof(audioBufferList),
NULL,
NULL,
kCMSampleBufferFlag_AudioBufferList_Assure16ByteAlignment,
&buffer
);
for (int bufferCount=0; bufferCount < audioBufferList.mNumberBuffers; bufferCount++) {
SInt16* samples = (SInt16 *)audioBufferList.mBuffers[bufferCount].mData;
for (int i=0; i < numSamplesInBuffer; i++) {
// amplitude for the sample is samples[i], assuming you have linear pcm to start with
}
}
//Release the buffer when done with the samples
//(retained by CMSampleBufferGetAudioBufferListWithRetainedblockBuffer)
CFRelease(buffer);
Run Code Online (Sandbox Code Playgroud)
amr*_*rox 18
AVAssetReader *reader = [[AVAssetReader alloc] initWithAsset:asset error:&error];
AVAssetTrack *track = [[asset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];
NSDictionary *settings = @{ AVFormatIDKey : [NSNumber numberWithInt:kAudioFormatLinearPCM] };
AVAssetReaderTrackOutput *readerOutput = [AVAssetReaderTrackOutput assetReaderTrackOutputWithTrack:track
outputSettings:settings];
[reader addOutput:readerOutput];
[reader startReading];
CMSampleBufferRef sample = [readerOutput copyNextSampleBuffer];
while ( sample )
{
sample = [readerOutput copyNextSampleBuffer];
if ( ! sample )
{
continue;
}
CMBlockBufferRef buffer = CMSampleBufferGetDataBuffer(sample);
size_t lengthAtOffset;
size_t totalLength;
char *data;
if ( CMBlockBufferGetDataPointer( buffer, 0, &lengthAtOffset, &totalLength, &data ) != noErr )
{
NSLog(@"error!");
break;
}
// do something with data...
CFRelease(sample);
}
Run Code Online (Sandbox Code Playgroud)
这里的答案不是通用的.CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer
当AudioBufferList
需要以不同的方式调整大小时,调用可能会失败.以非交错样本为例.
正确的方法是CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer
两次打电话.第一个调用查询所需的大小AudioBufferList
,第二个调用实际填充AudioBufferList
.
size_t bufferSize = 0;
CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer(
sampleBuffer,
&bufferSize,
NULL,
0,
NULL,
NULL,
0,
NULL
);
AudioBufferList *bufferList = malloc(bufferSize);
CMBlockBufferRef blockBuffer = NULL;
CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer(
sampleBuffer,
NULL,
bufferList,
bufferSize,
NULL,
NULL,
kCMSampleBufferFlag_AudioBufferList_Assure16ByteAlignment,
&blockBuffer
);
// handle audio here
free(bufferList);
CFRelease(blockBuffer);
Run Code Online (Sandbox Code Playgroud)
在一个现实世界的例子中,你必须执行错误处理,你也不应该每帧都有malloc,而是缓存AudioBufferList
.
归档时间: |
|
查看次数: |
18176 次 |
最近记录: |