从连续的数据stream中播放audio(iOS)

整个上午一直对我的头反对这个问题。

我已经build立了一个数据源的连接,返回audio数据(这是一个录音设备,所以没有设置长度的数据,数据只是stream入。就像,如果你打开一个stream到收音机)

我已经设法接收我的代码中的所有数据包。 现在我只需要玩它。 我想播放正在进入的数据,所以我不想排队几分钟或任何事情,我想使用我在那个时刻收到的数据并播放它。

现在我整个上午都在寻找不同的例子,但是没有一个真的被排除在外。

在里面

  • (void)连接:(NSURLConnection )连接didReceiveData:(NSData )data {

function,“数据”包是audio包。 我尝试使用AVPlayer,MFVideoPlayer进行stream媒体播放,但到目前为止还没有任何效果。 也试着看着mattgallagher的Audiostreamer,但仍然无法实现它。

这里的任何人都可以帮忙,有一些(最好)工作的例子?

小心:如果您从服务器接收到PCM数据,下面的答案才有效。 这当然不会发生。 这就是为什么在渲染audio和接收数据之间你需要另一个步骤:数据转换。

取决于格式,这可能或多或less棘手,但一般来说,您应该使用audio转换服务这一步。

你应该使用-(void)connection:(NSURLConnection )connection didReceiveData:(NSData)data只填充来自服务器的数据的缓冲区,播放它应该与这个方法无关。

现在,要使用缓冲区播放“存储”在内存中的数据,您需要使用RemoteIO和audio单元。 这是一个很好的综合教程 。 您可以从教程中删除“logging”部分,因为您并不需要它。

正如你所看到的,他们定义了一个回放回放:

 callbackStruct.inputProc = playbackCallback; callbackStruct.inputProcRefCon = self; status = AudioUnitSetProperty(audioUnit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Global, kOutputBus, &callbackStruct, sizeof(callbackStruct)); 

playbackCallbackfunction如下所示:

 static OSStatus playbackCallback(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData) { for (int i = 0 ; i < ioData->mNumberBuffers; i++){ AudioBuffer buffer = ioData->mBuffers[i]; unsigned char *frameBuffer = buffer.mData; for (int j = 0; j < inNumberFrames*2; j++){ frameBuffer[j] = getNextPacket();//this here is a function you have to make to get the next chunk of bytes available in the stream buffer } } return noErr; } 

基本上它是用下一个需要播放的字节填充ioData缓冲区。 如果没有要播放的新数据,请确保将ioData缓冲区清零(静音)(如果stream缓冲区中没有足够的数据,播放器将保持沉默状态)。

另外,使用alSourceQueueBuffersalSourceUnqueueBuffers可以使用OpenAL来实现同样的function,以将缓冲区逐个排队。

而已。 快乐的编码!