アルファチャンネル付き動画をvideoタグで読み込む

# 概要
アルファチャンネル付き動画を、videoタグで読み込みたい。
iOSは`H.265(mp4)`、それ以外は`VP9(webm)`であれば、アルファチャンネル付き動画をブラウザで再生できるので、それぞれファイルを用意する。

次のような手順でうまくいった。

1. After Effectsでアルファチャンネル付きのmovを書き出す
2. 1のmovをffmpegを使ってVP9のwebmに変換
3. 1のmovをShutter Encoderを使ってH.265のmp4に変換
4. 2と3のファイルをvideoタグから読み込む


### ホントにこの２つでいいのか？
念のため[caniuseのwebmの項目](https://caniuse.com/webm)をみると、webm形式に対応していないブラウザは２つ。
１つはSafari on iOS。webmの再生自体は出来るがVP9形式がデフォルトでオフになっているため透過できない模様。
もう１つはOpera Mini。まあええかの精神でこの記事では扱わない。

# After Effectsから書き出し
出力モジュールを `ロスレス圧縮（アルファ付き）` にして書き出す。


### 補足
After Effectsからの書き出し時、オプションを変更しないとダメと書いてある記事があったが、とくにデフォルト設定から変えなくても問題なかった。

# ffmpegでwebm(VP9)に変換
After Effectsで書き出したmovを、ffmpegでVP9コーデックのwebmに変換する。
ffmpegのインストールは[こちらの記事](https://qiita.com/umi_kappa/items/1f51da746f04978d4957)を参考にした。

```
ffmpeg -i input.mov -c:v libvpx-vp9 -crf 10 -b:v 1M output.webm
```

### パラメータの意味
 [Googleの記事](https://developers.google.com/media/vp9/bitrate-modes#vp9_bitrate_modes)を参考に、オプションの意味をまとめた（が、自信はない）：


|パラメータ|意味|
|---|---|
|-i input.mov|入力ファイル名|
|-c:v libvpx-vp9|vp9を使うことを明示|
|-crf 10|最高品質レベルを設定します。有効な値は 0 ～ 63 です。数値が小さいほど品質が高くなります|
|-b:v 1M|制限品質（CQ）モードの指定。目標ビットレートを1MBpsとする。|
|output.webm|出力ファイル名|

# Shutter Encoderでmp4(H.265) に変換
[この記事](https://supergeekery.com/blog/transparent-video-in-chrome-edge-firefox-and-safari-circa-2022)を参考に、[Shutter Encoder](https://www.shutterencoder.com/)で変換する

### v15.7をインストール
何故か最新(16.4)だとうまくいかなかったので、記事に従って[old versions](https://www.shutterencoder.com/old%20versions/)からv15.7のものをインストールした。

## 変換
[記事](https://supergeekery.com/blog/transparent-video-in-chrome-edge-firefox-and-safari-circa-2022)中腹の `Cre­at­ing an H.265 ver­sion of the video, and not an H.264 video` の画像の説明に従い、次のような設定をした上で  `Choose files` から変換したいファイルを選び、 `Start function` を押下すると変換される。
- `Choose function` : `H.265`  を選択
- `Ext`: `mp4` を選択
- `Hardware acceleration`: `OSX VideoToolbox` を選択
- `Enable alpha channel` をチェック

# HTMLタグ
こんな感じの関数で作ったvideoのdomを動的に挿入する。

```Javascript
const gen_video_tag = () => {
    const filename = './path/to/filename';

    // 基本はwebmを読み込む
    let src = `${filename}.webm`;
    let type = 'video/webm';

    // iOSだけmp4
    const isIOS = /iP(hone|(o|a)d)/.test(navigator.userAgent)
    if (isIOS) {
        src = `${filename}.mp4`;
        type = "video/mp4;codecs=hvc1";
    }

    const raw = `<video muted playsinline autoplay loop src="${src}" type="${type}"></video>`;

    // stringをhtmlとしてパースし、videoタグだけ返却
    const parser = new DOMParser();
    const html = parser.parseFromString(raw, 'text/html');
    return html.querySelector('video');
}
```

### なんでJS？
もちろん、最初は↓こんな感じでsourceでの出し分けで良いと思ったのだが、iOSでmp4が再生されなかった。

```html
<video muted playsinline autoplay loop>
  <source src="hoge.mp4" type="video/mp4;codecs=hvc1">
  <source src="hoge.webm" type="video/webm">
</video>
```

↓こうだとiOSでもmp4が再生される不思議。もう考えることをやめ、UAで出し分けることにした。

```html
<video muted playsinline autoplay loop src="hoge.mp4" type="video/mp4;codecs=hvc1" />
```

# 参考記事
- [FFmpegで WebM の半透過動画を作成し、Chromeで再生する](https://izmiz.hateblo.jp/entry/2015/01/09/214817)
- [FFmpegを使って動画をWebMへ変換する手順](https://qiita.com/umi_kappa/items/1f51da746f04978d4957)
- [Video with trans­paren­cy in Chrome, Edge, Fire­fox, Safari, iOS and Android, cir­ca 2022
](https://supergeekery.com/blog/transparent-video-in-chrome-edge-firefox-and-safari-circa-2022)
- [ffmpeg コマンドラインツール入門 第1回](https://techblog.morphoinc.com/entry/2020/07/13/100058)

# 追記 Shutter Encoderなしでアルファ付きH.265変換
Shutter Encoderを使わずにターミナルからH.265の変換する方法を見つけたので追記。

結論としてはShutter Encoder v15.7にビルトインされているバージョンのffmpegを使い、Shutter Encoder内のコンソールから拾ったコマンドを実行する。
ので、↑の手順をやった前提で書きます。

たぶん[ffmpegのソースコード](https://github.com/FFmpeg/FFmpeg)から色々設定してコンパイルすれば同じことができるんじゃないかと思うが、難しそうだったので試していない。

### Shutter Encoder内のffmpegのパスを調べる

私の場合は下記にあった。
```
/Applications/Shutter\ Encoder.app/Contents/Resources/Library/ffmpeg
```

ターミナルから楽に実行できるようにしたいのでaliasを作っておく。
```~/.bashrc
alias ffmpeg2='/Applications/Shutter\ Encoder.app/Contents/Resources/Library/ffmpeg'
```


### Shutter Encoderでコマンドをコピペする
Shutter Encoderを開き、↑の方でした設定を済ませておく
ウィンドウ左下のProgress statusを右クリックするとShow consoleできるので、ここからコンソールを開き、実行しているコマンドをコピペする。

![スクリーンショット 2022-10-24 20.57.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/949694/938de5e1-b5e5-e2a4-5442-451da72be97e.png)


### コマンドを整形して実行する
拾ってきたコマンドを色々整理すると大体こんな感じになった。一件落着。

```bash
ffmpeg2\
    -hwaccel none\
    -i input.mov\
    -c:v hevc_videotoolbox\
    -alpha_quality 1\
    -b:v 1M\
    -pix_fmt yuva420p\
    -tag:v hvc1\
    -y output.mp4
```