2012-08-28 34 views
0

我正在开发一个网站,使用Catalyst(一个perl MVC框架)和JWplayer在线服务多个视频,而且我需要一种稳定的方式将视频流传输到客户端播放器具有从随机点开始视频的能力。使用催化剂框架为Flash/html5播放器流视频

我搜索了网络的一些方法来做到这一点,但我找不到在Catalyst(RTMP或HTTP Pseudostreaming)中实现它的简单方法。我发现的唯一简单例子是一个流式传输MP3的旧版Catalyst脚本(http://dev.catalyst.perl.org/repos/Catalyst/trunk/examples/Streaming/lib/Streaming.pm),但我不知道如果将该技术应用于视频,该功能是否会按预期工作。

在Catalyst/Perl中以非复杂的方式提供在线视频的好方法是什么?或者推荐的方法是什么?

谢谢你们!

回答

0

这只是一个部分的答案,因为我目前还坚持这一点。

如果文件已经是FLV格式,那么Static :: Simple插件就可以正常工作。我已经用root/static /目录中的文件和$c->serve_static_file方法对它进行了测试。下面是我jwplayer设置(包裹在jQuery的ready功能。

<script type="text/javascript" src="[% c.uri_for('/static/js/mediaplayer-5.10') %]/jwplayer.js"></script> 
<script type="text/javascript"> 
$(function() { 
     jwplayer('mediaplayer').setup({ 
     'flashplayer': "[% c.uri_for('/static/js/mediaplayer-5.10/player.swf') %]", 
     'id': 'playerID', 
     'width': '480', 
     'height': '270', 
     'file': "[% c.uri_for('/download') %]/dump/ffs/root/static/transcode_jEfhmk.flv" 
    }); 
}); 
</script> 

如果该文件是另一种格式,则需要对其进行转码。以下是我目前的尝试。它转码就好了,你可以即使流的文件的下载,但我遇到了麻烦jwplayer从转码流播放。

use IPC::Open3; 

#path comes in as /flv/path/to/file.avi 
sub index :Path :Args { 
    my ($self, $c, @path) = @_; 
    @path = grep($_ ne '..', @path); 
    my $path = join('/',@path); 
    my $abs_path = $c->config->{'serve_dir'} . '/'; 
    $abs_path .= join("/", @path); 

    if (-r $abs_path){ 
     my ($stdin, $stdout, $stderr, $pid); 
    #avconv 
    # -i input_file 
    # -b:v video bitrate 
    # -s video size 
    # -r video framerate 
    # -an no audio (having trouble with the audio settings) 
    # -f format 
    # pipe:1 send transcoded video to STDOUT 
     $pid = open3($stdin, $stdout, $stderr, "avconv -i \"$abs_path\" -b:v 600k -s 320x240 -r 25 -f flv -an pipe:1"); 

     $c->response->content_type("video/x-flv"); 
     $c->response->header('Content-Disposition' => "filename=transcode.flv"); 
     my $chunk_size = 1048576; 
     do { 
      read($stdout, my $buffer, $chunk_size); 
      $c->write($buffer); 
     } while (kill(0, $pid)); #loop while transcoding process is alive 
    } 
} 

要添加伪流,你需要做一个控制器,查找开始查询参数,然后寻求它,并将$c->response->body发送到文件句柄。

open(my $fh, "<", $path); 
binmode($fh); 
if ($c->req->param('start')){ 
    seek($fh, $c->req->param('start'), 0); 
} 
$c->response->body($fh); 

一个告诫:视频必须在jwplayer能够寻找的元数据中具有关键帧。

从jwplayer的HTTP streaming页:

注:编码视频时,有些FLV编码器不包括seekpoints元数据。 没有这些数据,HTTP Pseudostreaming将不起作用。如果您怀疑自己的视频没有元数据,请使用我们的Metaviewer plugin检查视频。应该有一个查找点或关键帧列表。如果它不存在,请使用FLVMDI工具解析您的FLV视频并注入此元数据。

+0

Static :: Simple插件会在玩家请求的任何开始位置向玩家提供视频(使用FLV格式)?我今天没有时间测试它,但我会测试它并发布结果! – h3ct0r

+0

看起来我错了。我的视频即时缓冲,所以我没有注意到你无法通过缓冲部分。看起来我们可能需要实现[pseudo-streaming](http://www.longtailvideo.com/support/jw-player/jw-player-for-flash-v5/12534/video-delivery-http-pseudo-streaming #mechanism),捕获开始参数,并在Streaming.pm中寻找它。至少它是以字节为单位的。嘿。 –

+0

感谢您的信息,我仍然在寻找稳定而简单的流式传输方式。如果我成功了,我会把如何在这里! – h3ct0r

0

最后,我使用带有x_send_file插件的apache来传递webm视频(使用范围字节搜索)和亚马逊云前端来传送mp4视频和使用mp4进行流式传输。