Django,使用FileWrapper(HTML5)流式传输H.264视频

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开发服务器会出现以下错误:
Traceback(最近的调用最先):
  File“/ usr / lib / pymodules / python2.6 / django / core / servers / basehttp.py”,第280行,在运行中
    self.finish_response()
  File“/ usr / lib / pymodules / python2.6 / django / core / servers / basehttp.py”,第320行,在完成响应时
    self.write(data)
  File“/ usr / lib / pymodules / python2.6 / django / core / servers / basehttp.py”,第416行,在写入时
    self._write(data)
  File“/ usr / lib / python2.6 / socket.py”,第300行,在写入时
    self.flush()
  File“/ usr / lib / python2.6 / socket.py”,第286行,在刷新时
    self._sock.sendall(buffer)
error:[Errno 104]由对等方重置连接
[05 / Dec / 2010 13:08:00] “GET / video / mp4 // tmp / test.mp4 HTTP / 1.1”200 384329753
Traceback(最近的调用最先): File“/ usr / lib / pymodules / python2.6 / django / core / servers / basehttp.py”,第280行,在运行中 self.finish_response() File“/ usr / lib / pymodules / python2.6 / django / core / servers / basehttp.py”,第320行,在完成响应时 self.write(data) File“/ usr / lib / pymodules / python2.6 / django / core / servers / basehttp.py”,第416行,在写入时 self._write(data) File“/ usr / lib / python2.6 / socket.py”,第300行,在写入时 self.flush() File“/ usr / lib / python2.6 / socket.py”,第286行,在刷新时 self._sock.sendall(buffer) error:[Errno 104]由对等方重置连接
Traceback(最近的调用最先): File“/ usr / lib / pymodules / python2.6 / django / core / servers / basehttp.py”,第280行,在运行中 self.finish_response() File“/ usr / lib / pymodules / python2.6 / django / core / servers / basehttp.py”,第320行,在完成响应时 self.write(data) File“/ usr / lib / pymodules / python2.6 / django / core / servers / basehttp.py”,第416行,在写入时 self._write(data) File“/ usr / lib / python2.6 / socket.py”,第300行,在写入时 self.flush() File“/ usr / lib / python2.6 / socket.py”,第286行,在刷新时 self._sock.sendall(buffer) error:[Errno 32]破管道
浏览器(Google Chrome)似乎尝试多次检索视频,前两次重置连接,最后一次断开连接。请注意,Django返回200 OK响应以及视频的正确大小。

这里有一个奇怪的问题:尽管视频不播放,但我可以右键单击播放器控件,选择 另存为... ,Google Chrome会愉快地下载整个视频并将其存储在本地。然后,我仍然可以在Google Chrome中通过使用 file:// URL 打开保存的视频来播放它。

我还尝试将视频文件放在本地Web服务器中,并在视频标签中引用它,这也起作用。

所以我认为问题与 FileWrapper 和/或 Django 处理带有迭代器的 HttpResponse 的方式有关。数据是存在的,可以使用 另存为... 保存,那么为什么不能播放呢?

谢谢!


可能与以下问题相关:http://stackoverflow.com/questions/4354649/how-to-use-content-type-video-mp2t-in-http-response - AndiDog
谢谢您的回复。我不认为问题是错误的MIME类型。我正在使用“video/mp4”,Google Chrome可以处理。检查HTTP流量,看起来问题可能是Google Chrome需要支持范围请求,然后才能通过HTTP进行流式传输。我可能会通过mod_xsendfile解决此问题,但仍希望找出上面的代码为什么会出错。 - Roger Dahl
抱歉重新提出一个旧问题,但你能解决这个问题吗? - hakura
1
@alper:问题在于Chrome需要使用HTTP字节范围进行视频流传输。我通过mod_xsendfile解决了这个问题。 - Roger Dahl
1个回答

0

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接