17 April 2014

我在开发Android和iOS上的视频播放器。二者底层的解码和控制代码可以统一,但涉及音视频输出的部分在不同的系统上是有差别的。 对于视频输出,可以用同样的架构,即OpenGL;但对于音频输出,两个系统上的处理则完全不一样。

这里所要输出的音频是解码之后的PCM数据。

在Android系统上,可以调用AudioTrack类的write函数,以推的方式将PCM数据写入播放缓冲区。 Android内部维护的这个缓冲区如果满了,上面那个write函数会被阻塞。因为声音的播放按照固定采样率进行,所以多长时间对应多少数据是一定的(正常速度播放时)。 播放硬件按照固定速率消费数据,因此如果写的太快会被阻塞。

在iOS系统上,比如用AudioQueue这个类,声音数据是由系统向你索取的,而非你主动去写。用户实现一个回调函数,在其中提供音频数据。 当什么时候需要数据时,系统会调用这个函数。

相对于Android上的用户在“推”,iOS上是系统在“拉”。我觉得前者用起来方便,而且试图寻找iOS系统上“推”的方案,但没有找到。