我想用Python实现一个服务器,通过HTTP传输MP3格式的音乐,我想让它广播音乐,这样客户机就可以连接到流,开始收听当前正在播放的音乐,就像一个广播电台一样。之前,我已经使用SocketServer.TCPServer在Python中实现了自己的HTTP服务器(是的,我知道BaseHTTPServer存在,只是想自己编写一个迷你HTTP堆栈),那么音乐流媒体在架构上会有什么不同呢?在网络端和MP3端,我需要查看哪些库?
imzjd6km1#
mp3格式是为流媒体设计的,这使得一些事情比你想象的要简单。数据本质上是一个带有内置边界标记的audio frames流,而不是一个文件头后面跟着原始数据。这意味着一旦客户端希望接收音频数据,你就可以从现有mp3源的任何一点开始发送它,无论是实时的还是文件的。客户端会同步到它找到的下一帧并开始播放音频。耶!当然,您必须为客户端提供一种建立连接的方法,事实上的标准是SHOUTcast(ICY)协议,这非常类似于HTTP,但是状态和头字段不同,不能直接与Python内置的http服务器库兼容,你可以让这些库为你做一些工作。但是他们有文档记录的接口不足以完成它;你必须阅读他们的代码来理解如何让他们说SHOUTcast。以下是一些帮助您入门的链接:https://web.archive.org/web/20220912105447/http://forums.winamp.com/showthread.php?threadid=70403https://web.archive.org/web/20170714033851/https://www.radiotoolbox.com/community/forums/viewtopic.php?t=74https://web.archive.org/web/20190214132820/http://www.smackfu.com/stuff/programming/shoutcast.htmlhttp://en.wikipedia.org/wiki/Shoutcast我建议从一个mp3文件开始作为您的数据源,设置客户机-服务器连接并进行播放,然后继续讨论实时源、多编码比特率、带内元数据和播放列表等问题。播放列表通常是.pls或.m3u文件,本质上只是指向直播流URL的静态文本文件。它们并不困难,甚至不是绝对必要的,因为许多(大多数?)mp3流媒体客户端会接受一个没有播放列表的直播流URL。至于体系结构,这个领域是非常开放的。HTTP服务器有很多选择。线程化?工作进程?事件驱动?这取决于你。对我来说,更有趣的问题是如何共享来自单个输入流的数据(广播公司),其中网络处理程序服务于多个输出流为了避免IPC和同步复杂化,我可能会从单线程事件驱动设计开始,在python 2中,像gevent这样的库可以给予very good I/O performance,同时允许你以一种非常容易理解的方式来构造你的代码。2在python3中,我更喜欢异步协程。
z4bn682m2#
由于您已经有了很好的python经验(假设您已经编写了一个HTTP服务器),我只能提供一些关于如何扩展您已经完成的基础工作的建议:
Accept-Encoding
Range
TE (Transfer Encoding)
祝你的项目好运!
yws3nbqq3#
你可能会想试试m3u或pls文件,这样你就能给予一个文件格式,玩家们可以很好地理解它,从而在http服务器上找到mp3文件。一个最小的m3u文件就是一个简单的文本文件,每行一个歌曲网址,假设你的服务器上有以下网址:
/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,以支持大量的并发流。
shstlldc4#
在走得太远之前先研究一下这些:http://wiki.python.org/moin/PythonInMusic具体而言http://edna.sourceforge.net/
bfnvny8b5#
你会希望有一个.m3u或.pls文件指向一个静态URI(例如http://example.com/now_playing.mp3),然后当他们要求这个文件时,给予他们从你在歌曲中的任何位置开始的mp3数据。可能有一堆小问题我在这里掩盖了...然而,至少正如forest指出的,你可以从任何字节开始流传输mp3数据。
5条答案
按热度按时间imzjd6km1#
mp3格式是为流媒体设计的,这使得一些事情比你想象的要简单。数据本质上是一个带有内置边界标记的audio frames流,而不是一个文件头后面跟着原始数据。这意味着一旦客户端希望接收音频数据,你就可以从现有mp3源的任何一点开始发送它,无论是实时的还是文件的。客户端会同步到它找到的下一帧并开始播放音频。耶!
当然,您必须为客户端提供一种建立连接的方法,事实上的标准是SHOUTcast(ICY)协议,这非常类似于HTTP,但是状态和头字段不同,不能直接与Python内置的http服务器库兼容,你可以让这些库为你做一些工作。但是他们有文档记录的接口不足以完成它;你必须阅读他们的代码来理解如何让他们说SHOUTcast。
以下是一些帮助您入门的链接:
https://web.archive.org/web/20220912105447/http://forums.winamp.com/showthread.php?threadid=70403
https://web.archive.org/web/20170714033851/https://www.radiotoolbox.com/community/forums/viewtopic.php?t=74
https://web.archive.org/web/20190214132820/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这样的库可以给予very good I/O performance,同时允许你以一种非常容易理解的方式来构造你的代码。2在python3中,我更喜欢异步协程。
z4bn682m2#
由于您已经有了很好的python经验(假设您已经编写了一个HTTP服务器),我只能提供一些关于如何扩展您已经完成的基础工作的建议:
Accept-Encoding
、Range
、TE (Transfer Encoding)
等。MP3 over-HTTP播放器(即VLC)只不过是一个知道如何“说”HTTP和“寻找”文件中不同位置的MP3播放器。祝你的项目好运!
yws3nbqq3#
你可能会想试试m3u或pls文件,这样你就能给予一个文件格式,玩家们可以很好地理解它,从而在http服务器上找到mp3文件。
一个最小的m3u文件就是一个简单的文本文件,每行一个歌曲网址,假设你的服务器上有以下网址:
您可以从以下URL提供播放列表:
资源的内容将是:
播放器(如Winamp)将能够打开HTTP服务器上的m3u文件的URL,然后开始播放播放列表中的第一首歌曲。您所要做的就是像播放其他静态内容一样播放mp3文件。
根据您希望支持的客户机数量,您可能希望使用像Twisted这样的库来研究异步IO,以支持大量的并发流。
shstlldc4#
在走得太远之前先研究一下这些:
http://wiki.python.org/moin/PythonInMusic
具体而言
http://edna.sourceforge.net/
bfnvny8b5#
你会希望有一个.m3u或.pls文件指向一个静态URI(例如http://example.com/now_playing.mp3),然后当他们要求这个文件时,给予他们从你在歌曲中的任何位置开始的mp3数据。可能有一堆小问题我在这里掩盖了...然而,至少正如forest指出的,你可以从任何字节开始流传输mp3数据。