Iphone 从连续数据流(iOS)播放音频
整个上午我都在为这个问题绞尽脑汁 我已经设置了一个到数据源的连接,该数据源返回音频数据(它是一个录音设备,因此数据上没有设置长度。数据只是流进来。就像,如果你打开一个到收音机的流) 我已经成功地接收了代码中的所有数据包。现在我只需要玩它。我想播放即将到来的数据,所以我不想排队几分钟或其他任何事情,我想使用我在那一刻收到的数据并播放它 现在,我整个上午都在寻找不同的例子,但没有一个是真正摆出来的 在Iphone 从连续数据流(iOS)播放音频,iphone,objective-c,ios,core-audio,audio-streaming,Iphone,Objective C,Ios,Core Audio,Audio Streaming,整个上午我都在为这个问题绞尽脑汁 我已经设置了一个到数据源的连接,该数据源返回音频数据(它是一个录音设备,因此数据上没有设置长度。数据只是流进来。就像,如果你打开一个到收音机的流) 我已经成功地接收了代码中的所有数据包。现在我只需要玩它。我想播放即将到来的数据,所以我不想排队几分钟或其他任何事情,我想使用我在那一刻收到的数据并播放它 现在,我整个上午都在寻找不同的例子,但没有一个是真正摆出来的 在 (void)连接:(NSURLConnection)连接didReceiveData:(NSDa
- (void)连接:(NSURLConnection)连接didReceiveData:(NSData)数据{
这里的任何人都可以提供帮助,有一些(最好)工作示例吗?小心:以下答案只有在从服务器接收PCM数据时才有效。这当然不会发生。这就是为什么在呈现音频和接收数据之间需要另一个步骤:数据转换 根据格式的不同,这可能或多或少有点棘手,但一般来说,这一步您应该使用音频转换器服务 您应该使用
-(void)connection:(NSURLConnection)connection didReceiveData:(NSData)data
仅用来自服务器的数据填充缓冲区,播放它与此方法无关
现在,要使用缓冲区播放“存储”在内存中的数据,您需要使用RemoteIO和音频单元。您可以从教程中删除“录制”部分,因为您实际上并不需要它
如您所见,它们定义了用于播放的回调:
callbackStruct.inputProc = playbackCallback;
callbackStruct.inputProcRefCon = self;
status = AudioUnitSetProperty(audioUnit,
kAudioUnitProperty_SetRenderCallback,
kAudioUnitScope_Global,
kOutputBus,
&callbackStruct,
sizeof(callbackStruct));
和playbackCallback
函数如下所示:
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;
}
静态OSStatus播放回调(void*inRefCon,
AudioUnitRenderActionFlags*ioActionFlags,
常量音频时间戳*inTimeStamp,
UInt32 InBunsNumber,
UInt32数字帧,
音频缓冲列表*ioData){
对于(inti=0;imNumberBuffers;i++){
AudioBuffer=ioData->mBuffers[i];
无符号字符*frameBuffer=buffer.mData;
对于(int j=0;j
基本上,它所做的是用下一个需要播放的字节块填充ioData
缓冲区。如果没有新数据要播放,请确保将ioData
缓冲区归零(静音)(如果流缓冲区中没有足够的数据,播放器将静音)
此外,使用OpenAL,您还可以使用alSourceQueueBuffers
和alSourceUnqueueBuffers
依次对缓冲区进行排队
就这样。祝您编码愉快!cab您可以解释如何从nsinputstream读取的字节中播放ausiofunction@valentinRadu我很困惑如何制作音频缓冲区,我正在从这个方法获取数据,还有另一件事,如何调用回放调用?提前感谢大家的帮助!