2015-11-16 2 views
8

У меня есть приложение Rails Я пытаюсь играть видео HTML5 с помощью следующей разметки:Safari не загружается видео HTML5 в приложении Rails

Не работает:

<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 без каких-либо результатов.

Для отладки, я скопировал этот пример 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:

Не работает: lo чески размещается образец видео

<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.
  • Локально размещенные видеоролики работают в Safari за пределами приложения Rails. Я создал статическую страницу и использовал все приведенные выше примеры для хорошего эффекта.

Исходя из всего этого, кажется, что некоторые комбинации Safari и Rails предотвращают загрузку видео.

+0

Может быть, это что-то делать с контент-типами вы можете попробовать добавить это к вашему 'mime_types.rb' ' Rack :: Мима :: MIME_TYPES.merge! ( ".ogg" => «приложение/ogg ", " .ogx "=>" application/ogg ", " .ogv "=>" video/ogg ", " .wemb "=>" video/webm ", " .mp4 "=>". video/mp4 ", " .m4v "=>" video/mp4 ")' – Chris

+0

@Chris Я добавил это и перезапустил Rails, но не повезло. Я вижу, что тип MIME уже корректен без этого изменения, согласно curl. Если вы взяли этот список где-то важного, обратите внимание, что в нем есть опечатка: '' .wemb ''. Я изменил это на '.webm '' при локальном тестировании. – Shepmaster

+0

Интересно отметить, что файл ** корректно загружается и начинает воспроизводиться при развертывании моего приложения в Heroku. – Shepmaster

ответ

2

У меня была такая же проблема, и выяснилось, что это байтовый диапазон, который вам нужен для перемещения назад и вперед в видео.

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[@[email protected]_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.

+0

Спасибо. Я адаптировал метод, и он работал хорошо. Как уже упоминалось, это, вероятно, не очень хорошая настройка производительности, и я бы использовал что-то вроде« X-Sendfile »в этом Однако он позволяет работать в Safari во время разработки, и это то, что мне нужно! – Shepmaster

Смежные вопросы