12

我们无法使用默认的 rails 3 应用程序在 ipad 上播放 mp4。在桌面上的 chrome 和其他浏览器中查看路线时,mp4 会正确提供。

这是我们的代码:

file_path = File.join(Rails.root, 'test.mp4')
send_file(file_path, :disposition => "inline", :type => "video/mp4")

我们点击 0.0.0.0:3000/video/test.mp4 观看视频并在 ipad 上显示无法播放图标。我们尝试修改各种标题“Content-Length”、“Content-Range”等,但它们似乎不会影响最终结果。

我们也在一定程度上尝试过使用 send_data

IE

File.open(file_path, "r") do |f|
    send_data f.read, :type => "video/mp4"
end 

在 Ipad 上观看时,相同的视频可以从公用文件夹中正常播放。

通过rails向Ipad提供mp4文件的正确方法是什么?

4

1 回答 1

21

问题似乎是 rails 不处理 ios 流式传输 mp4 所需的 http-range 请求。

这是我们的开发解决方案,(使用 Thin 作为我们的服务器):

  if(request.headers["HTTP_RANGE"]) && Rails.env.development?

    size = File.size(file_path)
    bytes = Rack::Utils.byte_ranges(request.headers, size)[0]
    offset = bytes.begin
    length = bytes.end - bytes.begin + 1

    response.header["Accept-Ranges"]=  "bytes"
    response.header["Content-Range"] = "bytes #{bytes.begin}-#{bytes.end}/#{size}"
    response.header["Content-Length"] = "#{length}"

    send_data IO.binread(file_path,length, offset), :type => "video/mp4", :stream => true,  :disposition => 'inline',
              :file_name => file_name

  else
    send_file(file_path, :disposition => 'inline', :stream => true, :file_name => file_name)
  end

最终,我们将使用 nginx XSendfile为生产环境中的资产提供服务,因为上述解决方案比我们需要的要慢得多。

于 2013-05-16T16:41:19.297 回答