使用 SDL 在 C++ 中播放在线音频流

问题描述 投票:0回答:1

我有一个向服务器发送请求的应用程序,服务器发回 MP3 或 PCM 格式的音频流。我想知道:实时播放此流的最有效方式是什么?理想情况下,我想播放此音频流,而不必先将其写入文件以减少延迟,并且我想在 SDL 中执行此操作。

我尝试寻找一些 SO 帖子,但大多数似乎只是简单地从预先存在的文件或类似文件中播放音频。我想应该有某种缓冲区,我可以简单地将音频帧添加到其中,但我不确定如何准确执行此操作。

c++ audio sdl
1个回答
0
投票

让我们从操作系统/应用程序级别开始。要播放音频流,操作系统通常需要以某个周期间隔向其提供解压缩的音频数据。

SDL 和 SDL_Mixer 将提供文档和 API,您可以在应用程序中使用它们来包装此过程。您只需正确初始化和设置 SDL 库,并在它请求数据时将数据复制到其 API 中。

我建议您首先使用基本的 WAV 文件在 SDL 程序中使用此部分。因此,请确保线程正确,打开 WAV,在需要时将文件中的数据 memcpy 到 SDL 的缓冲区中,等等。

现在,MP3 和其他类似格式(如 OGG 和 AAC)都是压缩音频格式。一般来说,你不能直接将它们复制到操作系统中来玩。他们需要先减压。 SDL 和 SDL_Mixer 可能会也可能不会为您执行某些操作。您需要查阅他们的文档。但是,从概念上讲,您需要确保应用程序和音频管道中的某个位置正确解压缩数据以便操作系统播放。

我建议您接下来使用本地 MP3 文件来处理此部分,该文件位于磁盘上应用程序可执行文件旁边。这与 WAV 文件类似,只是您可能需要先解压缩数据;或者确保 SDL 正在内部对其进行解压缩。

最后我们来谈谈流式音频数据。

理想情况下,我想播放此音频流而不必先将其写入文件以减少延迟,

您只考虑文件和磁盘延迟。流式传输时,您还会遇到网络延迟,这通常比磁盘延迟更严重。因此,为了解决这个问题,有一些文件格式充当音频数据本身的容器或包装器。 TS 和 FLV 就是几个例子。这些文件被设计为以单独的块的形式通过网络发送,并且能够应对网络中遇到的常见问题。

因此,为了将所有内容整合在一起,让我们将 RTSP 视为我们的网络音频示例。 RTSP 服务器将允许您向其发出请求并询问哪些流可用。然后,您将选择一个流,它将开始通过 RTP 协议将数据分块给您。我们假设里面有 TS 数据。您的应用程序将接收 RTP 协议并检索 TS。您将从 TS 文件中提取压缩的音频数据(即 MP3 或 AAC 等)。然后您将其解压并发送到操作系统来播放。

这或多或少是一个完整的音频流示例。还有其他格式和协议;就像 HLS 一样。

我强烈建议您不要自己编写这部分代码。这非常复杂。如果您无法从磁盘下载和播放完整的 MP3 和 WAV 文件,您应该寻找现成的流媒体解决方案,该解决方案创建一种可以与 MPV 等现有媒体播放器配对的格式。

© www.soinside.com 2019 - 2024. All rights reserved.