我在这里遇到AVAssetReader的问题,从iPod库中获取样本并通过Audio Queue进行流式传输。我无法找到任何这样的例子,所以我尝试实现自己的,但似乎不知何故,AssetReader被“搞砸”在音频队列的回调函数中。具体来说,它在执行copyNextSampleBuffer时失败,即它还没有完成时返回null。我已经确定指针存在,所以如果有人可以提供帮助就会很棒。
下面是我使用过的回调函数代码。当AudioQueue回调未调用时,此回调函数“有效”。
static void HandleOutputBuffer (
void *playerStateH,
AudioQueueRef inAQ,
AudioQueueBufferRef inBuffer
) {
AQPlayerState *pplayerState = (AQPlayerState *) playerStateH;
//if (pplayerState->mIsRunning == 0) return;
UInt32 bytesToRead = pplayerState->bufferByteSize;
[[NSNotificationCenter defaultCenter] postNotificationName:NOTIF_callsample object:nil];
float * inData =(float *) inBuffer->mAudioData;
int offsetSample = 0;
//Loop until finish reading from the music data
while (bytesToRead) {
/*THIS IS THE PROBLEMATIC LINE*/
CMSampleBufferRef sampBuffer = [pplayerState->assetWrapper getNextSampleBuffer]; //the assetreader getting nextsample with copyNextSampleBuffer
if (sampBuffer == nil) {
NSLog(@"No more data to read from");
// NSLog(@"aro status after null %d",[pplayerState->ar status]);
AudioQueueStop (
pplayerState->mQueue,
false
);
pplayerState->mIsRunning = NO;
return;
}
AudioBufferList audioBufferList;
CMBlockBufferRef blockBuffer;
CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer(sampBuffer, NULL, &audioBufferList, sizeof(audioBufferList), NULL, NULL, 0, &blockBuffer);
AudioBuffer audioBuffer = audioBufferList.mBuffers[0];
memcpy(inData + (2*offsetSample),audioBuffer.mData,audioBuffer.mDataByteSize);
bytesToRead = bytesToRead - audioBuffer.mDataByteSize;
offsetSample = offsetSample + audioBuffer.mDataByteSize/8;
}
inBuffer->mAudioDataByteSize = offsetSample*8;
AudioQueueEnqueueBuffer (
pplayerState->mQueue,
inBuffer,
0,
0
);
}
答案 0 :(得分:2)
我遇到了同样神秘的错误。果然,“设置”音频会话使得错误消失了。这就是我设置音频会话的方式。
- (void)setupAudio {
[[AVAudioSession sharedInstance] setDelegate:self];
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:nil];
NSError *activationError = nil;
[[AVAudioSession sharedInstance] setActive: YES error:&activationError];
NSLog(@"setupAudio ACTIVATION ERROR IS %@", activationError);
[[AVAudioSession sharedInstance] setPreferredIOBufferDuration:0.1 error:&activationError];
NSLog(@"setupAudio BUFFER DURATION ERROR IS %@", activationError);
}
答案 1 :(得分:1)
来自音频会话编程指南,AVAudioSessionCategoryAmbient:
此类别允许在应用播放音频时播放来自iPod,Safari和其他内置应用程序的音频。
使用AVAssetReader可能使用iOS的硬件解码器,它会阻止使用AudioQueue。设置AVAudioSessionCategoryAmbient意味着音频以软件呈现,允许两者同时工作 - 但是,这会对性能/电池寿命产生影响。 (请参阅“类别如何影响编码和解码”下的Audio Session Programming Guide)。
答案 2 :(得分:0)
好的我已经以某种方式解决了这个奇怪的错误......显然这是因为音频会话没有正确设置。谈论缺乏这方面的文件...