3

我有一个可以实时生成视频的程序。现在我想在生成该视频时在线流式传输该视频。有人知道一个简单的方法吗?

我正在描述一种我尝试过但没有奏效的 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()
4

2 回答 2

2

什么类型的文件test2.mpg

如果它是一个mpeg4文件,您的方法将不起作用,因为您将在文件的开头或结尾有标题。如果您的文件是mpeg2传输流,那么这应该可以工作。

于 2011-03-09T23:09:21.957 回答
1

您可能遇到了文件结尾,因此您的循环失败了,无论是 EOFError 还是在某处崩溃。如果视频是实时生成的,除非 test2.mpg 是一个 FIFO 管道(使用 mkfifo 创建——在这种情况下,您一次只能有一个阅读器)——从管道读取可能不会返回任何数据,并且您的循环的运行速度可能比保存视频数据的速度快得多。所以你需要一个策略来处理 EOF。

此外,您需要确保刷新您的输出——在此程序中的 sys.stdout.write() 行之后以及其他程序中的视频流之后。由于您的循环没有结束条件也没有输出,并且您可能永远不会写入任何数据,因此可能是在循环的一次迭代之后,某些事情失败了,并且网络服务器丢弃了缓冲的数据。

此外,一次读取 1MB 的恒定大小可能会导致延迟问题。为了获得更好的延迟,最好使用较小的尺寸;但是,为了获得更好的质量和吞吐量,您可以使用更大的尺寸。但是,如果生成视频的程序、您的 cgi 脚本或网络服务器没有定期刷新,那么延迟点就没有实际意义。

我还建议研究“select”或“poll”/epoll——这些方法中的任何一种都可以让您更好地控制读取,并且可以通过休眠直到数据可用来帮助您解决文件结尾问题。如果您发现自己需要睡觉(0.5),最好正确使用 select/poll。

于 2011-03-08T04:33:37.807 回答