6
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Zoom の文字起こし・翻訳 AI を "Zoom 以外" で使う — Google Meet / Teams / YouTube、どんなサイトでもリアルタイム字幕+翻訳

6
Last updated at Posted at 2026-07-08

Zoom の文字起こし・翻訳 AI を "Zoom 以外" で使う — Google Meet / Teams / YouTube、どんなサイトでもリアルタイム字幕+翻訳

「Zoom の会議 AI は Zoom の中でしか使えない」——そう思っていませんか?

今年登場した Zoom AI ServicesScribe(文字起こし)Translator(翻訳) は、Zoom 会議に紐づかない ただの REST API です。つまり音声さえ取れれば、Google Meet でも Teams でも YouTube でも、Zoom の高精度 AI で字幕&翻訳ができます。

本記事では、OSS のリアルタイム翻訳アプリ Sokuji(Chrome 拡張・GitHub 921★) に Zoom AI Services を実際に組み込み、"どんなサイトでも動く" ようにした実装と、公式ドキュメントに載っていないハマりどころを全部公開します。

Google Meet 上で日本語→英語のリアルタイム字幕

↑ これは Google Meet です。でも字幕と翻訳は Zoom の AI が動かしています。


対象読者 / 先に結論

対象読者:ブラウザ拡張から外部の AI API を叩きたい人、Zoom AI Services を実プロダクトに組み込みたい人。

そして本記事の実装で ハマった 4 つの罠を先にまとめておきます(詳細は各章)。ここだけでも持ち帰ってもらえれば、同じ所で溶けずに済みます。

  1. 認証 は Build Platform の API Key/Secret から HS256 JWT を自作する(Marketplace の OAuth とは別系統)
  2. file は data-URI(生 base64 は 400 UNSUPPORTED_MEDIA
  3. 翻訳ペアは片側が必ず英語ja→zh は弾かれる)
  4. 拡張は host_permissions で CORS を越える(CSP の connect-src だけでは足りない)

1. なぜ "Zoom 以外" で動くのか

まずここが本記事のキモです。Zoom の AI には、混同しやすい 2 種類があります。

使える場所 実体
AI Companion Zoom 会議の中だけ 会議機能の一部
AI Services API(Scribe / Translator / Summarizer) どこでも ただの REST API

Scribe は「音声 → テキスト」、Translator は「テキスト → テキスト」。どちらも https://api.zoom.us/v2/aiservices/... への普通の POST にすぎません。音声のソースが Zoom である必要はないのです。

だから、ブラウザ拡張でタブ音声やマイク音声を拾って API に流せば、Google Meet だろうと YouTube だろうと、Zoom の AI で字幕・翻訳ができる——というわけです。


2. 全体アーキテクチャ

拡張のサイドパネル
  → タブ / マイク音声(PCM)
    → VAD で発話を区切る(Silero VAD)
      → 発話を WAV(data-URI) 化 → Scribe(文字起こし)
        → Translator(翻訳)
          → 画面に字幕オーバーレイ

ポイントは VAD(音声区間検出)で「1 発話ずつ」区切ること。Scribe はストリーミングではなく ファイル単位の同期 API(Fast モード) なので、「話し終わった 1 文」を送って結果を受け取る 準リアルタイム方式にしています。1 発話あたりの往復はおよそ 2 秒です。

プロバイダー選択に "Zoom AI Services"


3. 認証:$20 無料クレジットと Build Platform の JWT(ハマり①)

最初の関門が認証です。Zoom AI Services の認証は、Marketplace の普通の OAuth アプリとは別系統でした。

  • 使うのは Zoom Build PlatformAPI Key / API Secret
  • これを使って HS256 の JWT を自分で署名し、Authorization: Bearer <jwt> で投げます。
  • $20 の無料クレジットは、開発者ポータルの Plans & Billing → Zoom Build Platform(旧 Zoom SDK Universal Credit) の無料トライアルから。※ Build Platform は新規/独立アカウントが必要な点に注意。

JWT はブラウザ内で Web Crypto を使って署名できます(BYOK・クライアント署名)。

// API Key / Secret から HS256 JWT を作る(iss = API Key)
async getToken(): Promise<string> {
  const now = Math.floor(Date.now() / 1000);
  const iat = now - 30, exp = iat + 7200;
  const header  = base64urlString(JSON.stringify({ alg: 'HS256', typ: 'JWT' }));
  const payload = base64urlString(JSON.stringify({ iss: this.apiKey, iat, exp }));
  const signingInput = `${header}.${payload}`;

  const key = await crypto.subtle.importKey(
    'raw', new TextEncoder().encode(this.apiSecret),
    { name: 'HMAC', hash: 'SHA-256' }, false, ['sign'],
  );
  const sig = await crypto.subtle.sign('HMAC', key, new TextEncoder().encode(signingInput));
  return `${signingInput}.${base64url(new Uint8Array(sig))}`;
}

💡 Marketplace の Server-to-Server OAuth(Account ID + Client ID/Secret)でも通ると案内されますが、実際に AI Services を叩くと Build Platform の API Key/Secret + JWT が確実でした。ここで認証方式を取り違えると延々ハマります。


4. 音声の渡し方:生 base64 では通らない。data: URI が正解(ハマり②)

transcribefile フィールドに ただの base64 文字列を入れると、こう返ってきます。

{ "code": 400, "reason": "UNSUPPORTED_MEDIA",
  "message": "File extension \"\" is not supported. Supported: .m4a, .mp3, .mp4, .wav, .webm" }

正解は data-URIdata:audio/wav;base64,<bytes> にすると 200 で正しく文字起こしされます(公式サンプルは公開 URL を渡していますが、バイトを直送するなら data-URI が必要)。

export async function transcribe(token, wavDataUri, language) {
  const json = await post('/scribe/transcribe', token, {
    file: wavDataUri,                       // ← "data:audio/wav;base64,..." が必須
    config: { language, word_time_offsets: true },
  });
  return json?.result?.text_display ?? '';
}

💡 実は自動レビュー bot に「生 base64 が正しいのでは」と指摘されたのですが、実 API で叩いて検証すると data-URI が必須でした。ドキュメントより実測、です。


5. 翻訳の制約:ペアの片側は必ず英語(ハマり③)

Translator には強い制約があります。言語ペアのどちらか一方が英語でなければならないのです。

  • ja → zh(日本語→中国語)を投げると 400 "one side must be English"
  • en ↔ X の形だけが通ります(ja → enen → zh など)。

なので Sokuji 側では「英語を軸にした非対称の言語マトリクス」で提供言語を設計しています。

export async function translate(token, text, sourceLanguage, targetLanguage) {
  const json = await post('/translator/translate', token, {
    text,
    config: { source_language: sourceLanguage, target_languages: [targetLanguage] },
  });
  return json?.result?.translations?.[targetLanguage] ?? '';
}

💡 おまけの実測:pt-PTpt-BR も現状 500 が返りました(zh-CN / ko-KR / fr-FR は 200)。対応言語は必ず実際に叩いて確かめるのが安全です。

言語ペア設定(source: 日本語 / target: English)


6. 拡張で CORS を越える:CSP だけでは足りない。host_permissions(ハマり④)

拡張から api.zoom.usfetch すると CORS エラーになります。これは "プロバイダーを追加したときの定番の罠" でした。

  • api.zoom.us は寛容な Access-Control-Allow-Origin を返しません。
  • CSP の connect-src に足すだけでは不十分。Manifest V3 では host_permissions に追加して初めて、拡張ページからの cross-origin fetch が CORS を越えられます。
"host_permissions": [
  "...",
  "https://api.zoom.us/*"   //  これが無いと translator/translate  CORS エラー
]

OpenAI や Gemini は寛容な CORS を返すため connect-src だけで動きますが、Zoom はそうではありません。ここは API ごとに違うので要注意。


7. どのサイトで動く?

Sokuji の content script は Google Meet / Microsoft Teams / Zoom(Web) に注入され、サイドパネルは どのページでも開けます。音声は タブ音声 or マイクから取得するので、YouTube などの動画にも字幕を出せます。

Google Meet 上のリアルタイム字幕オーバーレイ

「Zoom の AI を YouTube の日本語動画に当てて英語字幕を出す」——字面だけ見ると矛盾していますが、REST API なら普通にできてしまいます。

YouTube の日本語動画に Zoom AI で英語字幕

↑ ここは YouTube。Zoom は 1 ミリも開いていませんが、Zoom の AI が字幕を出しています。


8. レイテンシとコスト(実測)

項目 実測値
1 発話(3–7 秒)の端到端 約 2.0–2.7 秒(Scribe 約 1.4–2.5s + Translator 約 0.6–0.8s)
Scribe 料金 $0.0033 / 分($20 で約 100 時間
対応ソース言語(Scribe) en-US / zh-CN / ja-JP / es-ES / it-IT

ストリーミングではないので "喋りながら 1 文字ずつ" は出ませんが、1 発話ごとの準リアルタイム字幕としては十分実用的でした。


9. まとめ

  • Zoom AI Services は "Zoom 専用" ではない。 Scribe / Translator は REST API なので、拡張に載せれば どんなサイトの音声でも字幕+翻訳にできる。
  • 実運用のカギは 4 つのハマりどころ:
    1. Build Platform の API Key/Secret + HS256 JWT(Marketplace OAuth とは別系統)
    2. file は data-URI(生 base64 は 400)
    3. 翻訳ペアは片側が英語
    4. 拡張は host_permissions で CORS 越え
  • 実装は OSS の Sokuji に入っています。$20 の無料クレジットで今すぐ試せます。

🔗 GitHub:https://github.com/kizuna-ai-lab/sokuji

6
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?