我在使用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视频标记中的网址:
<video width="560" height="340" controls>
<source src='/video/mp4//tmp/test.mp4' type='video/mp4 codecs="avc1.42E01E, mp4a.40.2"'>
</video>
但是,当我打开包含视频的页面时,视频无法播放,Django开发服务器会发出以下错误:
Traceback (most recent call last): File "/usr/lib/pymodules/python2.6/django/core/servers/basehttp.py", line 280, in run self.finish_response() File "/usr/lib/pymodules/python2.6/django/core/servers/basehttp.py", line 320, in finish_response self.write(data) File "/usr/lib/pymodules/python2.6/django/core/servers/basehttp.py", line 416, in write self._write(data) File "/usr/lib/python2.6/socket.py", line 300, in write self.flush() File "/usr/lib/python2.6/socket.py", line 286, in flush self._sock.sendall(buffer) error: [Errno 104] Connection reset by peer [05/Dec/2010 13:08:00] "GET /video/mp4//tmp/test.mp4 HTTP/1.1" 200 384329753 Traceback (most recent call last): File "/usr/lib/pymodules/python2.6/django/core/servers/basehttp.py", line 280, in run self.finish_response() File "/usr/lib/pymodules/python2.6/django/core/servers/basehttp.py", line 320, in finish_response self.write(data) File "/usr/lib/pymodules/python2.6/django/core/servers/basehttp.py", line 416, in write self._write(data) File "/usr/lib/python2.6/socket.py", line 300, in write self.flush() File "/usr/lib/python2.6/socket.py", line 286, in flush self._sock.sendall(buffer) error: [Errno 104] Connection reset by peer Traceback (most recent call last): File "/usr/lib/pymodules/python2.6/django/core/servers/basehttp.py", line 280, in run self.finish_response() File "/usr/lib/pymodules/python2.6/django/core/servers/basehttp.py", line 320, in finish_response self.write(data) File "/usr/lib/pymodules/python2.6/django/core/servers/basehttp.py", line 416, in write self._write(data) File "/usr/lib/python2.6/socket.py", line 300, in write self.flush() File "/usr/lib/python2.6/socket.py", line 286, in flush self._sock.sendall(buffer) error: [Errno 32] Broken pipe
浏览器Google Chrome似乎尝试多次检索视频,前两次重置连接以及最后一次丢弃连接。请注意,Django会返回200 OK响应以及正确的视频大小。
以下是奇怪的部分:即使视频无法播放,我也可以右键点击播放器控件,选择将视频另存为... ,Google Chrome将很乐意下载整个视频和商店它在当地。然后,我仍然可以在Google Chrome中播放保存的视频,方法是使用file:// URL打开它。
我还尝试将视频文件放在本地网络服务器中并在视频标记中引用它,这也是有用的。
所以我认为这个问题与FileWrapper和/或Django使用迭代器处理HttpResponse的方式有关。数据在那里,它可以用保存视频... 保存,那为什么不播放?
谢谢!