Safari未在Rails应用中加载HTML5视频 [英] Safari not loading HTML5 video in Rails app

查看:144
本文介绍了Safari未在Rails应用中加载HTML5视频的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个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.

这是一些增加了对字节范围HTTP标头的支持的中间件

# (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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆