我应该使用哪种协议来传输音频(非直播)? [关闭]

2024-05-03

我正在尝试编写一个 Python 服务器,从头到尾传输一个请求的 mp3 文件。 (无直播)
我希望能够使用任何媒体播放器(如 VLC)播放该流并能够更改播放位置。

我听说过很多关于 HTTP Streaming 的内容,但在阅读了一些维基百科文章后,在我看来,“HTTP Streaming”只是不同流协议的总称,例如RTSP https://en.wikipedia.org/wiki/Real_Time_Streaming_Protocol/RTCP https://en.wikipedia.org/wiki/RTP_Control_Protocol/RTP https://en.wikipedia.org/wiki/Real-time_Transport_Protocol.

然后我遇到了喊话广播 https://en.wikipedia.org/wiki/Shoutcast这是使用自己的协议的流媒体专有软件(服务器!)。另一个现有的服务器程序似乎提供类似的功能是Icecast https://en.wikipedia.org/wiki/Icecast.
我不太确定 SHOUTcast 和 Icecast 之间的关系,但似乎有一种关系。

我认为流式传输一个特定的媒体文件与流式传输网络广播等连续流没有什么不同,所以我在谷歌上搜索了第一个网络广播并下载了 .pls 或 .m3u 文件。
两者基本上都是包含 url 的文本文件。所以我启动了wireshark并将VLC指向该url。
我看到的本质上是 HTTP 流量:

VLC:

GET /schizoid HTTP/1.1

VLC:

Host: <ip>:8000
User-Agent: VLC/2.0.5 LibVLC/2.0.5
Range: bytes=0-
Connection: close
Icy-MetaData: 1

服务器响应:

HTTP/1.0 200 OK
Content-Type: audio/mpeg
icy-br:128
ice-audio-info: bitrate=128
icy-br:128
icy-description:PsyTrance 24x7
icy-genre:psytrance
icy-name:Radio Schizoid
icy-pub:1
icy-url:http://schizoid.in:8000/schizoid
Server: Icecast 2.3.2
Cache-Control: no-cache
icy-metaint:16000

然后服务器开始发送原始数据,这似乎是 mp3 流。

根据维基百科 https://en.wikipedia.org/wiki/Shoutcast#History这就是 SHOUTcast 协议。
(我不确定这是否与 Icecast 使用的协议相同)

但我想到了一个封闭的(没有记录 http://www.smackfu.com/stuff/programming/shoutcast.html)协议不可能成为流媒体的标准。
所以我的问题是将流媒体(特定的 mp3 文件)集成到 python 服务器中的最佳(最简单和最好支持)方法是什么?
我是否必须手动实施 SHOUTcast 协议,还是使用 RTP 之类的协议?
(我不介意使用第三方库)


SHOUTcast 客户端协议实际上与 HTTP/1.0 相同。唯一相关的区别是响应状态行:

ICY 200 OK

代替HTTP/1.0, 你得到ICY。真的是这样!从那里开始,它的行为是一样的。 Web 浏览器和大多数 HTTP 客户端都会忽略这一点。 Android 和某些浏览器会卡住,但大多数都很好。 Icecast 的客户端流行为与 SHOUTcast 相同,只是它实际上返回HTTP/1.0 200 OK其状态行。

现在,您已经注意到在这些响应标头中,有一些带有流信息的额外标头。除一项外,所有其他信息都只是额外信息,不会对您返回的数据产生任何影响。如果您不请求任何元数据,那么服务器什么也不做,只是获取从源发送给它的每个字节,并将其中继到每个客户端(还有一些服务器端缓冲区)。

如果在您的请求标头中指定Icy-MetaData: 1,然后行为会略有变化。在响应中,您将得到Icy-MetaInt: 8192或类似的。这意味着每 8,192 字节就会有一个元数据块。有时那块只是0x00这意味着没有元数据更新。其他时候会有一个字节像0x01。如果将该值乘以 16,您就知道接下来的 16 个字节将是 ASCII 元数据,例如StreamTitle: 'My Stream';StreamUrl='';, 填充为0x00。我已经描述过另一篇文章中更详细地介绍了元数据 https://stackoverflow.com/a/4914538/362536,如果你好奇的话。

所有这一切都表明,最流行的流媒体协议实际上是 HTTP,并且 SHOUTcast/Icecast/许多其他服务器添加了请求标头,您可以在其中将元数据交织到流中。不请求元数据的 HTTP 客户端只会获得常规 MP3 流,浏览器会认为它只是某处的某个文件。毕竟,浏览器并不关心你如何获取数据。

现在,您应该使用什么?您的要求:

我正在尝试编写一个 Python 服务器,从头到尾传输一个请求的 mp3 文件。 (无直播)

HTTP 就是您所需要的。事实上,不需要为此编写一些服务器。 Apache/Nginx/任何东西都可以正常工作。只是一个简单的 HTTP 服务器!如果您想通过 ID 提供文件,那么您的 Python 就派上用场了。编写一些代码,根据该 ID 从磁盘中获取适当的资源。我不会为此烦恼 RTSP...这对于您所需要的来说开销太大,并且您会损害客户端兼容性。

我希望能够使用任何媒体播放器(如 VLC)播放该流并能够更改播放位置。

对于该要求,只需确保您的服务器支持范围请求 https://stackoverflow.com/a/8507991/362536。客户将负责剩下的事情。

总结一下这一切

  • SHOUTcast/Icecast 服务器用于“实时”广播式流,其中所有客户端(大致)同时获得相同的音频流
  • HTTP 是向客户端交付任何内容(无论是否是流式传输)的兼容性最好的协议
  • RTSP/RTMP/RTP 和所有相关协议都不是必需的,除非您正在流式传输长时间运行的流或实时流,其中基于客户端带宽可用性的可变比特率非常重要。 (这些协议还有其他功能,但这似乎是选择它们的决定因素。如果您想了解更多信息,我建议您阅读每个协议。)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

我应该使用哪种协议来传输音频(非直播)? [关闭] 的相关文章

随机推荐