Django 中使用流响应处理视频的方法


Posted in Python onJuly 20, 2018

起步

利用 html5 的 <video> 标签可以播放:

<video width="320" height="240" controls>
 <source src="/static/video/demo.mp4" type="video/mp4">
 您的浏览器不支持Video标签。
</video>

但是这样的方式,视频中的进度条无法使用,而且以静态文件方式返回的话,后台的程序会占用大量的内存。

使用响应流的方式能很好的解决这两个问题。

StreamingHttpResponse

大多数 Django 响应使用 HttpResponse 。这意味着响应的主体内置在内存中,并以单件形式发送到 HTTP 客户端。而如果用 StreamingHttpResponse 的方式则可以以 chunks (部分块)的方式返回。一个很简单的例子就是:

from django.http import StreamingHttpResponse

def hello():
  yield 'Hello,'
  yield 'there!'

def test(request):
  return StreamingHttpResponse(hello)

根据 WSGI 协议中的,当服务器调用时,应用程序对象必须返回一个可迭代的,产生零个或多个字节串。因此我们可以通过给服务器提供生成器来完成流响应的功能。

常见的使用 StreamingHttpResponse 是一些大文件的下载等,利用它还能完成断点续传的功能。

视频流

使用视频流时可以从请求头部中获得起始字节数。

Django 中使用流响应处理视频的方法

这字段似乎是浏览器自动提供的,因为html代码中,我只需要改下视频的 src 的从静态地址变成路由方式而已。对于响应体而言,也要提供响应体返回的块的一个范围:

Django 中使用流响应处理视频的方法

Content-Range 分别表示了 起始字节号-终止字节号/文件总字节 ,该响应体的内容包含了文件该范围内的内容。处理视频流的代码如下:

import re
import os
from wsgiref.util import FileWrapper
from django.http import StreamingHttpResponse

def file_iterator(file_name, chunk_size=8192, offset=0, length=None):
  with open(file_name, "rb") as f:
    f.seek(offset, os.SEEK_SET)
    remaining = length
    while True:
      bytes_length = chunk_size if remaining is None else min(remaining, chunk_size)
      data = f.read(bytes_length)
      if not data:
        break
      if remaining:
        remaining -= len(data)
      yield data

def stream_video(request, path):
  """将视频文件以流媒体的方式响应"""
  range_header = request.META.get('HTTP_RANGE', '').strip()
  range_re = re.compile(r'bytes\s*=\s*(\d+)\s*-\s*(\d*)', re.I)
  range_match = range_re.match(range_header)
  size = os.path.getsize(path)
  content_type, encoding = mimetypes.guess_type(path)
  content_type = content_type or 'application/octet-stream'
  if range_match:
    first_byte, last_byte = range_match.groups()
    first_byte = int(first_byte) if first_byte else 0
    last_byte = first_byte + 1024 * 1024 * 8    # 8M 每片,响应体最大体积
    if last_byte >= size:
      last_byte = size - 1
    length = last_byte - first_byte + 1
    resp = StreamingHttpResponse(file_iterator(path, offset=first_byte, length=length), status=206, content_type=content_type)
    resp['Content-Length'] = str(length)
    resp['Content-Range'] = 'bytes %s-%s/%s' % (first_byte, last_byte, size)
  else:
    # 不是以视频流方式的获取时,以生成器方式返回整个文件,节省内存
    resp = StreamingHttpResponse(FileWrapper(open(path, 'rb')), content_type=content_type)
    resp['Content-Length'] = str(size)
  resp['Accept-Ranges'] = 'bytes'
  return resp

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
使用XML库的方式,实现RPC通信的方法(推荐)
Jun 14 Python
Python基于回溯法子集树模板实现图的遍历功能示例
Sep 05 Python
详解python string类型 bytes类型 bytearray类型
Dec 16 Python
python监控键盘输入实例代码
Feb 09 Python
CentOS下Python3的安装及创建虚拟环境的方法
Nov 28 Python
python读取各种文件数据方法解析
Dec 29 Python
正则给header的冒号两边参数添加单引号(Python请求用)
Aug 09 Python
详解python破解zip文件密码的方法
Jan 13 Python
tensorflow模型保存、加载之变量重命名实例
Jan 21 Python
Python实现列表索引批量删除的5种方法
Nov 16 Python
pandas求平均数和中位数的方法实例
Aug 04 Python
python神经网络学习 使用Keras进行回归运算
May 04 Python
Python实现手写一个类似django的web框架示例
Jul 20 #Python
python 实现求解字符串集的最长公共前缀方法
Jul 20 #Python
python实现求两个字符串的最长公共子串方法
Jul 20 #Python
Django基础知识与基本应用入门教程
Jul 20 #Python
opencv python 2D直方图的示例代码
Jul 20 #Python
Linux下python制作名片示例
Jul 20 #Python
Python爬虫的两套解析方法和四种爬虫实现过程
Jul 20 #Python
You might like
PHP中的array数组类型分析说明
2010/07/27 PHP
php更新mysql后获取影响的行数发生异常解决方法
2013/03/28 PHP
php结合ajax实现赞、顶、踩功能实例
2014/05/12 PHP
PHP高级编程实例:编写守护进程
2014/09/02 PHP
php图片处理函数获取类型及扩展名实例
2014/11/19 PHP
php中注册器模式类用法实例分析
2015/11/03 PHP
CodeIgniter集成smarty的方法详解
2016/05/26 PHP
PHP 将数组打乱 shuffle函数的用法及简单实例
2016/06/17 PHP
php使用str_replace替换多维数组的实现方法分析
2017/06/15 PHP
Firefox下提示illegal character并出现乱码的原因
2010/03/25 Javascript
javascript中String类的subString()方法和slice()方法
2011/05/24 Javascript
js下将字符串当函数执行的方法
2011/07/13 Javascript
用Node.js通过sitemap.xml批量抓取美女图片
2015/05/28 Javascript
jquery拖拽效果完整实例(附demo源码下载)
2016/01/14 Javascript
JavaScript+H5实现微信摇一摇功能
2018/05/23 Javascript
js实现下拉框二级联动
2018/12/04 Javascript
详解elementui之el-image-viewer(图片查看器)
2019/08/30 Javascript
[01:01]2020完美高校联赛(秋)西安落幕
2021/03/11 DOTA
python3.5仿微软计算器程序
2020/03/30 Python
python中for循环把字符串或者字典添加到列表的方法
2019/07/20 Python
CSS3 清除浮动的方法示例
2018/06/01 HTML / CSS
Css3实现无缝滚动防抖
2020/09/14 HTML / CSS
HTML5几个设计和修改的页面范例分享
2015/09/29 HTML / CSS
英国婚礼商城:Wedding Mall
2019/11/02 全球购物
卫校毕业生自我鉴定
2013/10/31 职场文书
亲子拓展活动方案
2014/02/20 职场文书
人事部经理岗位职责
2014/03/07 职场文书
校园歌咏比赛主持词
2014/03/18 职场文书
解除劳动合同协议书
2014/04/14 职场文书
安全生产专项整治方案
2014/05/06 职场文书
学校安全生产承诺书
2014/05/23 职场文书
关于护士节的演讲稿
2014/05/26 职场文书
企业文化理念标语
2014/06/10 职场文书
党员一帮一活动总结
2014/07/08 职场文书
软件项目经理岗位职责
2015/04/01 职场文书
数学备课组工作总结
2015/08/12 职场文书