我在使用 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... 保存,那为什么不能播放呢?
谢谢!