Help us understand the problem. What is going on with this article?

Safariで動画を表示する際、サーバーのHTTP Range Request対応が必須になっている

More than 1 year has passed since last update.

発生した現象

ローカルPCに適当にサーバーを立て、html5のvideoタグで各ブラウザで表示する際、
なぜかSafariで動画が表示されない問題が発生しました。
しかも、まったく同じhtmlファイルでローカルPCのファイルパス直打ちであれば動画が表示されました。

スクリーンショット 2018-06-19 11.24.40.png

上:ローカルPCのファイルパス指定
下:ローカルサーバーのURL指定

サーバーは php5.6を使って php -S localhost:8001 で適当に立てていました。

原因

Safariでは、mp4のようなサイズが大きくなると思われるファイルをHTTPリクエストする際に、
HTTP Range Requestを利用し、サーバーがこれに対応できないとそのファイルを読み込まないようです。

スクリーンショット 2018-06-19 12.47.04.png

今回のHTTPリクエストでは、 Range: bytes=0-1 が指定されており、
「最初の1byteのみ送信せよ」というリクエストを送っています。
サーバーは「206 Partial Content」とともに動画データの最初の1byteを返すのが正解なのですが、
php5.6で立てたサーバーではこのRangeヘッダーに対応しておらず、
無視してmp4をすべて返してしまっていました。

Range RequestはRFC7233で定義され、2014年ごろに"Proposed standard"に昇格しました。

RFC 7233 Hypertext Transfer Protocol (HTTP/1.1): Range Requests
https://tools.ietf.org/html/rfc7233

RFC 7233 日本語訳
https://triple-underscore.github.io/RFC7233-ja.html

MDN Web docs
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Range

php5.6などの古いサーバーではこれに対応しておらず、
かつ、手元のブラウザ(Mac Safari/Mac Firefox/Mac Chrome/Windows10 Edge)を比較したところ
Mac SafariのみRange Requestに対応できない場合はエラーとなるため、
Safariのみ動画が再生できない不思議な挙動が発生していました。

いくつか手元にあった他のサーバーも試してみましたが、

と、古くメンテされてないプロジェクトでは対応してないものがあるようです。
(コマンド例の一部は https://qiita.com/higuma/items/b23ca9d96dac49999ab9 を参考にしました)

Apache、nginxやS3、CloudFrontなどは当然対応しているので、開発環境以外で問題になることは少ないかと思いますが、
開発環境ではこの問題に引っかからないように注意しましょう。

その他

Safariが「mp4以外のファイル」でもRange Requestを必須にしているのかどうかは、ちゃんと調べてません。
どんな基準でRange Requestを使うようにしてるんですかね?


Golang(1.10.3)だと、適当に書いてもRangeに対応できる。

httpServer.go
package main

import "net/http"

func main() {
  panic(http.ListenAndServe(":8001", http.FileServer(http.Dir("."))))
}
go run httpServer.go

2010年ごろのauガラケーではRange Headerが必須だった時代があったようです。
当時対応するのは結構大変だったんじゃないですかね……
http://tnamao.hatenablog.com/entry/20100617/p1

備考

検証に使用したHTMLファイル

<!DOCTYPE html>
<html>
  <head> 
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <link href="http://vjs.zencdn.net/7.0/video-js.min.css" rel="stylesheet">
    <script src="http://vjs.zencdn.net/7.0/video.min.js"></script>
  </head>
  <body>
    <video class="video-js vjs-default-skin" controls muted autoplay>
      <source src="./google.mp4" type='video/mp4' />
    </video>
  </body>
</html>

追記

2016年時点では状況が異なり、
SafariではRangeヘッダーがついていなかったんだそうです。
(しかもその当時は、Firefoxでは206 Partial Contentを返すと動画が途中までしか再生されない問題が発生したらしい)

http://engineer.crowdworks.jp/entry/2016/03/16/121353

(情報提供: https://qiita.com/jmatsu )

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした