如何在 C/C++ 中获取用于流式传输的 mp3 音频数据包

Posted

技术标签:

【中文标题】如何在 C/C++ 中获取用于流式传输的 mp3 音频数据包【英文标题】:How to obtain mp3 audio packets for streaming in C/C++ 【发布时间】:2014-11-24 19:11:29 【问题描述】:

我希望能够将歌曲分成数据包并访问这些单独的数据包。 原因是我想使用名为命名数据网络的实验性网络协议通过网络发送每个单独的数据包。

当数据包到达目的地时,我想播放它们。所以我想实现一个流功能。唯一的区别是我将使用的网络层。此网络层不基于 IP。

有谁知道任何将歌曲文件分解成片段然后单独播放这些数据包的 C/C++ 实现?我查看了 Gstreamer,但从其管道结构中获取单个数据包似乎很复杂。 我发现这个参考最接近我想要的,但对我来说不是很清楚:how can I parse audio raw data recorder with gstreamer?

总结一下我需要的几点:

    将歌曲分成数据包 播放单个数据包(或一小组数据包)的音频内容。

非常感谢您的帮助!

【问题讨论】:

MP3 是一种流媒体格式,因此您或多或少可以将其切碎,它仍然可以播放或多或少没问题。 流格式仍然由块组成。在 MP3 的情况下,这些被称为帧并且不一定是独立的 - 一个帧可能会引用来自几个先前帧的数据(搜索“位储存器”)。如果解码器支持这一点并执行某种缓冲,简单地将 MP3 切成随机数据块可能会起作用。然而,这远不能保证。例如,Web Audio API 的 decodeAudioData 很难处理这些。见***.com/questions/10470742/… 【参考方案1】:

MP3 文件只是一个succession of MP3 frames。每一帧由一个头和一个数据块组成。

将 MP3 文件拆分为 MP3 帧将涉及解析 MP3 文件。可以参考to this documentation for a good description of the format。

请注意,对于 mpeg 第 3 层编解码器,帧不是独立的。 In the worst case, 9 input frames may be needed before beeing able to decode one single frame.

我会做什么来代替这个

我想您可能会忽略大部分这些细节,而专注于流媒体问题本身。这是我首先要尝试构建的内容:

在发送方,将文件拆分为数据包,然后使用您的系统一一发送。命令示例:send_stream test.mp3

在接收方,接收数据包并重建原始文件。命令示例:receive_stream test.mp3

一旦你有这个工作正常,修改接收程序,以便它在标准输出上按顺序写入数据包。这将允许您将标准输出重定向到文件

# sender side did not change
send_stream test.mp3

# receiver side
receive_stream > test.mp3

然后,您可以使用madplay 播放 mp3在接收时,只需将receive_stream 输出重定向到 madplay:

# madplay - tells madplay to read its input from standard input.
receive_stream | madplay -

对于一个好的 mp3 解码器,take a look at MAD。

【讨论】:

以上是关于如何在 C/C++ 中获取用于流式传输的 mp3 音频数据包的主要内容,如果未能解决你的问题,请参考以下文章

iOS 上的 MP3 流式传输

如何以 mp3 格式从麦克风流式传输声音?

如何从 ASP.NET MVC 控制器操作流式传输 MP3

Spring-MVC:如何从控制器流式传输 mp3 文件

用于从 iphone 麦克风流式传输音频的多点连接

如何使用 node.js 和 socket.io 通过 WebSockets 流式传输 MP3 数据?