如何在iOS中从服务器播放流式PCM数据?

如何在iOS中从服务器播放流式PCM数据?

问题描述:

我想开发应用程序什么播放从服务器流PCM数据。如何在iOS中从服务器播放流式PCM数据?

我已经使用AudioQueue,但它不能很好地工作。 (从服务器)

PCM数据格式:

Sample rate = 48000, num of channel = 2, Bit per sample = 16 

并且,服务器不流固定字节客户端。

(流式可变字节例:30848,128,2764,...字节)

我的源代码:

这里,ASBD结构是什么我已经设置好的&创建音频队列对象 (语言:SWIFT)

// Create ASBD structure & set properties. 
var streamFormat = AudioStreamBasicDescription() 

streamFormat.mSampleRate = 48000 
streamFormat.mFormatID = kAudioFormatLinearPCM 
streamFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked 
streamFormat.mFramesPerPacket = 1 
streamFormat.mChannelsPerFrame = 2 
streamFormat.mBitsPerChannel = 16 

streamFormat.mBytesPerFrame = (streamFormat.mBitsPerChannel/8) * streamFormat.mChannelsPerFrame 
streamFormat.mBytesPerPacket = streamFormat.mBytesPerFrame 
streamFormat.mReserved = 0 

// Create AudioQueue for playing PCM streaming data. 
var err = AudioQueueNewOutput(&streamFormat, self.queueCallbackProc, nil, nil, nil, 0, &aq) 

... 

我已经设置好的ASBD结构&创建AudioQueue对象像上面。

AudioQueue播放流PCM数据非常好几秒,

但很快播放声音开启和关闭。我能做什么?

(仍然流,并排队AudioQueue)

请给我任何的想法。

+0

低带宽格式的工作? –

+0

请原谅?我不知道你说的很好。 – user6081283

+0

当你尝试传输像mp3这样更紧凑的格式时它会工作吗? –

你需要做的(至少)两两件事:

您需要缓冲数据的处理时延抖动和从服务器之间的数据不同的数据包大小,以及音频队列回调请求数据。一个典型的解决方案是使用一个预先填充了一定数据量的循环FIFO /缓冲区,足以处理更糟糕的网络抖动(您需要统计分析这个数字)。音频队列回调可以将请求的数据量从循环FIFO中复制出来。网络代码试图保持填充。

您可能还需要一些方法来在两种比率不够相同时隐藏错误:例如,某种方式在网络速率太慢时复制或合成额外的声音,以及在网络速率过高时以某种方式排除样本,这两种方式都尽可能地听不到任何速率不连贯或不产生大声的点击,或者网络中断。

+0

第二部分仅适用于实时流。否则,客户端可以控制从服务器读取数据的速度,并使其适应播放速度。 – Codo

+0

即使是一个非实时流也会受到瞬时网络中断(拥塞,丢失的数据包太多等)的影响。 – hotpaw2

+0

我部分同意。如果你有缓存(而且这是必需的),只留下长时间的暂时网络丢失。您将无法用重复或合成的声音填充它们。但我同意需要以某种方式避免大声点击。 – Codo