我有一个Rails应用程序我尝试使用以下标记播放HTML5视频:
不起作用:
<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上,视频显示&#34;正在加载......&#34;但从不播放,尽管它在Chrome和Firefox中的效果与预期一致。我认为它最初可能是路径,但我已尝试过绝对路径,相对路径和Rails image_path
帮助器而没有结果。
要进行调试,我复制了此示例HTML5视频标记,并按预期在Safari中播放(此处唯一的区别是源视频):
工作:外部托管的示例视频
<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中停止工作:
无法使用:本地托管的示例视频
<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的某些组合阻止了视频的加载。
答案 0 :(得分:4)
我遇到了同样的问题,并确定了在视频中前后移动所需的字节范围。
Here's some middleware that adds support for the byte-range HTTP header:
# (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 media file stream accept byte range request through send_data or send_file method或this Ruby Forum post。
答案 1 :(得分:1)
我知道这个问题已经超过 5 年了,但我遇到了同样的问题并解决了它,所以我会在这里发布我的解决方案。
当您将视频文件放入资产文件夹时,它们会以一种特殊的方式提供服务。然后,不提供字节范围请求。这意味着 Safari 不会播放视频,因为它需要字节范围请求才能在视频中跳转并以不同的速度播放。
如果您将视频放入公共文件夹并从那里提供它们,则是中间件为它们提供服务,在这种情况下,将提供范围请求。 (Rails 5)
因此,只需将您的视频移至 public
。至少那为我修好了......
答案 2 :(得分:0)
参考链接:https://superuser.com/questions/870133/html5-video-tag-not-supported-in-safari-5-1-on-windows-7
由于rail_中的video_tag在内部使用HTML5“视频”标签属性,而Safari浏览器不支持HTML5视频标签属性。
为了使HTML5视频能够通过Windows上的Safari播放,您需要 需要安装Quicktime。
我这样做了,视频仍然无法播放。
但是,一旦我重新启动计算机,一切都会按预期工作 来!