我正在使用 Python 的 Twisted.web 构建一个视频流媒体,并回调 ffmpeg。
我想知道,因为我通过使用'return file.read()'发送文件,所以发送转码输出会出现问题,因为它不能被完整读取?我是不是想太多了,这一切都是由 Twisted.web 的低级管理代码管理的,还是我必须重新考虑我的方法?
此外,我如何支持人们跳到没有为他们缓冲的视频部分?我希望它会非常复杂,但只是以防万一。
谢谢
我正在使用 Python 的 Twisted.web 构建一个视频流媒体,并回调 ffmpeg。
我想知道,因为我通过使用'return file.read()'发送文件,所以发送转码输出会出现问题,因为它不能被完整读取?我是不是想太多了,这一切都是由 Twisted.web 的低级管理代码管理的,还是我必须重新考虑我的方法?
此外,我如何支持人们跳到没有为他们缓冲的视频部分?我希望它会非常复杂,但只是以防万一。
谢谢
1)我可以在扭曲中使用 file.read() 吗?
最简洁的答案是不”。
除非你做了一堆其他相对复杂的事情,比如在 fd 上设置 O_NONBLOCK,或者明确地将这个请求委托给单独的线程,否则file.read()
是一个阻塞调用,它将在文件返回之前将整个文件读入内存。
当这些数据从磁盘同步读取时,Twisted 的反应器将无法调用任何回调或读取或写入任何 fd 上的任何可用数据,导致任何其他挂起的请求或流传输在您的文件被读取时完全停止进入记忆。
此外,如果文件的源卷负载过重和/或有很多文件,即使是open()
获取文件对象的调用也可能会阻塞很长时间。没有非阻塞打开,所以如果你需要一个文件对象,你应该使用reactor.deferToThread()
扭曲的常规文件对象。
所以这是你应该做的:
要使用 twisted 直接从文件系统读取文件,您应该查看 twisted.web.server.Site 和 twisted.web.static.File。这里有一个关于它们的有趣教程。这些调用不仅会从磁盘流式传输文件内容,而且还会支持静态文件的附加 HTTP 功能,例如 HTTP Range 请求。
2) 我如何支持人们跳到没有为他们缓冲的视频部分?
这就是通常所说的擦洗,基本上有两种擦洗:HTML5 擦洗和基于时间的擦洗。
前者(HTML5 清理)只是“HTTP 范围请求”的一种花哨方式,并且受到原生浏览器和插件的支持,例如 Safari Mobile、Quicktime、mplayer 以及所有实现 html5 标签的浏览器。twisted.web.static.File
我在回答第一个问题时提到的 支持这一点。
后者(基于时间的清理)是支持清理的传统方式。它基本上是自定义播放器(例如 jwplayer 或 OSMF)和服务器之间的协议,允许播放器请求从某个查询参数指定的时间偏移开始的视频。
这可以通过在子进程中启动 ffmpeg 来完成,该-itsoffset
参数从所需的查询参数中提取,使用磁盘中的一些输入文件,或使用您最喜欢的 webserver 中的模块。无论哪种方式都需要玩家了解要发送的查询参数。