Safari未在Rails应用中加载HTML5视频 [英] Safari not loading HTML5 video in Rails app
问题描述
我有一个Rails应用程序我正在尝试使用以下标记播放HTML5视频:
I have a Rails app I'm trying to play an HTML5 video from using the following markup:
不起作用:
<video controls poster="http://lvh.me:3000/assets/videos/myvideo.png">
<source src="http://lvh.me:3000/assets/images/videos/myvideo.mp4" type="video/mp4">
<source src="http://lvh.me:3000/assets/images/videos/myvideo.webm" type="video/webm">
<source src="http://lvh.me:3000/assets/images/videos/myvideo.ogv" type="video/ogg">
</video>
在Safari上,视频显示正在加载...但从未播放,尽管它按预期工作在Chrome和Firefox中。我认为它最初可能是路径,但我已经尝试了绝对路径,相对路径和Rails image_path
帮助器,没有结果。
On Safari, the video says "Loading..." but never plays, although it works as expected in Chrome and Firefox. I thought it may have been the path at first, but I've tried absolute paths, relative paths, and the Rails image_path
helper with no results.
为了调试,我复制了这个示例HTML5视频标签,它按预期在Safari中播放(这里唯一的区别是源视频):
To debug, I copied this example HTML5 video tag and it plays in Safari as expected (the only difference here is the source video):
工作:外部托管的示例视频
Works: externally hosted sample video
<video controls poster="http://easyhtml5video.com/assets/video/Penguins_of_Madagascar.jpg">
<source src="http://easyhtml5video.com/assets/video/new/Penguins_of_Madagascar.mp4" type="video/mp4">
<source src="http://easyhtml5video.com/assets/video/new/Penguins_of_Madagascar.webm" type="video/webm">
<source src="http://easyhtml5video.com/assets/video/new/Penguins_of_Madagascar.ogv" type="video/ogg">
</video>
然而,当我采用这个完全相同的标记并在本地托管这些相同的文件时,视频停止工作Safari:
However, when I take this exact same markup and host these same files locally, the video stops working in Safari:
无法使用:本地托管的示例视频
Doesn't work: locally hosted sample video
<video controls poster="http://lvh.me:3000/assets/videos/Penguins_of_Madagascar.jpg">
<source src="http://lvh.me:3000/assets/videos/new/Penguins_of_Madagascar.mp4" type="video/mp4">
<source src="http://lvh.me:3000/assets/videos/new/Penguins_of_Madagascar.webm" type="video/webm">
<source src="http://lvh.me:3000/assets/videos/new/Penguins_of_Madagascar.ogv" type="video/ogg">
</video>
注意:
- 我没有在Safari控制台或Rails日志中收到错误;文件或其他内容没有404。
- 本地托管的视频在Chrome和FF中运行,所以我知道路径是正确的。
- 外部托管的视频在Safari中工作正常。
- 本地托管的视频在Rails应用程序之外的Safari中工作 - 我创建了一个静态页面并使用上面的所有示例效果很好。
- I'm not getting errors in the Safari console or Rails log; no 404s on the files or anything.
- Locally hosted videos work in Chrome and FF, so I know the paths are correct.
- Externally hosted videos work fine in Safari.
- Locally hosted videos work in Safari outside of the Rails app—I created a static page and used all the examples above to good effect.
基于所有这些,似乎Safari和Rails的某些组合阻止了视频的加载。
Based on all of this, it seems like some combination of Safari and Rails that's preventing the videos from loading.
推荐答案
我遇到了同样的问题并且发现它是你在视频中前后移动所需的字节范围。
I had the same problem and figured out it's the byte-range you need for moving back and forward in video.
# (c) Thomas Fritzsche
# This is prove-of-concept coding only
# iOS devices insist on support for byte-rage http header, that is not native
# supported by rack apps like dragonfly
# this rack middleware will evaluate the http header and provide byte range support.
# For a dragonfly Rails (3.2.3) app I have tested this will call like this.
# I reload Rack::Cache that case trouble when initialized by Rails.
# This small trick makes it working :-)
#-----------------------
#require 'dragonfly/rails/images'
#require "range"
#
#
#Rails.application.middleware.delete(Rack::Cache)
#Rails.application.middleware.insert 0, Rack::Cache, {
# :verbose => true,
# :metastore => URI.encode("file:#{Rails.root}/tmp/dragonfly/cache/meta"),
# :entitystore => URI.encode("file:#{Rails.root}/tmp/dragonfly/cache/body")
#}
#
#Rails.application.middleware.insert_before Rack::Cache, RangeFilter
#
# [...]
#-------------------
class RangeFilter
def initialize(app)
@app = app
end
def call(env)
dup._call(env)
end
def _call(env)
@status, @headers, @response = @app.call(env)
range = env["HTTP_RANGE"]
if @status == 200 and range and /\Abytes=(\d*)-(\d*)\z/ =~ range
@first_byte, @last_byte = $1, $2
@data = "".encode("BINARY")
@response.each do |s|
@data << s
end
@length = @data.bytesize if @length.nil?
if @last_byte.empty?
@last_byte = @length - 1
else
@last_byte = @last_byte.to_i
end
if @first_byte.empty?
@first_byte = @length - @last_byte
@last_byte = @length - 1
else
@first_byte = @first_byte.to_i
end
@range_length = @last_byte - @first_byte + 1
@headers["Content-Range"] = "bytes #{@first_byte}-#{@last_byte}/#{@length}"
@headers["Content-Length"] = @range_length.to_s
[@status, @headers, self]
else
[@status, @headers, @response]
end
end
def each(&block)
block.call(@data[@first_byte..@last_byte])
@response.close if @response.respond_to?(:close)
end
end
供进一步参考,查看 rails媒体文件流通过send_data或send_file方法接受字节范围请求或这个Ruby论坛帖子。
For further reference, check out rails media file stream accept byte range request through send_data or send_file method or this Ruby Forum post.
这篇关于Safari未在Rails应用中加载HTML5视频的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!