iOS 8でBasic認証のmp4が見られないとき

自分のサーバでYoutubeしたい

Flowplayerを使おう

Youtubeは便利なんですが、メディアファイルを他人に任せたくないという場合はあると思います。私の場合も、家族のビデオを親戚と共有する場合などに、Youtubeを使うのは抵抗があります。

自分のサーバにメディアファイルをおいて外部から再生したい場合、Flowplayerを使えばブラウザウインドウ内での再生もでき、最大化もできて便利です。 うちのサーバでもやってみた例があります。

デフォルトだとflv形式ですが、それだとiPhoneやiPadで再生できないので、mp4形式にしています。HTMLの書き方は簡単ですし、今回はそこが本題ではないのでここではうちで書いている方法だけ紹介しておきます。

<script type="text/javascript" src="/flowplayer/flowplayer-3.2.12.min.js"></script>
<script type="text/javascript" src="/flowplayer/flowplayer.ipad-3.2.13.min.js"></script>
<div style="text-align: center;">
<a id="player1" href="video.mp4" style="display:block;width:480px;height:270px"></a>
<script type="text/javascript">
flowplayer("player1", "/flowplayer/flowplayer-3.2.18.swf",{buffering: true,clip: {autoPlay: false,autoBuffering: true,bufferLength: '3',scaling: 'fit'}}).ipad();
</script>

Flowplayer関連では以下のファイルをwebの上記のディレクトリ(/flowplayer/)以下に置いています。

  • flowplayer-3.2.12.min.js
  • flowplayer.ipad-3.2.13.min.js
  • flowplayer-3.2.18.swf
  • flowplayer.controls-3.2.15.swf (自動的にロードされます)

4行目の再生したいビデオファイル名(video.mp4)およびプレイヤーの大きさ(480 x 270)、1, 2, 6行目の関連ファイルの置き場所(/floplayer/)などは個別に変わりえるところです。環境に応じて適宜修正してください。

あと、この設定は追加スクリプト含めmp4対応になっていますので、そのままiPhoneやiPadで再生可能です。

iOS 8だと再生できない?

このメディアファイルをBASIC認証の必要な場所に置くと、iOS7までは問題なく再生できるのですが、iOS8ではちゃんと認証をしても再生できません。Flowplayerでは再生マークに斜線が入ってしまいますし、mp4ファイルのURLを直接指定しても再生されません。

Webサーバのログを調べたところ、401 Forbidden エラーが出ていることがわかりました。ログを見ると以下のようになっています。

xx.xx.xx.xx - - [25/Feb/2015:00:00:00 +0900] "GET /somewhereProtected/video.mp4 HTTP/1.1" 401 290 "-" "Mozilla/5.0 (iPhone; CPU iPhone OS 8_1_3 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile/12B466 Safari/600.1.4"
xx.xx.xx.xx - - [25/Feb/2015:00:00:00 +0900] "GET /somewhereProtected/video.mp4 HTTP/1.1" 401 401 "https://www.markn.org/somewhereProtected/video.mp4" "Mozilla/5.0 (iPhone; CPU iPhone OS 8_1_3 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile/12B466 Safari/600.1.4"

最初の行で401エラーが返ってBASIC認証を要求して、正しいユーザ名とパスワードの組を入力しても2行目でやはり401エラーになっています。

iOS 8のバグかも

これについては、海外のフォーラムなどでも議論されており、同様の症状を訴える人が出ています。どうもiOSのバグである可能性もあるようです。サーバ側で 401が出ているので、認証していても次のリクエストでユーザ名とパスワードを送出していないのかもしれないのですが、わかりません。

とりあえず対処法

いまのところ分かっている対処法は、.htaccessに以下を追加することです。メディアファイルが入っているディレクトリ、またはその親ディレクトリのどこかに、以下の内容を持つ.htaccessという名前のファイルを作っておきます。

<FilesMatch "\.mp4">
satisfy any
order allow,deny
allow from all
</FilesMatch>

注意

この対処ですが、mp4ファイルにアクセス制限をかけないようにするという後ろ向きの対応なのでご注意ください。mp4ファイルへの完全パスが分かってしまうと、外部から直接URLを指定することでmp4の再生が可能になってしまいます。

どういうことかというと、

/somewhereProtected/index.html

にFlowplayerへのスクリプト(最初に示したもの)を書いたとして、

/somewhereProtected/video.mp4

というメディアファイルを置いたとします。

/somewhereProtected/.htaccess

でアクセス制限をかけつつ、mp4再生対応のために上記の追加を書いたとすると、index.htmlに対してはアクセス制限がかかるのでユーザ名とパスワードが必要ですが、

http://example.com/somewhereProtected/video.mp4

というパスを知られてしまった人に直接アクセスされるとユーザ名やパスワードなしでvideo.mp4が見えてしまう、ということです。

調べた限り、現時点ではこの事象に対する完璧な対策は見つかっていません。iOS 8.1.3ではこれがないとうまく動きませんでした。

こちらもよく読まれています