我正在寻找一个python片段来读取互联网广播流(.asx,.pls等)并将其保存到文件中。
最后的项目是cron'ed脚本,它将记录一两个小时的互联网广播,然后将其传输到我的手机上以便在我上下班时播放。 (3g在我上下班途中有点不稳定)
欢迎任何snippits或指针。
答案 0 :(得分:10)
以下使用请求库来处理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
中断它。
答案 1 :(得分:6)
所以经过修补和玩耍后,我发现Streamripper效果最好。这是我使用的命令
streamripper http://yp.shoutcast.com/sbin/tunein-station.pls?id=1377200 -d ./streams -l 10800 -a tb$FNAME
答案 2 :(得分:5)
如果您发现Python 3中的请求或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)
然后在打开URL之前将这些行放在主例程的开头。
ORIGINAL_HTTP_CLIENT_READ_STATUS = urllib.request.http.client.HTTPResponse._read_status
urllib.request.http.client.HTTPResponse._read_status = NiceToICY
它们将覆盖标准例程(仅此一次)并在打开流时运行NiceToICY函数代替正常状态检查。 NiceToICY替换无法识别的状态响应,然后复制“真实”_read_status函数所需的原始响应的相关位。最后调用原始函数,并将其中的值传递回调用者,其他所有内容都正常继续。
我发现这是解决导致错误的状态消息问题的最简单方法。希望它对你也有用。
答案 3 :(得分:2)
我知道这已经有一年了,但这仍然是一个可行的问题,我最近一直在摆弄。
大多数互联网电台都会为您提供下载类型选项,我选择MP3版本,然后从原始套接字读取信息并将其写入文件。诀窍在于确定下载与播放歌曲的速度有多快,以便您可以在读/写大小上创建平衡。这将在你的缓冲区def。
现在您拥有该文件,只需将其保留在您的驱动器(记录)上即可,但大多数玩家将从文件中删除已播放的块,并在流式传输停止时将文件从驱动器和ram中清除。
我使用了一些没有压缩应用程序的文件存档中的代码片段来处理大量的文件文件处理,播放,缓冲魔法。它与流程的流程非常相似。如果你写了一些sudo-code(我强烈推荐)你可以看到相似之处。
答案 4 :(得分:1)
我只熟悉shoutcast流的工作方式(这就是你提到的.pls文件):
您下载了pls文件,它只是一个播放列表。它的格式非常简单,因为它只是一个指向实际流的文本文件。
您可以连接到该流,因为它只是HTTP,可以流式传输MP3或AAC。为了您的使用,只需将您获得的每个字节保存到文件中,您就可以获得可以传输到MP3播放器的MP3或AAC文件。
Shoutcast有一个可选的附加功能:元数据。你可以找到它的工作原理here,但并不是真的需要。
如果你想要一个这样做的示例应用程序,请告诉我,稍后我会做些什么。