【问题标题】:iOS: Playing PCM buffers from a streamiOS:从流中播放 PCM 缓冲区
【发布时间】:2013-01-05 01:37:36
【问题描述】:

我正在从包含编码 PCM 缓冲区的套接字接收一系列 UDP 数据包。解码后,我留下了一个 int16 * 音频缓冲区,我想立即播放。

预期的逻辑是这样的:

init(){
   initTrack(track, output, channels, sample_rate, ...);
}

onReceiveBufferFromSocket(NSData data){
   //Decode the buffer
   int16 * buf = handle_data(data);

   //Play data
   write_to_track(track, buf, length_of_buf, etc);
}

不过,我不确定与播放缓冲区有关的所有内容。在Android上,我可以通过创建一个AudioTrack对象来实现这一点,通过指定采样率、格式、通道等来设置它......然后只需使用缓冲区调用“write”方法(就像我希望的那样我可以在上面的伪代码中)但在 iOS 上我做得不够。

我尝试使用音频文件流服务,但我猜我做错了,因为没有声音出现,而且我觉得这些功能本身实际上并没有进行任何播放。我还尝试了解音频队列服务(我认为它可能接近我想要的),但是我找不到任何简单的代码示例来使用它。

任何帮助将不胜感激,特别是示例代码的形式。

【问题讨论】:

  • 嘿,你解决了吗?我遇到了类似的问题,如果可能,请发布您的代码示例。

标签: ios audio pcm


【解决方案1】:

您也可以使用 audioQueue 服务,确保您进行某种数据包重新排序,如果您使用 ffmpeg 解码流,则有一个选项。

否则音频队列很容易设置。

https://github.com/mooncatventures-group/iFrameExtractor/blob/master/Classes/AudioController.m

您也可以使用 AudioUnits,不过要复杂一些。

【讨论】:

    【解决方案2】:

    您需要使用某种类型的缓冲区来保存传入的 UDP 数据。 This 是我用过的一个简单又好用的循环缓冲区。

    然后要从缓冲区播放数据,您可以使用音频单元框架。 Here 是一个很好的示例项目。

    注意:第一个链接还向您展示了如何使用音频单元进行播放。

    【讨论】:

    • 我仍然对如何做到这一点一无所知。我有一个来自 UDP 套接字的接收回调函数。我在那里获取 PCM 帧,所以你的意思是我应该有一个循环缓冲区,以便函数可以将它获取的帧放在那里,另一个回调(我不太确定如何制作)检查缓冲区并使用 audiounit 服务提交要播放的帧?但是什么叫第二个回调?我似乎无法决定何时播放音频,对吗?
    • 如果你看我的第一个链接中的例子,有一个函数叫做:audioOutputCallback。它向您展示了如何将数据从循环缓冲区复制到音频单元播放中。我刚刚复制了上面那个函数。
    • 请分享你的实现部分
    猜你喜欢
    • 2021-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-31
    • 2013-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多