[RUBY-ON-RAILS] 미디어 파일 스트림 또는 SEND_DATA send_file 방법을 통해 바이트 범위 요청을 수락 레일
RUBY-ON-RAILS미디어 파일 스트림 또는 SEND_DATA send_file 방법을 통해 바이트 범위 요청을 수락 레일
나는 다음과 같은 문제가있다. 사운드 파일에 액세스 할 수 있어야합니다 특정 사용자가 원인 사운드는 공용 폴더에서 숨겨져 있습니다. 나는 현재 사용자가 접근이 파일을 사용할 수 있는지 여부를, 사운드 URL을 같은 역할을하지만, 먼저 계산하는 특정 방법을했다 그래서.
이 파일은 SEND_DATA 방법으로 전송됩니다. 문제는 꽤 느린이 ... 심지어 내가 소리를 재생하는 데 사용하는 jplayer 플러그인의 개발자를 작동하는 경우 작동 나는 것을 그냥, 나는 그것이 제대로 작동하도록 바이트 범위 요청을 수락 할 수 있어야한다고 하더군요 ...
어떻게이 send_file SEND_DATA 또는 사용하여 파일을 전송하여 레일 컨트롤러 내에서 할 수 있습니까?
감사, 마르쿠스
해결법
-
==============================
1.내가 send_file 사용하여 약간의 성공으로 파일을 제공 할 수있었습니다. 나는이 노래의 이전 부분을 찾고, 하나 개의 장애를 가지고 있지만 대신 검색 막대에서 진정한 위치 0시에서 노래를 다시 시작하게하는 새로운 요청이 발생합니다. 이것은 내가 나를 위해 지금까지 작업 한 것입니다 :
내가 send_file 사용하여 약간의 성공으로 파일을 제공 할 수있었습니다. 나는이 노래의 이전 부분을 찾고, 하나 개의 장애를 가지고 있지만 대신 검색 막대에서 진정한 위치 0시에서 노래를 다시 시작하게하는 새로운 요청이 발생합니다. 이것은 내가 나를 위해 지금까지 작업 한 것입니다 :
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)
-
==============================
2.여기 내 버전입니다. 나는 제대로 파일을 OGG 역할을하는 데 필요한 시간을 계산하기 위해 'ogginfo-RB'보석을 사용합니다. 추신. WAV, MP3, OGG - 나는 항상 세 가지 형식이있다.
여기 내 버전입니다. 나는 제대로 파일을 OGG 역할을하는 데 필요한 시간을 계산하기 위해 'ogginfo-RB'보석을 사용합니다. 추신. WAV, MP3, OGG - 나는 항상 세 가지 형식이있다.
the_file = File.open(file_path) file_begin = 0 file_size = the_file.size file_end = file_size - 1 if request.headers['Range'] status_code = :partial_content match = request.headers['range'].match(/bytes=(\d+)-(\d*)/) if match file_begin = match[1] file_end = match[1] if match[2] and not match[2].empty? end response.headers['Content-Range'] = "bytes #{file_begin}-#{file_end.to_i + (match[2] == '1' ? 1 : 0)}/#{file_size}" else status_code = :ok end response.headers['Content-Length'] = (file_end.to_i - file_begin.to_i + 1).to_s response.headers['Last-Modified'] = the_file.mtime response.headers['Cache-Control'] = 'public, must-revalidate, max-age=0' response.headers['Pragma'] = 'no-cache' response.headers['Accept-Ranges'] = 'bytes' response.headers['Content-Transfer-Encoding'] = 'binary' require 'ogginfo-rb' ogginfo = Ogg::Info::open(the_file.path.gsub(/.mp3|.wav/,'.ogg')) duration = ogginfo.duration.to_f response.headers['Content-Duration'] = duration response.headers['X-Content-Duration'] = duration send_file file_path, filename: "#{call.id}.#{ext}", type: Mime::Type.lookup_by_extension(ext), status: status_code, disposition: 'inline', stream: 'true', buffer_size: 32768
-
==============================
3.또 다른 수정 버전 - 내가 진 내용으로 zip 파일을 다운로드하려고했다 이것은 나를 위해 일한 것입니다 -
또 다른 수정 버전 - 내가 진 내용으로 zip 파일을 다운로드하려고했다 이것은 나를 위해 일한 것입니다 -
def byte_range_response (request, response, content) file_begin = 0 file_size = content.bytesize file_end = file_size - 1 status_code = '206 Partial Content' match = request.headers['range'].match(/bytes=(\d+)-(\d*)/) if match file_begin = match[1] file_end = match[2] if match[2] && !match[2].empty? end content_length = file_end.to_i - file_begin.to_i + 1 response.header['Content-Range'] = 'bytes ' + file_begin.to_s + '-' + file_end.to_s + '/' + file_size.to_s response.header['Content-Length'] = content_length.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_data get_partial_content(content, content_length, file_begin.to_i), type: 'application/octet-stream', status: status_code end def get_partial_content(content, content_length, offset) test_file = Tempfile.new(['test-file', '.zip']) test_file.puts(content) partial_content = IO.binread(test_file.path, content_length, offset) test_file.close test_file.unlink partial_content end
-
==============================
4.나는 개럿의 답변을 사용 (하나 또는 두 개의 버그 수정 포함)를 수정했습니다. 나는 또한 대신 파일에서 읽는 SEND_DATA를 사용 :
나는 개럿의 답변을 사용 (하나 또는 두 개의 버그 수정 포함)를 수정했습니다. 나는 또한 대신 파일에서 읽는 SEND_DATA를 사용 :
def stream_data data, options={} range_start = 0 file_size = data.length range_end = file_size - 1 status_code = "200" if request.headers["Range"] status_code = "206" request.headers['range'].match(/bytes=(\d+)-(\d*)/).try do |match| range_start = match[1].to_i range_end = match[2].to_i unless match[2]&.empty? end response.header["Content-Range"] = "bytes #{range_start}-#{range_end}/#{file_size}" end response.header["Content-Length"] = (range_end - range_start + 1).to_s response.header["Accept-Ranges"] = "bytes" send_data(data[range_start, range_end], filename: options[:filename], type: options[:type], disposition: "inline", status: status_code) end
from https://stackoverflow.com/questions/6759426/rails-media-file-stream-accept-byte-range-request-through-send-data-or-send-file by cc-by-sa and MIT license
'RUBY-ON-RAILS' 카테고리의 다른 글
[RUBY-ON-RAILS] 조건을 가진 열에 대한 카운터 캐시? (0) | 2020.02.20 |
---|---|
[RUBY-ON-RAILS] 액티브 :: 자료에 대한 정의되지 않은 방법 raise_in_transactional_callbacks = ': 클래스 (NoMethodError) (0) | 2020.02.20 |
[RUBY-ON-RAILS] 레일에 루비 - 모델에서 액세스 컨트롤러 변수 (0) | 2020.02.20 |
[RUBY-ON-RAILS] 사용자의 시간대의 시간을 표시하는 방법 (0) | 2020.02.20 |
[RUBY-ON-RAILS] 부트 스트랩 날짜 선택기를 사용하는 동안 어떻게 선택한 날짜 값을 얻으려면? (0) | 2020.02.19 |