轨道视频流4.2

时间:2015-07-07 22:00:19

标签: ruby-on-rails-4 video nginx passenger jplayer

我不确定这是编程问题还是网络服务器配置问题。

视频文件不在public/中,因此请求必须通过控制器。

在我的控制器中:

  def play_video
   video=Video.find params[:id]
   response.headers['Content-Length'] = File.size(video.path).to_s
   send_data File.read(video.path,mode: 'rb'), type: video.mime_type, disposition: 'inline'

在客户端,我现在正在使用JPlayer。在Linux上运行的Firefox中,无论是开发还是生产,它都能正常运行,我可以毫无问题地前进或后退。在Linux和Windows上几乎所有其他浏览器中,它都可以正常播放,但就是它,在开发和生产中没有向前或向后跳过。我会将其添加到JPlayer错误中,但只使用<video> with control attribute以及mediaelement.js,我会得到完全相同的行为。

在开发中,我正在使用Thin,正在制作PassengerNginx

nginx.conf:

    worker_processes  4;
    events {
        worker_connections  1024;
    }
     sendfile        on;
     #tcp_nopush     on;
  http {
    passenger_root /usr/local/lib64/ruby/gems/2.2.0/gems/passenger-5.0.11;
    passenger_ruby /usr/local/bin/ruby;
    keepalive_timeout  120;
   gzip  on;
   server {
        server_tokens off;
        listen 80 default_server;
        listen 443 ssl;
        server_name www.example.com;
        root /path/to/public;  
        passenger_enabled on;
        client_max_body_size 100M;
        add_header Strict-Transport-Security "max-age=31536000;  includeSubdomains;";       
        add_header X-Content-Type-Options nosniff;
        add_header X-XSS-Protection "1; mode=block";
        include mime.types;
        default_type application/octet-stream;
        #removed SSL config stuff
        ...

我不确定问题出在哪里。尝试跳过时,我没有收到任何错误消息。

请不要链接到Rails HTTP Streaming教程,因为它们都是蹩脚的,并且没有任何帮助向客户端发送“hello world”10次示例,除非您有一个实际上解决视频流的问题。我找到的任何东西都是旧版本的rails和其他网络服务器。

1 个答案:

答案 0 :(得分:2)

这是一个反模式,你正在尝试做什么,send_file是完全阻塞同步机制,基本上它需要N个Rails进程,因为你的应用程序将一次提供多少请求。这是通过控制访问文件或执行任何类型的前/后处理的理由来完成的:权限检查,审计等。

如果这是反模式图案的样子: 1)X-Accel-Redirect 2)通过auth_request模块进行异步权限检查

在第一种情况下,您的Rails应用程序仅返回X-Accel-Redirect标头中的文件URL,其中包含空主体,然后关闭此请求,以便Rails可以立即继续提供新请求,而不是等到客户端获取文件(如果客户端的连接速度慢,Rails在完成之前无法自由处理)。基本上要同时服务10个大型视频文件,10个工作人员要求你拥有。 X-Accel-Redirect仅与一名工人完成同样的工作:

<强>滑轨

def download
  video=Video.find params[:id]
  headers['X-Accel-Redirect'] = "#{video.file_name}"
  render nothing: true
end

<强> Nginx的

location /video {
  internal;
  root /mnt/video;
}

备选方案是auth_request,效率相似,但您需要事先知道文件目标URL不是由服务器生成的。 Auth_request位置是内部的,它通过Rails路由处理身份验证,然后拒绝或将用户传递到目标视频文件URL:

<强> Nginx的

location /video/ {
    root /mnt/video;
    auth_request /auth;
    ...
}

location = /auth {
    internal;
    proxy_pass http://localhost;
    proxy_pass_request_body off;
    proxy_set_header Content-Length "";
    proxy_set_header X-Original-URI $request_uri;
}