加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ruby-on-rails – Rails send_file不播放mp4

发布时间:2020-12-17 02:37:27 所属栏目:百科 来源:网络整理
导读:我有一个Rails应用程序,可以保护上传的视频,将它们放入私人文件夹. 现在我需要播放这些视频,当我在控制器中执行此类操作时: def show video = Video.find(params[:id]) send_file(video.full_path,type: "video/mp4",disposition: "inline") end 并在/ vide
我有一个Rails应用程序,可以保护上传的视频,将它们放入私人文件夹.

现在我需要播放这些视频,当我在控制器中执行此类操作时:

def show
    video = Video.find(params[:id])
    send_file(video.full_path,type: "video/mp4",disposition: "inline")
  end

并在/ videos /:打开浏览器(Chrome或FF),不播放视频.

如果我将相同的视频放在公共文件夹中,并像/video.mp4那样访问它,它将播放.

如果我删除了dispositon:“inline”它会下载视频,我可以从我的电脑上播放它. webm视频也是如此.

我错过了什么?这可能吗?

解决方法

要流式传输视频,我们必须为某些浏览器处理请求的 byte range.

解决方案1:使用send_file_with_range gem

简单的方法是让send_file_with_range gem修补send_file方法.

在Gemfile中包含gem

# Gemfile
gem 'send_file_with_range'

并为send_file提供range:true选项:

def show
  video = Video.find(params[:id])
  send_file video.full_path,disposition: "inline",range: true
end

The patch很短,值得一看.
但是,不幸的是,它对我来说对Rails 4.2不起作用.

解决方案2:手动修补send_file

受宝石的启发,手动扩展控制器非常简单:

class VideosController < ApplicationController

  def show
    video = Video.find(params[:id])
    send_file video.full_path,range: true
  end

private

  def send_file(path,options = {})
    if options[:range]
      send_file_with_range(path,options)
    else
      super(path,options)
    end
  end

  def send_file_with_range(path,options = {})
    if File.exist?(path)
      size = File.size(path)
      if !request.headers["Range"]
        status_code = 200 # 200 OK
        offset = 0
        length = File.size(path)
      else
        status_code = 206 # 206 Partial Content
        bytes = Rack::Utils.byte_ranges(request.headers,size)[0]
        offset = bytes.begin
        length = bytes.end - bytes.begin
      end
      response.header["Accept-Ranges"] = "bytes"
      response.header["Content-Range"] = "bytes #{bytes.begin}-#{bytes.end}/#{size}" if bytes

      send_data IO.binread(path,length,offset),options
    else
      raise ActionController::MissingFile,"Cannot read file #{path}."
    end
  end

end

进一步阅读

因为,起初,我不知道stream:true和range:true之间的区别,我发现这个railscast很有帮助:

http://railscasts.com/episodes/266-http-streaming

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读