本連載は分散型マイクロブログ用ソフトウェアMisskeyの開発に関する紹介と、関連するWeb技術について解説を行っています。
今回は、Misskey v2025.
モチベーション
Webサービスにおいては、アップロードされた動画をサーバーにそのまま保存するのではなく、ストレージ節約のため非可逆的に圧縮したり、互換性向上のため再エンコードを行う、というシチュエーションは一般的です。
Misskeyでも動画の投稿が可能なので、サーバーサイドでffmpegを利用してサムネイルの生成を行うなどの処理を行っています。
しかし、サーバーサイドで動画処理を行うのは画像と比べてもはるかに負荷がかかりますし、最終的に圧縮されるとしてもユーザーはオリジナル動画をいちどアップロードする必要があり、帯域を無駄に使います。
そこでMisskeyではMediabunnyを導入し、ユーザーのブラウザ上で動画の圧縮処理を完結させるようにしました。

Mediabunny
公式サイトで
ECMAScript 2021が動く環境であればサーバー上でも動作しますが、Misskeyではブラウザ上で利用しています。
使い方は驚くほど簡単で、Misskeyに動画圧縮機能を追加するのに、UI部分などを除いたロジック部分のコードはたった50行程度の追加で済みました。
ノート
Misskeyの圧縮機能実装時のプルリクエストはGitHubを参照してください。
Mediabunny公式では動画圧縮のデモも用意されているので、実際にファイルを選んで遊んでみてください
なお、Mediabunnyは圧縮以外にも様々な動画・
実装
実際にMediabunnyを使用して動画の圧縮を行うコード例を紹介します。
import * as mediabunny from 'mediabunny';
async function compress(source: Blob): Promise<Blob> {
// 入力を準備
const input = new mediabunny.Input({
source: new mediabunny.BlobSource(source),
formats: mediabunny.ALL_FORMATS,
});
// 出力を準備。今回はmp4で出力
const output = new mediabunny.Output({
target: new mediabunny.BufferTarget(),
format: new mediabunny.Mp4OutputFormat(),
});
// 変換を行うインスタンス。今回はビットレートのクオリティをLOWにすることで、圧縮を行うように指定
const conversion = await mediabunny.Conversion.init({
input,
output,
video: {
bitrate: mediabunny.QUALITY_LOW,
},
audio: {
bitrate: mediabunny.QUALITY_LOW,
},
});
// 処理の進捗が更新されたときのコールバック。進捗率は 0.0~1.0 で渡される
currentConversion.onProgress = p => console.log(`${p * 100}%完了`);
// 圧縮処理を実行 (注: 時間がかかる場合あり)
await conversion.execute();
// 圧縮したデータを返す
return new Blob([output.target.buffer!], { type: output.format.mimeType });
}
動画データ
公式に説明がある通りTree-shakableなので、適切にimportを行えば必要なコードだけをバンドルに含めることもできます。
ノート
元動画の長さや解像度によってはそれなりに時間がかかる場合があるため、実際のプロダクトでは、ユーザーに進捗状況を表示したり、キャンセル機能を実装するのがベターでしょう。
コード例ではビットレートを決め打ちしていましたが、Misskeyではどれくらいの圧縮率で変換を行うかユーザーが設定できるようにしています。
Mediabunnyでは以下のビットレートのプリセットが用意されています。
- QUALITY_
VERY_ LOW - QUALITY_
LOW - QUALITY_
MEDIUM - QUALITY_
HIGH - QUALITY_
VERY_ HIGH
Misskey上の圧縮率設定では、高=QUALITY_
元になる動画の内容にもよりますが、それぞれの設定でどれくらい元のファイルサイズから減るかの検証結果も載せておきます。
QUALITY_ |
50%前後 |
QUALITY_ |
20%前後 |
QUALITY_ |
10%前後 |
対応ブラウザ
先進的ですが意外にもカバレッジは広く、主要ブラウザで広くサポートされています
ノート
通常気にする必要はないですが、セキュアコンテキスト
筆者は非セキュアコンテキストである.local
ドメインでローカルの開発環境にアクセスして動作確認していたのですが、期待通りに動作せず原因究明に時間を費やしてしまいました…。
まとめ
今回はMediabunnyを使ってブラウザ上で簡単に動画の圧縮を行う実装を紹介しました。WebCodecs APIの登場で、
Misskeyでは現在動画の圧縮機能でのみ使用していますが、かなりのポテンシャルを感じたので、今後活用の幅を広げたいと考えています。