28
26

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

モバイルブラウザのビデオ再生でアプリキャッシュが使えるかを再度検証

Last updated at Posted at 2014-09-04

(2016/7/25): 最近のChromeやSafariでのアップデート関連を新しい記事にまとめてみました。

モバイルブラウザでは、<video>タグを使ってビデオの再生を行うとき、ユーザに無断でダウンロードを開始して通信料金が過剰にかからないようにするために、preload属性を指定しても無効になるようになっています。

ですが、ユーザが再生を開始するためにボタンをクリックしてからバッファリングを開始するのではなく、先にダウンロードを始めておいて、ユーザが操作するときにはダウンロードが完了していて、ボタンをタップすれば即座に再生が開始される、といった動作を実現させたい場合もあるのではないでしょうか。

そこで、第一歩目として、HTML5のアプリケーションキャッシュが本当に<video>タグで上手く活用できないのか、iOSとAndroidで検証してみたいと思います。

とりあえず、やってみた

sample.html
<!DOCTYPE html>
<html manifest="cache.manifest">
  <head>
    ...
    (中略)
    ...
  </head>
  <body>
    <video controls>
      <source src="video.mp4">
      <source src="video.webm">
    </video>
  </body>
</html>
cache.manifest
CACHE MANIFEST
# version 0.1
sample.html
video.mp4
video.webm

単純に、このような感じでマニフェストを用意して、iOSのSafariやAndroidの標準ブラウザ、Chrome、Firefoxで再生してみると...、<video>タグはキャッシュを完全に無視して、最初からバッファリングを開始して再生しようとしてしまいます。

本当にキャッシュされないのか?

実は、マニフェストが無視されるわけではなく、キャッシュ自体は機能しているようで、ブラウザには読み込まれるにもかかわらず、<video>タグは無視して自らコンテンツをダウンロードしようとする、ということのようです。

少し細工してみた

それならば、HTML上では<video>タグの再生ファイルの場所を明示せず、キャッシュが完了してからJavaScriptでファイルの場所を与えてやるとどうなるか、確かめてみます。

sample.html
<!DOCTYPE html>
<html manifest="cache.manifest">
  <head>
    ...
    (中略)
    ...
    <script src="cache.js"></script>
  </head>
  <body>
    <video id="video" controls></video>
  </body>
</html>
cache.js
function setVideo() {
  var v = document.getElementById('video');
  v.src =
    (v.canPlayType('video/mp4; codecs="avc1.640029,mp4a.40.2"') == 'probably') ?
      'video.mp4' : 'video.webm';
}

function update() {
  var c = window.applicationCache;
  if(c == c.UPDATEREADY) {
    c.swapCache();
    setTimeout(function() {
      location.reload();
    }, 2000);
  }
}

window.addEventListener('load', function() {
  var c = window.applicationCache;
  c.addEventListener('cached', setVideo, false);
  c.addEventListener('noupdate', setVideo, false);
  c.addEventListener('updateready', update, false);
}, false);

で、マニフェストも更新。

cache.manifest
CACHE MANIFEST
# version 0.2
sample.html
video.mp4
video.webm

コードは適当なので多少間違いや不備があるかもしれませんが...
さて、このようにするとどうなったかといいますと...

  • iOS Safariの場合、再生ボタンをタップすると、キャッシュされた動画が即座に再生されます。
  • Android (標準ブラウザ、Chrome、Firefox)の場合、依然として、キャッシュが無視され、一からバッファリングをやり直して再生しようとします。

以上、まとめ

そういうわけで、iOS Safariでは、キャッシュが完了してから、src属性にファイルの場所をJavaScriptで後から指定してやると、キャッシュを参照して再生してくれる、ということになるようです。しかし、Androidではどうあがいてもキャッシュから動画を再生してくれない、ということにもなってしまいます。

そうなると、Androidでは他に手立てはないのだろうか、ということになりますが...続きは次の機会に。

28
26
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
28
26

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?