Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 从连续数据流(iOS)播放音频_Iphone_Objective C_Ios_Core Audio_Audio Streaming - Fatal编程技术网

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)数据{
功能,“数据”包是音频包。我尝试使用AVPlayer、MFVideoPlayer进行流媒体播放,但迄今为止没有任何效果。还尝试查看mattgallagher的Audiostreamer,但仍然无法实现


这里的任何人都可以提供帮助,有一些(最好)工作示例吗?

小心:以下答案只有在从服务器接收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我很困惑如何制作音频缓冲区,我正在从这个方法获取数据,还有另一件事,如何调用回放调用?提前感谢大家的帮助!