Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails + X-Sendfile serving large video to Ipad

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.

like image 349
sissy Avatar asked Mar 22 '14 18:03

sissy


2 Answers

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.

like image 138
Noah Passalacqua Avatar answered Oct 07 '22 18:10

Noah Passalacqua


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.

like image 34
Mike A Avatar answered Oct 07 '22 18:10

Mike A