12

デフォルトの Rails 3 アプリを使用して、iPad で再生する mp4 ファイルの提供に問題があります。mp4 は、デスクトップ上の Chrome およびその他のブラウザーでルートを表示すると、正しく提供されます。

コードは次のとおりです。

file_path = File.join(Rails.root, 'test.mp4')
send_file(file_path, :disposition => "inline", :type => "video/mp4")

0.0.0.0:3000/video/test.mp4 を押してビデオを表示すると、ipad で再生できないアイコンが表示されます。「Content-Length」、「Content-Range」などのさまざまなヘッダーを変更しようとしましたが、最終結果には影響しないようです。

send_data もある程度使用してみました

すなわち

File.open(file_path, "r") do |f|
    send_data f.read, :type => "video/mp4"
end 

Ipad で表示すると、同じビデオがパブリック フォルダーから正常に配信されます。

レールを介してIpadにmp4ファイルを提供する適切な方法は何ですか?

4

1 に答える 1

21

問題は、Rails が ios が mp4 をストリーミングするために必要とする http-range リクエストを処理しないことです。

これが開発用のソリューションでした (サーバーとしてシンを使用):

  if(request.headers["HTTP_RANGE"]) && Rails.env.development?

    size = File.size(file_path)
    bytes = Rack::Utils.byte_ranges(request.headers, size)[0]
    offset = bytes.begin
    length = bytes.end - bytes.begin + 1

    response.header["Accept-Ranges"]=  "bytes"
    response.header["Content-Range"] = "bytes #{bytes.begin}-#{bytes.end}/#{size}"
    response.header["Content-Length"] = "#{length}"

    send_data IO.binread(file_path,length, offset), :type => "video/mp4", :stream => true,  :disposition => 'inline',
              :file_name => file_name

  else
    send_file(file_path, :disposition => 'inline', :stream => true, :file_name => file_name)
  end

上記のソリューションは必要なものよりもはるかに遅いため、最終的には nginx XSendfileを使用して実稼働環境でアセットを提供します。

于 2013-05-16T16:41:19.297 に答える