通过HTTP将视频从Perl发送到客户端

时间:2013-01-26 19:51:40

标签: perl video-streaming html5-video audio-streaming

我目前正在制作一个perl脚本,将文件转换为webm / ogg / mp4格式,然后将其发送回用户,但是嵌入视频。这一切都有效,除了我不能发送EOF所以HTML5视频播放器知道结果是什么,因此他可以正确使用该文件(比如去特定时间,甚至知道文件何时结束(现在它只是停止但是你不能再用视频做任何事了。

启动代码:

elsif ($path =~ /^\/((\w|\d){11})\.webm$/ig) {
    print "HTTP/1.0 200 OK\r\n";
    $handler = \&resp_youtubemovie;
    $handler->($cgi,$1);

发送webm文件的功能

sub resp_youtubemovie {
    my $cgi = shift;
    my $youtubeID = shift;
    return if !ref $cgi;
    open(movie,"<$youtubeID.webm");
    local($/);
    $movie = <movie>;
    close(movie);
    print "Content-type: movie/webm\n";
    print $movie;
}

我已经尝试过使用while循环和缓冲区,但这也不起作用,我也尝试将HTTP状态代码更改为206 Partial Content,因为我还使用了其他一些视频流网站但是它无所谓。那么任何人都知道如何打开电影文件并正确地传输它?

2 个答案:

答案 0 :(得分:3)

Dancer这样的框架可以解决这个问题,而不是手工完成。这将为您节省许多很多麻烦。它还允许您利用Plack/PSGI强力胶水来确定如何与您的Web服务器通信。

use Dancer;

get qr{/(\w{11}\.webm)$}i => sub {
    my($video_file) = splat;

    return send_file(
        $video_file,
        streaming => 1,
    );
}

使用Dancer routes,你应该可以很容易地调整现有代码,特别是如果它与各种路径匹配的if / elsif很大。 Dancer在简单易用方面做得非常出色,如果需要,它还可以让您对确切的HTTP响应进行大量控制。

一些笔记......

  • webm的内容类型为video/webm,可能是您遇到问题的根源。舞者应该做对。如果没有,您可以明确告诉send_file内容类型。

  • (\w|\d){11}最好写成\w{11},因为\w包含\d

答案 1 :(得分:2)

您必须使用206 Partial Content HTTP状态,并且还必须发送:

  • Accept-Range: bytes标题。
  • 一个Content-Range: 0-2048/123456标头,您可以在其中发送内容的起始和结束字节索引,后跟内容的总字节长度。客户端将在请求标头中向您发送它想要的字节范围。客户端可以在单个请求中发送多个字节范围,在这种情况下,您还需要发送具有多部分字边界的内容。

最后,回到你的问题,如果客户端请求的字节范围不可满足,那么你发送416 HTTP状态并关闭连接。