【问题标题】:Streaming video for flash/html5 player using catalyst framework使用 Catalyst 框架为 flash/html5 播放器流式传输视频
【发布时间】:2018-06-30 01:08:35
【问题描述】:

我正在开发一个网站,使用 Catalyst(A perl MVC 框架)和 JWplayer 在线提供多个视频,我需要一种稳定的方式将视频流式传输到客户端播放器,并能够从一个随机点。

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

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

谢谢大家!

【问题讨论】:

    标签: perl streaming video-streaming jwplayer catalyst


    【解决方案1】:

    这只是部分答案,因为我目前也被困在这个问题上。

    如果文件已经是 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-&gt;response-&gt;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 编码器在编码视频时不包含搜索点元数据。 如果没有这些数据,HTTP 伪流将无法工作。如果您怀疑您的视频没有元数据,请使用我们的Metaviewer plugin 检查视频。应该有一个搜索点或关键帧列表。如果不存在,请使用 FLVMDI 工具解析您的 FLV 视频并注入此元数据。

    【讨论】:

    • Static::Simple 插件将在播放器请求的任何开始位置向播放器提供视频(使用 FLV 格式)?我今天没有时间测试它,但我会测试它并发布结果!
    • 看来我错了。我的视频立即缓冲,所以我没有注意到您无法通过缓冲部分。看起来我们可能需要实现pseudo-streaming,捕获开始参数,然后像在 Streaming.pm 中一样寻找它。至少它以字节为单位。呵呵。
    • 感谢您的信息,我仍在寻找一种稳定且简单的流式传输方式。如果我成功了,我会把方法放在这里!
    【解决方案2】:

    最后,我使用带有 x_send_file 插件的 apache 来传递 webm 视频(使用范围字节搜索)和 Amazon Cloud Front 来传递 mp4 视频和使用 mp4 流式传输。

    编辑: 结束使用带有自定义插件的 Wowza Streaming Server 与 Catalyst 进行安全通信。如果没有专用的视频服务器,就没有可靠的视频流传输方式,尤其是对于企业而言。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-10-23
      • 1970-01-01
      • 2011-09-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-23
      • 1970-01-01
      相关资源
      最近更新 更多