I have an application serving large (some hundreds of MB) video files and it is working perfectly on desktop browsers, using Rails + X-Sendfile on Apache. An important requirement is that these videos must be private and visible only to logged users, so that's why i'm using Rails to serve them.
Everything works perfectly with other devices. I serve the videos in this way:
response.headers["X-Sendfile"]= filename
send_file filename, :disposition => :inline, :stream => true, :x_sendfile => true
But Ipad's requests need the byte range header. A solution (that does not work perfectly) is something like this:
size = File.size(filename)
bytes = Rack::Utils.byte_ranges(request.headers, size)[0]
offset = bytes.begin
length = bytes.end - bytes.begin
response.header["Accept-Ranges"]= "bytes"
response.header["Content-Range"] = "bytes #{bytes.begin}-#{bytes.end}/#{size}"
send_data IO.binread(filename,length, offset), :type => "video/mp4", :stream => true, :disposition => 'inline', :file_name => filename
With this solution I have problems with larger than 50mb videos, and, more important, I'm giving to rails a responsibility that it shouldn't have. It should be apache to handle the heavy load of the streaming, through the x-sendfile module. But I dont know how. the send_data
method does not have the x-sendfile parameter, and solutions involving the send_file method are not working.
I found these 2 questions similar to mine but they are not working: rails media file stream accept byte range request through send_data or send_file method, What is the proper way to serve mp4 files through rails to an Ipad?
Any clue on what's going on? I'm struggling with this since weeks and i need to make it work. Other feasible solutions are welcome.