3

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

谢谢!

4

1 回答 1

0

对于那些在 2019 年(及以后)偶然发现这个问题的人,答案已发布在这里

于 2019-07-20T22:33:44.507 回答