ffmpeg.wasm を使ってGIF動画を作れるWebアプリを作って遊んでみた

公開:2020/12/17
更新:2020/12/17
3 min読了の目安(約3400字TECH技術記事

これは コネヒト Advent Calendar 2020 18日目 の記事です。

はじめに

コネヒト社で定期的に開催しているフロントエンドの勉強会(※) で、FFmpeg が WebAssembly で使えるという情報を耳にしたので、遊びがてらブラウザだけで動画をGIFに変換するWebアプリを作ってみました。
(※コロナでリモートワークになってから、ランチではなくおやつタイムにやっています)

ffmpeg.wasm の公式リポジトリと日本語の解説記事はこちらです。


作ったWebアプリ

ソースコードはこちら。

Google Chrome だけ動作確認をしています。他のブラウザは使えません。 また大きな動画ファイルを変換すると途中でエラーになります。
(これらの理由は「ハマりどころ」の章をご覧ください)

使用方法

大したアプリではないですが一応手順を説明します。
How to use

  1. 動画ファイルを選択
  2. 出力するGIFのフレームレートを設定
  3. Convert to GIF をクリック
  4. (GIFをダウンロードしたい場合)Download GIF をクリック

使ったもの

FFmpeg.wasm の使い方

普通に <script> タグでインポートして、

<script src="https://unpkg.com/@ffmpeg/ffmpeg@0.9.4/dist/ffmpeg.min.js"></script>

通常のFFmpegと同様の引数を文字列で渡してあげればOKです。

await ffmpeg.run(
  '-i', '(file name)',
  '-r', '(frame rate)',
  'output.gif'
);

ただしロードなどの手順は必要になります。
その辺りは公式ドキュメントの USAGE に詳しく書かれていますので、こちらを参照してみてください。
ファイルの扱いもちょっと面倒な感じですが、FFmpeg と同じ感じで使えるのは良いですね。

ハマりどころ

npm 経由でインストールしたパッケージはブラウザで使えない

いつもの癖で npmjs.com で配布されているパッケージを使おうとしたら、ビルド時にエラーになりました。
こちらは Node.js 用のパッケージのようです。

READMEにも、ブラウザの場合は <script> で読み込むように書かれています。
(ちゃんとドキュメントは読まないといけませんね)

README

Next.js で直接参照はできないので、私はこんな感じで使っています。

const getFFmpeg = () => {
  if (('FFmpeg' in window) && ('SharedArrayBuffer' in window)) {
    return window.FFmpeg;
  }
  throw new Error('FFmpeg がロードできません')
}

SharedArrayBuffer が使えないブラウザでは変換できない

Installation のところに書かれていたのですが、SharedArrayBuffer が使えないブラウザでは実行できないようです。

Only browsers with SharedArrayBuffer support can use ffmpeg.wasm, you can check HERE for the complete list.

Can I Use SharedArrayBuffer?
https://caniuse.com/?search=SharedArrayBuffer

FireFox も対応しているように見えるのですが、制限があるため使えないようです。
Edge は試していないですが、Chromium ベースなら使えるのかも?(未検証)

大きなファイルを扱えない

オンメモリでしか動かないようなので、容量の大きなファイルだと変換できないです。
ffmpeg error

今回は短い動画でGIFアニメーションを作っていたので、問題にならなかったようです。

感想

WebAssembly に興味があって触ってみたのですが、全然中身が分からなくても使えてしまった、というのが正直な感想です。
逆に言えば、きちんと提供する側で用意しておけば、利用する側はあまり意識しなくても使えるんだなー、ということでもあるとは思います。

FFmpeg.wasm については、対応ブラウザが少ないことや、ブラウザだけで動画変換ができるけどオンメモリなので用途が現時点では限られそう、という感じでした。
しかし、ブラウザだけでできることがどんどん増えているなー、という感じがしてWebエンジニアとしては嬉しく思います。

次はWASMでなにか作ってみたい。