Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
819 views
in Technique[技术] by (71.8m points)

http headers - rails media file stream accept byte range request through send_data or send_file method

I have the following problem. Sounds are hidden from the public folder, cause there are only certain Users who should have access to the sound files. So I made a certain method, which acts like a sound url, but calculates first, whether the current user is allowed to access this file.

The file gets sent by the send_data method. The problem is just, that I it works quite slow if it works even... The developer of the jplayer plugin, which I use to play the sound, told me that I should be able to accept byte range requests to make it work properly...

How can I do this within a rails controller by sending the file with send_data or send_file?

Thanks, Markus

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I've been able to serve up the files with some success using send_file. Although I have one hitch, seeking to an earlier part of the song causes a new request which makes the song restart from 0:00 instead of the true location from the seekbar. This is what I have working for me so far:

  file_begin = 0
  file_size = @media.file_file_size 
  file_end = file_size - 1

  if !request.headers["Range"]
    status_code = "200 OK"
  else
    status_code = "206 Partial Content"
    match = request.headers['range'].match(/bytes=(d+)-(d*)/)
    if match
      file_begin = match[1]
      file_end = match[1] if match[2] && !match[2].empty?
    end
    response.header["Content-Range"] = "bytes " + file_begin.to_s + "-" + file_end.to_s + "/" + file_size.to_s
  end
  response.header["Content-Length"] = (file_end.to_i - file_begin.to_i + 1).to_s
  response.header["Last-Modified"] = @media.file_updated_at.to_s

  response.header["Cache-Control"] = "public, must-revalidate, max-age=0"
  response.header["Pragma"] = "no-cache"
  response.header["Accept-Ranges"]=  "bytes"
  response.header["Content-Transfer-Encoding"] = "binary"
  send_file(DataAccess.getUserMusicDirectory(current_user.public_token) + @media.sub_path, 
            :filename => @media.file_file_name,
            :type => @media.file_content_type, 
            :disposition => "inline",
            :status => status_code,
            :stream =>  'true',
            :buffer_size  =>  4096)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...