我们在使用默认的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上显示无法播放图标。我们已尝试修改各种标题"内容长度","内容范围"等,但它们似乎不会影响最终结果。
我们也尝试过在某种程度上使用send_data
即
File.open(file_path, "r") do |f|
send_data f.read, :type => "video/mp4"
end
在Ipad上查看时,公共文件夹中的同一视频效果很好。
通过rails向Ipad提供mp4文件的正确方法是什么?
答案 0 :(得分:16)
问题似乎是rails不处理ios流mp4所需的http范围请求。
这是我们的开发解决方案(使用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来为我们的生产环境中的资产提供服务,因为上述解决方案比我们需要的要慢得多。