モバイルブラウザでインライン再生とトラッキングができる動画プレイヤーを bower で公開する

# Getting Started

[mobile-videoplayer.js](https://github.com/yoheimuta/mobile-videoplayer.js) という動画プレイヤーライブラリを作りました

iPhone の Safari で `video` タグを使って `MP4` ファイルを再生した場合に、`動画表示領域をタップして全画面表示にしないと再生できない（= インライン再生ができない）` というのが開発のきっかけです

`GIF アニメーション`に変換すれば、インライン再生はできるようになりますが、次のような細かい制御はできなくなります

- スクロールしたときに可視範囲に入ったら自動再生して、可視範囲から出たら停止して、次に可視範囲に入ったら続きから再生するような細かい制御ができない
- 最初から再生、停止、途中から再生、1/4 再生完了、1/2 再生完了、3/4 再生完了、すべて再生完了などの動画にまつわるイベントを外部サーバーに送信するトラッキング機能がない
- 動画を読み込むまで時間がかかるので、読み込みは裏側でやるようにしてその間の表示に影響がないようにしたい
- 動画を再生し終わったあとの表示を用意できるようにしたい

こういった細かい制御のニーズは、動画を使った広告商品の開発などで要求されたりします

また、視聴に耐えられる `FPS` と`スクリーンサイズ`に変換したとしても、`GIF` という画像フォーマット上、どうしても元の `MP4` ファイルよりもサイズが大きく、かつ画質も悪くなってしまいます

これらを解決するために、`mobile-videoplayer.js` を作りました

### デモ

`GitHub Pages` にホスティングしているデモサイトは [こちら](http://yoheimuta.github.io/mobile-videoplayer.js/scroll.html)

`ファイルサイズ`は、もとの `MP4` ファイルが 3.6 MB だったのに対して、このプレイヤーで再生する画像（動画）は 2.7 MB になりました
- `FPS` は 12 で`スクリーンサイズ`は 320 x 180 に変換しています（方法は後述）
 - 同じパラメーターで変換した `GIF アニメーション`は、`FPS` 12 で`ファイルサイズ`は 7.1 MB になります（変換スクリプトは [gist](https://gist.github.com/yoheimuta/157b9dbb1d0a4adfa178) に置いてあります）
- `GIF アニメーション`よりも`ファイルサイズ`が小さくなる理由は画像フォーマットを `JPEG` 形式にしているためです

### インストール

```rb
bower install mobile-videoplayer.js
```

で落としてきた、`bower_components/mobile-videoplayer.js/dist/mvplayer.min.*.js` を使います

### MP4 ファイルを再生可能なフォーマットに変換する

このプレイヤーは、複数用意された縦長の `JPEG` 画像に対して、順番に上から下まで一定の速度で表示することで動画を再生します

`MP4` ファイルを複数の `JPEG` 画像に変換するために、[jani-strip_maker](https://github.com/shin1ohno/jani-strip_maker) を使います

- 上記のデモに使った `MP4` ファイルからは、[このような JPEG 画像](https://github.com/yoheimuta/mobile-videoplayer.js/blob/master/src/assets/tamagotchi_320x180_1.jpg) が 4 つ生成されました
- iPhone の Safari には読み込める `JPEG` 画像に制限があるため、複数の `JPEG` 画像を用意するという手間をかけています（詳細は [README](https://github.com/yoheimuta/mobile-videoplayer.js#question) を参照）
 - 基本的には、`FFmpeg` と `ImageMagick` による `MP4` ファイルからの `JPEG` 画像変換が行われています

```sh
./bin/strip_maker from_movie_to_strips --input_file ./src/assets/tamagotchi_4u.mp4 --fps 12 --height 180 --width 320
```

### 動画を再生する

[GitHub Pages に置いているデモサイト](http://yoheimuta.github.io/mobile-videoplayer.js/) の html ファイルは次の通りです

```html:index.html
<!-- https://github.com/yoheimuta/mobile-videoplayer.js/blob/master/dist/index.html より -->
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>mobile-videoplayer</title>
  <meta name="description" content="">
  <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no">

  <script src="mvplayer.min.f7bdef7c.js"></script>
</head>
<body style="margin:0">
  <!--表示コンテナ-->
  <div id="video_container">
      <div class="load-scene">
          <img src="http://placehold.it/320x180">
      </div>

      <div
          class="play-scene"
          data-frame-width=320
          data-frame-height=180
          data-fps=12
          data-did-start-url=""
          data-did-resume-url=""
          data-did-complete-url=""
          data-first-quartile-url=""
          data-midpoint-url=""
          data-third-quartile-url=""
          data-did-pause-url=""
          style="display: none;"
          >
          <div
              data-url="assets/tamagotchi_320x180_1.a9ac945e.jpg"
              class="strip"
              >
              <img>
          </div>
          <div
              data-url="assets/tamagotchi_320x180_2.d10717e2.jpg"
              class="strip"
              style="display: none;"
              >
              <img>
          </div>
          <div
              data-url="assets/tamagotchi_320x180_3.a6a03603.jpg"
              class="strip"
              style="display: none;"
              >
              <img>
          </div>
          <div
              data-url="assets/tamagotchi_320x180_4.0895f168.jpg"
              class="strip"
              style="display: none;"
              >
              <img>
          </div>
      </div>

      <div class="replay-scene" style="display: none;">
          <p>replay ?</p>
      </div>

      <div class="done-scene" style="display: none;">
          <img src="http://placehold.it/320x180">
      </div>
  </div>
  <!--スクリプトの実行-->
  <script>
    window.onload = function(){
        MVPlayer.Controller.run(document.getElementById("video_container"), true);
    };
  </script>
</body>
</html>
```

### サポートするブラウザ

次のブラウザをサポートするようにしました

- これらは実際に検証した範囲のブラウザを列挙しています
- IE6 にも対応してみました

```
IE6, IE7, IE8, Safari(7.1/8), Firefox(31), Chrome(39),
iOS Safari(iOS6, iOS7, iOS8), Android(2.2, 4.4, 5)
```

# bower に公開する

![687474703a2f2f692e696d6775722e636f6d2f516d47485067632e706e67.png](https://qiita-image-store.s3.amazonaws.com/0/24932/2a0a5821-0494-23ce-9ae7-f91bcdd07b73.png)

web に公開されている記事の中に古いものがあったり、手順で補足したい点もあったので、自分がやった手順を書きます

- 公式リファレンスは http://bower.io/docs/creating-packages/ です

### まず、bower.json を用意する

公開はしていなくても依存解決にすでに使っている人も多いと思いますが、そういう場合は単純に不足分を追記すれば良いだけです

- `ignore` は何を書くべきなのか、他のパッケージでも記述に統一感がなくて迷うかもしれません
 - 実際に確認した限り、github に公開されているファイルの中から `bower install` で取得できる必要がないものはすべて含めて良さそうです（その点で、`.gitignore` に書かれているものを含めているものがありますが、不要だと思います）

```json
{
  "name": "mobile-videoplayer.js",
  "version": "v0.0.1",
  "homepage": "https://github.com/yoheimuta/mobile-videoplayer.js",
  "description": "Web video player for mobile browser, especially for ios safari which is disabled to autoplay mp4",
  "main": [
    "dist/mvplayer.min.*.js"
  ],
  "keywords": [
    "video",
    "video player",
    "videoplayerjs",
    "mobile videoplayer",
    "mobile",
    "ios",
    "iphone",
    "mp4",
    "safari",
    "autoplay",
    "vast"
  ],
  "license": "MIT",
  "ignore": [
    "**/.*",
    "dist/assets",
    "dist/*.html",
    "spec",
    "src"
  ],
  "devDependencies": {
    "jquery": "~2.1.3",
    "jasmine-jquery": "~2.1.0"
  }
}
```

### 次に、bower.json をプッシュして、レポジトリを release する

更新した `bower.json` を含んだ v0.0.1 をリリースすることが大事なポイントです

- `bower.json` を含んでいない v0.0.1 をリリースした場合の問題は、後述します
- リリースは [github releases](https://github.com/yoheimuta/mobile-videoplayer.js/releases) で行うのが便利だと思います

### 最後に、bower に登録する

`bower register <my-package-name> <git-endpoint>` と発行するだけです

```rb
[12:59:08 great@Mac-158 mobile-videoplayer.js master]$ bower register mobile-videoplayer.js git://github.com/yoheimuta/mobile-videoplayer.js
bower mobile-videoplayer.js#*  resolve git://github.com/yoheimuta/mobile-videoplayer.js.git#*
bower mobile-videoplayer.js#* download https://github.com/yoheimuta/mobile-videoplayer.js/archive/v0.0.1.tar.gz
bower mobile-videoplayer.js#* progress received 11.8MB
bower mobile-videoplayer.js#* progress received 12.6MB
bower mobile-videoplayer.js#* progress received 12.8MB
bower mobile-videoplayer.js#* progress received 13.1MB
bower mobile-videoplayer.js#* progress received 13.4MB
bower mobile-videoplayer.js#* progress received 13.6MB
bower mobile-videoplayer.js#* progress received 13.9MB
bower mobile-videoplayer.js#* progress received 14.2MB
bower mobile-videoplayer.js#* progress received 14.6MB
bower mobile-videoplayer.js#* progress received 15.1MB
bower mobile-videoplayer.js#* progress received 15.9MB
bower mobile-videoplayer.js#* progress received 17.1MB
bower mobile-videoplayer.js#* progress received 18.7MB
bower mobile-videoplayer.js#* progress received 21.0MB
bower mobile-videoplayer.js#*  extract archive.tar.gz
bower mobile-videoplayer.js#*     invalid-meta mobile-videoplayer is missing "main" entry in bower.json
bower mobile-videoplayer.js#*     invalid-meta mobile-videoplayer is missing "ignore" entry in bower.json
bower mobile-videoplayer.js#*         resolved git://github.com/yoheimuta/mobile-videoplayer.js.git#0.0.1
? Registering a package will make it installable via the registry (https://bower.herokuapp.com), continue?: Yes
bower mobile-videoplayer.js           register git://github.com/yoheimuta/mobile-videoplayer.js

Package mobile-videoplayer.js registered successfully!
All valid semver tags on git://github.com/yoheimuta/mobile-videoplayer.js will be available as versions.
To publish a new version, just release a valid semver tag.

Run bower info mobile-videoplayer.js to list the available versions.
```

念のため、確認してみます

```rb
# 登録を確認する
[13:01:57 great@Mac-158 mobile-videoplayer.js master]$ bower search mobile-videoplayer.js
Search results:

    mobile-videoplayer.js git://github.com/yoheimuta/mobile-videoplayer.js.git

# インストールする
[13:01:46 great@Mac-158 mobile-videoplayer.js master]$ cd /tmp
[13:02:35 great@Mac-158 tmp ]$ bower install mobile-videoplayer.js
bower mobile-videoplayer.js#*   cached git://github.com/yoheimuta/mobile-videoplayer.js.git#0.0.1
bower mobile-videoplayer.js#* validate 0.0.1 against git://github.com/yoheimuta/mobile-videoplayer.js.git#*
bower mobile-videoplayer.js#~0.0.1          install mobile-videoplayer.js#0.0.1

mobile-videoplayer.js#0.0.1 bower_components/mobile-videoplayer.js
```

終わりです

### 補足1. 更新した bower.json を含んでいない v0.0.1 をリリースした場合の問題

`bower install` は、v0.0.1 リリースのレポジトリの `bower.json` を参照するため、古い `bower.json` が v0.0.1 に残っていればそれを参照してしまいます（なければ失敗すると思われます）

```rb
# ignore が完全に無視されている
[13:02:47 great@Mac-158 tmp ]$ ls -la bower_components/mobile-videoplayer.js/
total 96
drwxr-xr-x  15 great  wheel   510  4 12 13:02 .
drwxr-xr-x   3 great  wheel   102  4 12 13:02 ..
-rw-r--r--   1 great  staff   623  4 12 13:02 .bower.json
-rw-r--r--   1 great  staff    70  4 12 12:19 .gitignore
-rw-r--r--   1 great  staff   271  4 12 12:19 .jshintrc
-rw-r--r--   1 great  staff  4973  4 12 12:19 Gruntfile.coffee
-rw-r--r--   1 great  staff  5869  4 12 12:19 README.md
-rw-r--r--   1 great  staff   319  4 12 12:19 bower.json
-rw-r--r--   1 great  staff   387  4 12 12:19 coverage_server.js
drwxr-xr-x   7 great  staff   238  4 12 12:19 dist
-rw-r--r--   1 great  staff   925  4 12 12:19 package.json
drwxr-xr-x   7 great  staff   238  4 12 12:19 spec
drwxr-xr-x  13 great  staff   442  4 12 12:19 src
-rw-r--r--   1 great  staff   681  4 12 12:19 tests.mustache
-rw-r--r--   1 great  staff  2072  4 12 12:19 wercker.yml
[13:02:56 great@Mac-158 tmp ]$ ls -la bower_components/mobile-videoplayer.js/dist/
assets/                   high_fps.html             index.html                mvplayer.min.175e4cba.js  scroll.html

# 最初から bower.json を含めた v0.0.2 を公開してみて挙動を確認する -> ちゃんとできた
[13:07:52 great@Mac-158 tmp ]$ rm -r bower_components/
[13:10:53 great@Mac-158 tmp ]$ bower install mobile-videoplayer.js
bower mobile-videoplayer.js#*   cached git://github.com/yoheimuta/mobile-videoplayer.js.git#0.0.1
bower mobile-videoplayer.js#* validate 0.0.1 against git://github.com/yoheimuta/mobile-videoplayer.js.git#*
bower mobile-videoplayer.js#*      new version for git://github.com/yoheimuta/mobile-videoplayer.js.git#*
bower mobile-videoplayer.js#*  resolve git://github.com/yoheimuta/mobile-videoplayer.js.git#*
bower mobile-videoplayer.js#* download https://github.com/yoheimuta/mobile-videoplayer.js/archive/v0.0.2.tar.gz
bower mobile-videoplayer.js#* progress received 5.4MB
bower mobile-videoplayer.js#* progress received 6.2MB
bower mobile-videoplayer.js#* progress received 7.1MB
bower mobile-videoplayer.js#* progress received 8.0MB
bower mobile-videoplayer.js#* progress received 9.0MB
bower mobile-videoplayer.js#* progress received 10.1MB
bower mobile-videoplayer.js#* progress received 11.5MB
bower mobile-videoplayer.js#* progress received 13.2MB
bower mobile-videoplayer.js#* progress received 15.2MB
bower mobile-videoplayer.js#* progress received 17.2MB
bower mobile-videoplayer.js#* progress received 18.1MB
bower mobile-videoplayer.js#* progress received 19.5MB
bower mobile-videoplayer.js#* progress received 21.0MB
bower mobile-videoplayer.js#*  extract archive.tar.gz
bower mobile-videoplayer.js#* resolved git://github.com/yoheimuta/mobile-videoplayer.js.git#0.0.2
bower mobile-videoplayer.js#~0.0.2          install mobile-videoplayer.js#0.0.2

mobile-videoplayer.js#0.0.2 bower_components/mobile-videoplayer.js
[13:11:24 great@Mac-158 tmp ]$ ls -la bower_components/mobile-videoplayer.js/
total 80
drwxr-xr-x  11 great  wheel   374  4 12 13:11 .
drwxr-xr-x   3 great  wheel   102  4 12 13:11 ..
-rw-r--r--   1 great  staff   982  4 12 13:11 .bower.json
-rw-r--r--   1 great  staff  4973  4 12 13:10 Gruntfile.coffee
-rw-r--r--   1 great  staff  5869  4 12 13:10 README.md
-rw-r--r--   1 great  staff   679  4 12 13:10 bower.json
-rw-r--r--   1 great  staff   387  4 12 13:10 coverage_server.js
drwxr-xr-x   3 great  staff   102  4 12 13:11 dist
-rw-r--r--   1 great  staff   925  4 12 13:10 package.json
-rw-r--r--   1 great  staff   681  4 12 13:10 tests.mustache
-rw-r--r--   1 great  staff  2072  4 12 13:10 wercker.yml
[13:11:31 great@Mac-158 tmp ]$ ls -la bower_components/mobile-videoplayer.js/dist/
total 24
drwxr-xr-x   3 great  staff   102  4 12 13:11 .
drwxr-xr-x  11 great  wheel   374  4 12 13:11 ..
-rw-r--r--   1 great  staff  8209  4 12 13:10 mvplayer.min.175e4cba.js
```

### 補足2. 公開した bower コンポーネントの更新手順

どうやるのかの、公式リファレンスが見つかりませんでした

- http://bob.yexley.net/creating-and-maintaining-your-own-bower-package/ を読むと、`bower.json` の `version` を更新して、新しいバージョンのレポジトリをリリースすれば勝手にやってくれるとのこと

試してみたところ、確かに勝手にやってくれました

- https://github.com/yoheimuta/mobile-videoplayer.js/commit/f5b1ba2841b095b985917a796b13ac347a389b2b をコミット
- https://github.com/yoheimuta/mobile-videoplayer.js/releases/tag/v0.0.2 をリリース
- 以上で終わりです