简体   繁体   English

python请求返回类似文件的对象以进行流式传输

[英]python requests return file-like object for streaming

I have created a requests object like this:我创建了一个这样的请求对象:

 obj.mp3 = requests.get('http://foo.com/bar.mp3', stream=True)

I thought that I could just feed this obj.mp3 object into any audio player that expects a file or an URI, obviously this idea is wrong: nothing played.我以为我可以将这个obj.mp3对象提供给任何需要文件或 URI 的音频播放器,显然这个想法是错误的:没有播放。 Below are the full code:下面是完整的代码:

#views.py

class ArticleDetailView(DetailView):
    model = Article
    template_name = 'song.html'

    def get_object(self):
        obj = super(ArticleDetailView, self).get_object()

        #code to store mp3 url in obj.mp3 and other stuff

        if obj.mp3:
            obj.mp3 = requests.get(obj.mp3, stream=True).content
        return obj

#song.html
<div class="audio">
  <audio src={{ article.mp3 }} type="audio/mpeg"> 
</div>

What is the correct way of treating return from requests as something that I can stream with a player?requests返回视为我可以与播放器一起播放的内容的正确方法是什么? I know at least I can write the obj.mp3 to a file, then just point the player to the file location, but I am trying to avoid write the file to disk.我知道至少我可以将obj.mp3写入文件,然后将播放器指向文件位置,但我试图避免将文件写入磁盘。

Thanks,谢谢,

There's an attribute Response.raw , which is already a file-like object.有一个属性Response.raw ,它已经是一个类似文件的对象。

resp = requests.get(url, stream=True)
resp.raw # is what you need

Using io.BytesIO(resp.content) is not preferable since behind the scenes you're reading the same amount of data twice (also memory-wise): accessing resp.content reads everything from the network stream, then io.BytesIO(resp.content) is allocating again the same amount of memory, and then you read it from BytesIO object.使用io.BytesIO(resp.content)不是可取的,因为在幕后您两次读取相同数量的数据(也是内存方面):访问resp.content从网络流中读取所有内容,然后io.BytesIO(resp.content)再次分配相同数量的内存,然后您从 BytesIO 对象中读取它。

Look into the io module for using file-like objects.查看io 模块以使用类文件对象。

Probably you could use io.BytesIO which you can initialize with the Response.content .可能您可以使用io.BytesIO ,您可以使用Response.content进行初始化。 Then instead of list of bytes you get a file-like object.然后你得到一个类似文件的对象而不是字节列表。

import io
resp = requests.get(url, stream=True)
obj.mp3 = io.BytesIO(resp.content)

Django's responsibility is to generate the HTML code that is then interpreted by the browser. Django 的职责是生成 HTML 代码,然后由浏览器解释。 The browser is what needs to be streaming the audio.浏览器需要流式传输音频。 You need to pass the mp3 url through Django templates that a player like http://www.jwplayer.com/ can then stream on the client side.您需要通过 Django 模板传递 mp3 url,然后像http://www.jwplayer.com/这样的播放器可以在客户端进行流式传输。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM