28

我想用 Python 实现一个服务器,通过 HTTP 流式传输 MP3 格式的音乐。我希望它可以广播音乐,以便客户端可以连接到流并开始收听当前正在播放的任何内容,就像广播电台一样。

以前,我使用 SocketServer.TCPServer 在 Python 中实现了我自己的 HTTP 服务器(是的,我知道 BaseHTTPServer 存在,只是想自己编写一个迷你 HTTP 堆栈),那么音乐流媒体在架构上会有什么不同呢?我需要在网络端和 MP3 端查看哪些库?

4

5 回答 5

40

mp3 格式专为流式传输而设计,这使得某些事情比您预期的要简单。数据本质上是带有内置边界标记的音频帧流,而不是文件头后跟原始数据。这意味着一旦客户端期望接收音频数据,您可以从现有 mp3 源中的任何点开始向其发送字节,无论是实时的还是文件,客户端将同步到它找到的下一帧和开始播放音频。耶!

当然,您必须为客户提供一种建立连接的方法。事实上的标准是 SHOUTcast (ICY) 协议。这与 HTTP 非常相似,但状态和标头字段的不同之处在于它与 Python 的内置 http 服务器库不直接兼容。您也许可以让这些库为您完成一些工作,但它们的文档化接口不足以完成它;您必须阅读他们的代码才能了解如何让他们说 SHOUTcast。

以下是一些帮助您入门的链接:

http://forums.winamp.com/showthread.php?threadid=70403

http://forums.radiotoolbox.com/viewtopic.php?t=74

http://www.smackfu.com/stuff/programming/shoutcast.html

http://en.wikipedia.org/wiki/Shoutcast

我建议从单个 mp3 文件开始作为数据源,让客户端-服务器连接设置和播放正常工作,然后继续处理实时源、多编码比特率、带内元数据和播放列表等问题。

播放列表通常是 .pls 或 .m3u 文件,本质上只是指向直播 URL 的静态文本文件。它们并不困难,甚至不是绝对必要的,因为许多(大多数?)mp3 流媒体客户端将接受根本没有播放列表的直播 URL。

至于建筑,这个领域非常开放。您有与 HTTP 服务器一样多的选项。螺纹?工作进程?事件驱动?由你决定。对我来说,更有趣的问题是如何与服务于多个输出流的网络处理程序(播放器)共享来自单个输入流(广播器)的数据。为了避免 IPC 和同步的复杂性,我可能会从单线程事件驱动设计开始。在 python 2 中,像gevent这样的库将为您提供非常好的 I/O 性能,同时允许您以非常易于理解的方式构建代码。在 python 3 中,我更喜欢 asyncio 协程。

于 2013-01-18T19:31:24.913 回答
1

由于您已经拥有良好的 python 经验(假设您已经编写了 HTTP 服务器),我只能提供一些关于如何扩展您已经完成的基础工作的建议:

  • 准备您的服务器以处理请求标头,例如:Accept-Encoding、、、等。 MP3-over-HTTP 播放器(即 VLC)只不过是一个知道如何“说出”HTTP 并“搜索”到文件中不同位置的 mp3 播放器.RangeTE (Transfer Encoding)

  • 在通过 HTTP 播放 mp3 时,使用 wireshark 或 tcpdump 来嗅探 VLC 完成的实际 HTTP 请求,这样您就知道您将如何接收并实现它们的请求标头。

祝你的项目好运!

于 2013-01-23T20:59:10.593 回答
0

您需要研究提供m3upls文件。这应该会为您提供一种玩家能够很好理解的文件格式,以便访问您的 http 服务器以查找 mp3 文件。

最小的 m3u 文件只是一个简单的文本文件,每行一个歌曲 url。假设您的服务器上有以下可用 URL:

/playlists/<playlist_name/playlist_id>
/songs/<song_name/song_id>

您将从 url 提供播放列表:

/playlists/myfirstplaylist

资源的内容就是:

/songs/1
/songs/mysong.mp3

播放器(如 Winamp)将能够在您的 HTTP 服务器上打开 m3u 文件的 URL,然后开始播放播放列表中的第一首歌曲。要支持这一点,您所要做的就是提供 mp3 文件,就像提供任何其他静态内容一样。

根据您想要支持的客户端数量,您可能希望使用Twisted之类的库来研究异步 IO ,以支持大量同步流。

于 2011-04-22T03:45:32.783 回答
0

在走得太远之前研究这些:

http://wiki.python.org/moin/PythonInMusic

具体来说

http://edna.sourceforge.net/

于 2011-04-28T22:47:37.503 回答
0

您将需要一个指向静态 URI 的 .m3u 或 .pls 文件(例如http://example.com/now_playing.mp3),然后在他们要求时从歌曲中的任何位置开始给他们 mp3 数据文件。可能有一堆小问题我在这里掩饰......但是,至少正如森林指出的那样,您可以开始从任何字节流式传输 mp3 数据。

于 2013-01-17T08:40:30.220 回答