# urls.py
from app01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^video/', views.video),
url(r'^test/', views.test),
]
#views.py
from django.shortcuts import render
from django.http import StreamingHttpResponse
def hello():
yield 'Hello,'
yield 'there!'
def test(request):
return StreamingHttpResponse(hello()) # 这里面传的是一个可迭代对象
import re
import os
import mimetypes
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): # path视频路径
"""将视频文件以流媒体的方式响应"""
range_header = request.META.get('HTTP_RANGE', '').strip()
range_re = re.compile(r'bytess*=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) # 根据由url给出的文件名或URL猜测文件的类型。返回值是一个元组(type, encoding)
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)
# print(111) 通过打印可以看到走的是视频流
else:
# 不是以视频流方式的获取时,以生成器方式返回整个文件,节省内存
resp = StreamingHttpResponse(FileWrapper(open(path, 'rb')), content_type=content_type)
resp['Content-Length'] = str(size)
# print(2222)
resp['Accept-Ranges'] = 'bytes'
return resp
def video(request):
return stream_video(request,r'D:deskpythonprojectday111 est_streammedia575ed05ec95db.mp4')
# 当浏览器请求大文件时,浏览器的请求头会有个Range字段,表示请求的起始字节到终止字节,我们就是通过request拿到这个数据,并通过这个数改变响应的字节流
# 在html页面中的video src地址不应再写静态文件的地址了,要写url地址,即向服务器发请求的地址
# 也可以使用这种方法传大文件,并且这样支持断点续传
# 处理视频流的代码后续最好单独写个文件,然后引用
# html页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="x-ua-compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Title</title>
</head>
<body>
<video width="320" height="240" controls>
<source src="http://127.0.0.1:8000/video/" type="video/mp4">
您的浏览器不支持Video标签。
</video>
</body>
</html>