Free AI Video Upscaler が WebGPU と WebCodecs を使用して、サーバー費用をゼロに抑えながら 25 万人の MAU にサービスを提供する方法

公開日: 2026 年 3 月 5 日

Sam Bhattacharyya は、2023 年に Free AI Video Upscalerオープンソースの趣味のプロジェクトとして最初に構築しました。予想外に自然な形で成長し、月間アクティブ ユーザー数(MAU)は 25 万人(2026 年 2 月時点)に達しました。これは、プロジェクトがクライアントサイドの AI 処理で構築されており、サーバー処理の費用がゼロであるためです。ソフトウェアのインストールやログインを必要とせずに、ブラウザで動画を補正できます。

このドキュメントでは、WebGPU と WebCodecs を使用して、アプリケーションに無料のクライアントサイド処理を追加する方法について説明します。

Free AI Video Upscaler の概要。
Free AI Video Upscaler の概要。

サーバー費用の課題

以前の職務では、数百万人のユーザーが利用するブラウザベースのライブ ストリーミング ツールの AI インフラストラクチャを管理していました。サーバーサイドで動画を処理するための予算コストが大きかったため、

サーバーサイドの動画処理が予算の 20% を占めていました。これは、給与に次ぐ同社の大きな変動費でした。文字起こし、音声、動画の補正などの AI 機能ごとに、チームは新しい実装に対して厳しい予算要件(動画 1 時間あたり 0.1 ドル)に直面しました。

クライアントサイド AI は唯一の例外で、仮想背景やバックグラウンド ノイズの除去などの機能は、社内のクライアントサイド SDK を使用して実装されました。これらの AI 機能では、モデル推論と動画処理がユーザーのデバイスで行われたため、サーバー処理費用は発生しませんでした。

WebCodecs などの API を使用すると、ブラウザで本格的な動画編集スイートを含む完全な動画処理パイプラインを構築できます。WebGPU により、クライアントサイドの AI が大幅に効率化されます。

WebCodecs と WebGPU を使用したクライアントサイド処理

Free AI Video Upscaler は、オープンソースの WebSR SDK を使用しています。この SDK は、画像を受け取り、アップスケールして、結果をキャンバスに描画します。

超解像ニューラル ネットワークは、ソース画像から画像の特徴を抽出するために、画像の畳み込み(行列乗算)を繰り返し適用してアップスケーリングを行います。これらの画像特徴にさらに畳み込みを適用して、最終的な高画質の画像を再構成します。

超解像プロセスの図。
超解像プロセスの図。

WebSR は、これらのニューラル ネットワークの畳み込みレイヤを WebGPU コンピューティング シェーダーとして実装します。たとえば、レイヤの例完全なネットワークをご覧ください。レンダリング メソッドを呼び出すと、SDK はアップスケーリング ネットワークの各レイヤを実行し、最終的な画像をキャンバスに出力します。詳しくは、ニューラル ネットワークの実装をご覧ください。

import WebSR from "https://esm.sh/@websr/websr@0.0.15";

const gpu = await WebSR.initWebGPU();
const canvas = document.getElementById("canvas");

const websr = new WebSR({
  network_name: "anime4k/cnn-2x-l",
  weights: await (
    await fetch("https://katana.video/files/cnn-2x-lg-2d-animation.json")
  ).json(),
  gpu,
  canvas,
});

const img = document.getElementById("source");
const bitmap = await createImageBitmap(img);

await websr.render(bitmap);

Codepen の WebSR SDK の例をご覧ください。

MediaPipe や TensorflowJS などのフレームワークを使用して、WebSR SDK を任意のモデルに置き換えることができます。動画処理パイプラインは WebCodecs を使用し、トランスコーディング パイプラインとして構造化されています。

トランスコーディング パイプラインを示すフローチャート。
トランスコーディング パイプラインを示すフローチャート。

パイプラインは複数のステージに分割されます。

  1. デマルチプレクス: File オブジェクトからエンコードされた動画チャンクを読み取ります。
  2. デコード: エンコードされたチャンクを VideoFrame オブジェクトにデコードします。
  3. 処理: 入力 VideoFrame をアップスケールされた VideoFrame に変換します。
  4. エンコード: アップスケールされた VideoFrame オブジェクトを新しいエンコードされたチャンクにエンコードします。
  5. 多重化: エンコードされた出力チャンクを出力ファイルに書き込みます。

パイプラインは Streams API を使用します。エンコード、デコード、デマルチプレクス、マルチプレクスはストリームとして実装されます。デモでは、プロジェクトは webcodecs-utils ライブラリの多重化ユーティリティとストリーム ユーティリティを使用します。このライブラリは、VideoEncoderVideoDecoderストリーミング ラッパーを提供します。

import {
  SimpleDemuxer,
  VideoDecodeStream,
  VideoProcessStream,
  VideoEncodeStream,
  SimpleMuxer,
} from "https://esm.sh/webcodecs-utils";

import WebSR from "https://esm.sh/@websr/websr@0.0.15";

// Fetch demo video
const arrayBuffer = await (
  await fetch("https://katana.video/files/hero-small.mp4")
).arrayBuffer();
const videoFile = new File([arrayBuffer], "hero-small.mp4", {
  type: "video/mp4",
});

// Initialize WebGPU and WebSR
const gpu = await WebSR.initWebGPU();
const weights = await (
  await fetch("https://katana.video/files/cnn-2x-lg-2d-animation.json")
).json();
const websr = new WebSR({
  network_name: "anime4k/cnn-2x-l",
  weights,
  gpu,
  canvas,
});

// Set up demuxer
const demuxer = new SimpleDemuxer(videoFile);
await demuxer.load();
const decoderConfig = await demuxer.getVideoDecoderConfig();

const encoderConfig = {
  codec: "avc1.4d0034", // https://webcodecsfundamentals.org/codecs/avc1.4d0034.html
  width: 640,
  height: 360,
  bitrate: 1000000,
  framerate: 30,
};

// Set up muxer
const muxer = new SimpleMuxer({ video: "avc" });

// Build the upscaling pipeline
await demuxer
  .videoStream()
  .pipeThrough(new VideoDecodeStream(decoderConfig))
  .pipeThrough(
    new VideoProcessStream(async (frame) => {
      // AI upscale with WebSR
      await websr.render(frame);
      const upscaledFrame = new VideoFrame(canvas, {
        timestamp: frame.timestamp,
        duration: frame.duration,
      });

      return upscaledFrame;
    }),
  )
  .pipeThrough(new VideoEncodeStream(encoderConfig))
  .pipeTo(muxer.videoSink());

// Get output
const blob = await muxer.finalize();

Codepen でパイプライン全体をご覧ください。

Streams API は、WebCodecs で特に役立ちます。これは、エンコードなどの 1 つのステージが過負荷になった場合、バックプレッシャーを使用してデコードなどのアップストリーム ステージを自動的に減速するためです。これにより、メモリの問題を回避し、効率を向上させることができます。

これにより、ユーザー エクスペリエンスがシンプルになります。

  1. ファイル入力を使用して動画をアップロードします。
  2. システムは動画をローカルで処理します。
  3. 結果は Blob としてダウンロードできます。

詳しくは、WebCodecs でトランスコード パイプラインを構築するをご覧ください。GitHub で、400 行未満のコードで構成された Free AI Video Upscaler の完全な処理パイプラインを確認することもできます。

結果

Free AI Video Upscaler の唯一のプロモーションは、1 件の Reddit 投稿でした。それにもかかわらず、ユーザーがフォーラムでツールを共有したことによる口コミのおかげで、月間アクティブ ユーザー数は 25 万人にまで自然に増加し、前月比 32% の成長率を達成しました。

    250,000

    1 か月のアクティブ ユーザー

    10,000

    1 日あたりに処理される動画数

    30,000

    1 か月あたりの動画の処理時間

    0 $

    サーバー処理費用

1 日あたり 10,000 本の動画(1 か月あたり 30,000 時間の動画)を処理し、サーバー費用はゼロです。

無料の AI 動画アップスケーラーは、有料の AI アップスケーリング サービスのリード生成ツールとして機能します。このサービスも、サーバーサイドで実行されるより強力な AI モデルを使用して構築しました。このアプローチでは、マーケティングを行わずに収益性を高めながら、初期のアプリケーションは無料のオープンソースのまま維持されます。

推奨事項とリソース

WebCodecs と WebGPU の前は、動画処理を多用するアプリケーションには、面倒なデスクトップ ソフトウェアか、コストのかかるサーバーサイド処理が必要でした。サーバー費用は、動画アプリケーションの運用費用の大部分を占めることがよくありました。

これらのブラウザ API を使用すると、効率的なクライアントサイドの動画処理アプリケーションを構築できます。これらのアプリケーションは、デスクトップ ソフトウェアよりも直感的で、摩擦が少なく、サーバーサイド処理よりも手頃でスケーラブルです。

WebCodecs と、Free AI Video UpscalerKatana などの動画アプリケーションの構築方法について詳しくは、WebCodecsFundamentals をご覧ください。本番環境と実装の詳細に焦点を当てて、本番環境の WebCodecs アプリケーションを構築する方法を学びます。