如何在视频生成时在线流式传输以及失败的CGI方法
我有一个程序,可以实时生成视频。现在我想在生成视频的同时,把它在线直播。有没有人知道简单的方法可以做到这一点?
我尝试过一种CGI的方法,但没有成功。不过请注意,我对所有能实现我目标的选项都持开放态度。我只是想知道为什么我的方法不行,以及我该如何修正它。
我把内容类型设置为mpeg,然后定期输出mpeg文件的一部分数据。但是视频只持续了很短的时间就停止了直播。我的代码大概是这样的(用Python写的)。
print "Content-type: video/mpeg"
print
f = open("test2.mpg")
while (True):
st = f.read(1024*1024)
sys.stdout.write(st)
time.sleep(0.5)
虽然这样做应该没问题。我真的搞不懂这两个程序的输出为什么会不同。但显然我不能用这种方法,因为我不能等到整个文件生成完再开始读取。
print "Content-type: video/mpeg"
print
f = open("test2.mpg")
print f.read()
2 个回答
你可能遇到了文件结束的问题,这样你的循环就会失败,可能会出现EOFError错误,或者在某个地方崩溃。如果视频是实时生成的,除非test2.mpg是一个FIFO管道(通过mkfifo创建的,这种情况下你只能有一个读取者),否则从管道读取可能不会返回任何数据,而你的循环可能会运行得比视频数据保存得快得多。所以你需要一个处理文件结束的策略。
另外,你需要确保在程序中的sys.stdout.write()这一行之后,以及在另一个程序的视频流之后都要刷新输出。因为你的循环没有结束条件,也没有输出,可能永远不会写入任何数据,所以在循环的一次迭代后,如果出现了问题,web服务器可能会丢弃缓冲的数据。
此外,每次读取1MB的固定大小可能会导致延迟问题。为了更好的延迟,使用更小的大小是个好主意;但是为了更好的质量和吞吐量,你可以使用更大的大小。不过,如果生成视频的程序、你的cgi脚本或web服务器没有定期刷新,那么延迟的问题就不那么重要了。
我还建议你看看“select”或者“poll”/epoll——这两种方法能让你更好地控制读取,可能会帮助你解决文件结束的问题,通过让程序在数据可用时再继续运行。如果你发现自己需要sleep(0.5),那么正确使用select/poll可能会更好。
test2.mpg
是什么类型的文件?
如果它是一个mpeg4
文件,你的方法就不行了,因为文件的开头或结尾会有一些头信息。如果你的文件是mpeg2
传输流,那么这个方法应该可以用。