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.
This could be completely unrelated as I am using nginx for the server, but if its only not working for ios, take a look at this blog post. There could be a similar solution for Apache.
In a sense, I had to add a proxy header that internally redirects to a folder path. How ever stupid this may seem, Apple has some sort of privacy issues that make this necessary for playback with audio and video files. Again not sure if this is the solution for you but for nginx this did wonders and cured my month long headache.
Have you enabled X-Sendfile config in your environment? Include the line config.action_dispatch.x_sendfile_header = "X-Sendfile"
for Apache. The server will then use that header for sending files.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With