自習室

こもります

FFmpegで WebM の半透過動画を作成し、Chromeで再生する

はじめに

f:id:AMANE:20141216172917j:plain

ウェブアプリで画面全体にわたるようなリッチなエフェクトを掛ける手段のひとつとして、デザイナさんに作ってもらう動画(たとえばAfter Effectsで)をそのまま使う、なんてことは出来ないかと考えてトライしてみました。

HTML要素の上に半透過の動画を <video> 要素で置くことで、もとのHTMLを動画で演出、みたいなことができています。

f:id:AMANE:20141216134814p:plain

できあがった物はこちらで確認出来ます

ブラウザは Chrome しか対応しておりません!ご注意。

環境

ちなみに、WebM を透過して表示できるのは、PC/MacChrome だけのようです。悪しからず。

Firefox@Mac だと、アルファチャンネルが捨てられて、全画面カラフルに塗りつぶされます

Safari@Mac だと、そもそも再生されません

元ネタ

今回の記事は、こちらの記事を足がかりに、追加でいろいろ調べてまとめた物になります。

動画の作り方

普段からデザイナさんに After Effects で動画を作ってもらっているので、この記事では After Effects を使ってにアルファ付き WebM 動画を作ってみます。

もしかしたら最新の After Effects では既にアルファ付き WebM の書き出しに対応しているかもしれませんが、私が使える 5.5 では出来なかったので、エンコードには FFmpeg に梱包されている vp8 (libvpx) を利用します。

f:id:AMANE:20141216152454p:plain

After Effectsコンポジション作成

新規プロジェクトから普通にコンポジションを作成し、そこに要素・アニメーションを加えていきます。半透過のテストをしたかったので、アルファが変わったり、淡いグラデーションがかかっているような動画を作ろうと思い、今回はこちらの記事を参考にサンプルを作ってみました

WebM は 60fps にも対応しているので、コンポジションのフレームレート設定を 60fpsにしました。

背景はデフォルトの黒です。

f:id:AMANE:20141216173304j:plain

After Effects でアルファ付き QuickTime Movie 書き出し

FFmpegでWebMにエンコードする元になる、アルファ付きの動画を出力します。AVI と QuickTime形式がアルファ付きに対応しているようですが、AVIだと尋常じゃない容量になるので、QuickTimeで書き出しますことにします。

対象のコンポジションを選択した状態で コンポジション > レンダーキューに追加 を選ぶと、レンダーキューウィンドウにひとつ、レンダリング処理が追加されます。

そのレンダーキューの "出力モジュール" を選択して、下記のような設定にします。ポイントは以下の3点です

  • 形式: QuickTime
  • チャンネル: RGB + アルファ
  • カラー: ストレート(マットなし)

f:id:AMANE:20141216142307j:plain

カラーを「合成チャンネル(マットあり)」 にすると、アルファチャンネルだけで無く、RGBのレイヤーも調整された動画が描き出されます。 出力された MOV ファイル単体を QuickTime で再生するときはこれで良いのですが、WebM にエンコードして他の画面に合成した際に、色味が暗い感じになってしまいます。

ストレートアルファとプリマルチプライド・アルファ(合成チャンネル)の違いは、こちらのページが詳しいです

あとは、出力先で適当に場所を決め、ファイル名を決めてレンダリングを行います。

FFmpeg で WebM にエンコード

インストール

FFmpegは別途インストールしておいてください。 Windowsの場合は、binaryをダウンロードしてきて、どこか適当な場所に解凍し、システム環境変数の path に、ffmpeg/bin のパスを通すと、コマンドプロンプト/PowerShell からコマンドをたたけるようになります。

エンコード

先ほど出力した mov ファイルのあるディレクトリに移動後、以下のコマンドでエンコードを行います。

ffmpeg -i webmtest.mov -crf 10 -b:v 1M webmtest.webm

オプションはいまいちよく理解出来ていないのですが、下記サイト様に説明が載っています。要は、オプション指定しないと結構画質が悪くなるので、VBR(可変ビットレート) の目標値 (1Mbits/s) と、VBRする際の最低品質保障 (4-63 での 10) を指定してね、という感じみたいです。

これでアルファ付きの WebM 動画ファイルが書き出されました。このファイルは、 Chrome にぽいっと投げ込むと、その場で再生してもらえます。が、背景がとくにないので真っ黒に表示され、このままでは透過できているのか分かりません。

f:id:AMANE:20141216173420j:plain

再生

というわけで、背景と適当なHTML要素を加えた上に透過動画をおいてみたのが、一番初めの作例になります。

再掲 → webm transparent test

画質優先で連番.tga を使う場合

AfterEffects から QuickTime(MOV) で書き出した時点で、圧縮率を最低にしたとしても、最終的なWebMにたどり着く前に何かしらの圧縮が入ってしまっていることになります。画質最高とは言えません。

そこで、一度無圧縮のアルファチャネル付き連番画像を書き出し、それから アルファ付き WebM をエンコードする、というパスを取ることもできます。

f:id:AMANE:20141216152504p:plain

連番 TGA 書き出し

新しいレンダリングキューを作成し、出力モジュールを以下の様に設定します。

  • 形式:Targa シーケンス
  • チャンネル: RGB + アルファ
  • カラー: ストレート(マットなし)
  • 形式オプション
    • 解像度 32bits/pixel (アルファチャネル付き)
    • 圧縮はなし!

その上でレンダリングすると、だだーっとTGAファイルが書き出されます。1920x1080、32bit ですと 1枚 8MB ほどもあるのでかなりつらい感じになります。。。

f:id:AMANE:20141216150852j:plain

連番 TGA から WebM にエンコードする

入力を、 MOV から 連番tga に変えるだけです。

ffmpeg -r 60 -i webmtest_%05d.tga -crf 10 -b:v 1M webmtest.webm

tga ファイルのサイズは膨大になりましたが、vp8 としては同じ圧縮を行うので、最終的に出てくる WebM ファイルの容量は、MOV を経由した場合と同程度になります。

さいごに

Chrome 限定な上、 WebM ってぶっちゃけそんなに流行っている気配も無いので、この手法もこれといって使えるシーンが無い可能性は大きいと思います。

けどせっかくちゃんと出来るようになったので、まとめておきました。ちゃんちゃん。