在Python中录制和保存网络广播

12 投票
6 回答
19123 浏览
提问于 2025-04-16 07:27

我在找一个Python代码片段,用来读取网络广播流(比如.asx、.pls等格式),并把它保存到一个文件里。

我的最终项目是一个定时脚本,它会录制一到两个小时的网络广播,然后把录音传到我的手机上,这样我在通勤的时候就可以听了。(因为我通勤的地方3G信号有点不稳定)

任何代码片段或者建议都非常欢迎。

6 个回答

7

如果你发现用Python 3的requests或者urllib.request来请求数据时,返回的是“ICY 200 OK”而不是“HTTP/1.0 200 OK”,导致无法保存数据流,那你需要告诉程序,ICY 200 OK也是可以接受的!

简单来说,你可以在打开数据流后、处理头信息之前,拦截处理状态的程序。

你只需要在打开数据流的代码上面加上这样一段代码。

def NiceToICY(self):
    class InterceptedHTTPResponse():
        pass
    import io
    line = self.fp.readline().replace(b"ICY 200 OK\r\n", b"HTTP/1.0 200 OK\r\n")
    InterceptedSelf = InterceptedHTTPResponse()
    InterceptedSelf.fp = io.BufferedReader(io.BytesIO(line))
    InterceptedSelf.debuglevel = self.debuglevel
    InterceptedSelf._close_conn = self._close_conn
    return ORIGINAL_HTTP_CLIENT_READ_STATUS(InterceptedSelf)

然后把这些代码放在你的主程序开头,也就是在你打开网址之前。

ORIGINAL_HTTP_CLIENT_READ_STATUS = urllib.request.http.client.HTTPResponse._read_status
urllib.request.http.client.HTTPResponse._read_status = NiceToICY

这样做会临时替代标准的状态检查程序,运行NiceToICY函数来处理打开流时的状态。NiceToICY会处理这个不被识别的状态响应,然后把原始响应中需要的部分复制过来,最后再调用原来的状态检查程序,把得到的值传回去,其他的流程就照常进行。

我发现这是解决状态消息导致错误的最简单方法。希望对你也有帮助。

14

下面的代码是我用requests库来处理HTTP请求时有效的。

import requests

stream_url = 'http://your-stream-source.com/stream'

r = requests.get(stream_url, stream=True)

with open('stream.mp3', 'wb') as f:
    try:
        for block in r.iter_content(1024):
            f.write(block)
    except KeyboardInterrupt:
        pass

这段代码会把一个音频流保存到stream.mp3这个文件里,直到你按下ctrl+C来中断它。

7

经过一番尝试和玩耍,我发现Streamripper是最有效的工具。这是我使用的命令:

streamripper http://yp.shoutcast.com/sbin/tunein-station.pls?id=1377200 -d ./streams -l 10800 -a tb$FNAME

撰写回答