我在使用 FileWrapper 类尝试使用 Django 流式传输 H.264 视频时遇到了一个奇怪的问题。我正在使用以下视图功能:
def mp4(request, path):
wrapper = FileWrapper(open(path, 'rb'))
content_type = mimetypes.guess_type(path)[0]
response = HttpResponse(wrapper, content_type=content_type)
response['Content-Length'] = os.path.getsize(path)
return response
该函数映射到此 URL:
(r'^/mp4/(.*)$', 'mp4'),
我在 HTML5 视频标签中引用 URL:
<video width="560" height="340" controls>
<source src='/video/mp4//tmp/test.mp4' type='video/mp4 codecs="avc1.42E01E, mp4a.40.2"'>
</video>
但是,当我打开包含视频的页面时,视频不播放并且 Django 开发服务器发出以下错误:
回溯(最近一次通话最后):
运行中的文件“/usr/lib/pymodules/python2.6/django/core/servers/basehttp.py”,第 280 行
self.finish_response()
文件“/usr/lib/pymodules/python2.6/django/core/servers/basehttp.py”,第 320 行,在 finish_response
self.write(数据)
文件“/usr/lib/pymodules/python2.6/django/core/servers/basehttp.py”,第 416 行,写入
self._write(数据)
文件“/usr/lib/python2.6/socket.py”,第 300 行,写入
self.flush()
文件“/usr/lib/python2.6/socket.py”,第 286 行,刷新
self._sock.sendall(缓冲区)
错误:[Errno 104] 对等方重置连接
[05/Dec/2010 13:08:00]“GET /video/mp4//tmp/test.mp4 HTTP/1.1”200 384329753
回溯(最近一次通话最后):
运行中的文件“/usr/lib/pymodules/python2.6/django/core/servers/basehttp.py”,第 280 行
self.finish_response()
文件“/usr/lib/pymodules/python2.6/django/core/servers/basehttp.py”,第 320 行,在 finish_response
self.write(数据)
文件“/usr/lib/pymodules/python2.6/django/core/servers/basehttp.py”,第 416 行,写入
self._write(数据)
文件“/usr/lib/python2.6/socket.py”,第 300 行,写入
self.flush()
文件“/usr/lib/python2.6/socket.py”,第 286 行,刷新
self._sock.sendall(缓冲区)
错误:[Errno 104] 对等方重置连接
回溯(最近一次通话最后):
运行中的文件“/usr/lib/pymodules/python2.6/django/core/servers/basehttp.py”,第 280 行
self.finish_response()
文件“/usr/lib/pymodules/python2.6/django/core/servers/basehttp.py”,第 320 行,在 finish_response
self.write(数据)
文件“/usr/lib/pymodules/python2.6/django/core/servers/basehttp.py”,第 416 行,写入
self._write(数据)
文件“/usr/lib/python2.6/socket.py”,第 300 行,写入
self.flush()
文件“/usr/lib/python2.6/socket.py”,第 286 行,刷新
self._sock.sendall(缓冲区)
错误:[Errno 32] 管道损坏
浏览器 Google Chrome 似乎多次尝试检索视频,前两次重置连接,最后一次断开连接。请注意,Django 返回 200 OK 响应以及正确的视频大小。
这是奇怪的部分:即使视频没有播放,我可以右键单击播放器控件,选择将视频另存为...,谷歌浏览器会愉快地下载整个视频并将其存储在本地。然后,我仍然可以在 Google Chrome 中通过使用 file:// URL 打开保存的视频来播放它。
我还尝试将视频文件放在本地 Web 服务器中并在视频标签中引用它,这也可以。
所以我认为这个问题与 FileWrapper 和/或 Django 使用迭代器处理 HttpResponse 的方式有关。数据在那里,可以用Save Video As... 保存,那为什么不能播放呢?
谢谢!