🎤

TTS (Azure) - Remotion テンプレート 解説

に公開

本ドキュメントは、Remotion TTS Exampleプロジェクトの包括的な技術資料です。

リンク


目次

  1. プロジェクト概要
  2. 実際の動作実行手順
  3. TTS処理フローの詳細解説

プロジェクト概要

概要

TTS (Azure) - テキストを音声化された動画に変換するテンプレートです。音声合成にはAzure Cloudと連携します。

このプロジェクトは、Remotionを使用してText-to-Speech(TTS)機能を持つビデオを生成するサンプルアプリケーションです。Azure Cognitive Services Speech APIでテキストを音声に変換し、AWS S3に保存してからRemotionで動画を生成します。

このプロジェクトはRemotionの公式テンプレートとして提供されており、FelippeChemelloによって開発・メンテナンスされています。

技術スタック

  • フロントエンド: React, TypeScript
  • 動画生成: Remotion
  • TTS: Azure Cognitive Services Speech SDK
  • ストレージ: AWS S3
  • バリデーション: Zod
  • その他: MD5(ファイル名ハッシュ化)

プロジェクト構造

src/
├── HelloWorld.tsx          # メインコンポーネント(動画表示)
├── HelloWorld/
│   └── Title.tsx          # アニメーション付きタイトル表示
├── Root.tsx               # Remotion Root コンポーネント
├── tts.ts                 # TTS機能の実装
├── types.ts               # 型定義とスキーマ
├── debounce.ts            # 入力待機機能
└── index.ts               # エントリーポイント

処理フロー

1. 初期化フロー

  1. Root.tsx:8-47 - Remotionコンポジションの定義
  2. types.ts:4-13 - 環境変数の読み込みと検証
  3. types.ts:19-24 - プロパティスキーマの定義

2. TTS音声生成フロー

  1. Root.tsx:24-42 - calculateMetadata内での音声生成処理
  2. debounce.ts:3-25 - 入力待機(1秒)
  3. tts.ts:86-108 - S3に音声ファイルが既に存在するかチェック
  4. tts.ts:34-84 - 音声合成処理:
    • Azure Speech SDKでSSML形式の音声を生成
    • S3に音声ファイルをアップロード
  5. tts.ts:131-141 - S3のパブリックURLを生成

3. 動画レンダリングフロー

  1. HelloWorld.tsx:13-44 - メインコンポーネント:
    • 音声の再生
    • タイトルテキストの表示
    • フェードアウトアニメーション
  2. Title.tsx:3-52 - アニメーション付きタイトル:
    • 単語ごとのスプリングアニメーション
    • 時間差での表示制御

重要な処理部分

音声合成 (tts.ts:34-84)

export const synthesizeSpeech = async (text: string, voice: Voice): Promise<void>
  • Azure Speech SDKを使用したSSML形式の音声合成
  • 音声データのS3アップロード
  • エラーハンドリング

ファイル名生成 (tts.ts:17-25)

export const getFileName = ({ text, voice }: { text: string; voice: string }) => {
  return `${md5(`${text}--${voice}`)}.mp3`;
};
  • テキストと音声の組み合わせからMD5ハッシュを生成
  • キャッシュ機能の実現

動的メタデータ計算 (Root.tsx:24-42)

calculateMetadata={async ({ props, abortSignal }) => {
  // 音声生成とファイル時間の計算
  const duration = await getAudioDurationInSeconds(fileName);
  return { props, durationInFrames: Math.ceil(duration * 30) };
}}
  • 音声の長さに基づいた動画時間の動的計算
  • 音声ファイルの存在確認とキャッシュ

アニメーション (Title.tsx:25-48)

transform: `scale(${spring({
  fps: videoConfig.fps,
  frame: frame - i * displaySpeed,
  config: { damping: 100, stiffness: 200, mass: 0.5 },
})})`,
  • 単語ごとの時間差スプリングアニメーション
  • displaySpeedによる表示速度制御

環境設定

  • Azure: TTS_KEY, TTS_REGION
  • AWS: ACCESS_KEY_ID, SECRET_ACCESS_KEY, S3_BUCKET_NAME, S3_REGION
  • 音声: 4種類の音声(日本語ブラジル、英語)をサポート

基本的な使用方法

  1. npm run dev - プレビュー開始
  2. npm run build - 動画のビルド
  3. npx remotion render - 動画のレンダリング

実際の動作実行手順

前提条件

  • Node.js (推奨:18.x以上)
  • npm または yarn

1. 環境セットアップ

1.1 Azureアカウントの作成とTTSサービスの設定

  1. Azure Portalにアクセス
  2. 「Speech Services」を検索して作成
  3. 以下の情報を取得:
    • キー: AZURE_TTS_KEY
    • 地域: AZURE_TTS_REGION (例: eastus)

⚠️ 注意: サブスクリプションが有効になるまで時間がかかる場合があり、その間は「1006」エラーが発生する可能性があります。

1.2 AWS S3バケットの設定

  1. AWS ConsoleでS3バケットを作成
  2. バケットポリシーを設定(パブリック読み取り許可):
{
  "Version": "2008-10-17",
  "Statement": [
    {
      "Sid": "AllowPublicRead",
      "Effect": "Allow",
      "Principal": { "AWS": "*" },
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::YOUR-BUCKET-NAME/*"
    }
  ]
}
  1. CORS設定を追加:
[
  {
    "AllowedHeaders": ["*"],
    "AllowedMethods": ["HEAD", "GET", "PUT", "POST", "DELETE"],
    "AllowedOrigins": ["*"],
    "ExposeHeaders": ["ETag", "x-amz-meta-custom-header"]
  }
]
  1. IAMユーザーを作成し、以下の権限を付与:
    • s3:GetObject
    • s3:PutObject
    • 対象バケットのみに制限

1.3 環境変数の設定

  1. .env.example.envにコピー:
cp .env.example .env
  1. .envファイルを編集:
AWS_ACCESS_KEY_ID=your_access_key_id
AWS_SECRET_ACCESS_KEY=your_secret_access_key
AWS_S3_BUCKET_NAME=your_bucket_name
AWS_S3_REGION=your_region
AZURE_TTS_KEY=your_azure_tts_key
AZURE_TTS_REGION=eastus

2. プロジェクトの実行

2.1 依存関係のインストール

npm install

2.2 開発サーバーの起動

npm run dev

ブラウザで http://localhost:3000 にアクセスすると、Remotion Studioが起動します。

2.3 動作確認

  1. Remotion Studioで「HelloWorld」コンポジションを選択

  2. 右側のプロパティパネルで設定を調整:

    • text: 音声化するテキスト
    • voice: 音声の種類(enUSWoman1, enUSWoman2, ptBRWoman, ptBRMan)
    • titleColor: タイトルの色
    • displaySpeed: アニメーション速度
  3. テキストを変更すると:

    • 1秒後にAzure TTSで音声が生成される
    • 音声ファイルがS3にアップロードされる
    • 音声の長さに基づいて動画の長さが自動調整される

3. 動画のレンダリング

3.1 動画の生成

npx remotion render HelloWorld output.mp4

3.2 カスタムプロパティでレンダリング

npx remotion render HelloWorld output.mp4 --props='{"text":"Hello Remotion","voice":"enUSWoman1","titleColor":"red","displaySpeed":15}'

4. トラブルシューティング

4.1 よくあるエラー

  • 1006エラー: Azureサブスクリプションが未有効
  • S3アクセスエラー: IAM権限またはバケットポリシーを確認
  • CORS エラー: S3バケットのCORS設定を確認

4.2 リント・型チェック

npm run lint

4.3 依存関係のアップデート

npm run upgrade

5. カスタマイズ

5.1 音声の追加

src/types.ts:15で音声リストを追加し、src/tts.ts:27-32でvoiceMapを更新

5.2 アニメーションの調整

src/HelloWorld/Title.tsx:33-41でスプリングアニメーションのパラメータを調整

5.3 動画設定の変更

src/Root.tsx:14-17で解像度、FPS、デフォルト長さを変更


TTS処理フローの詳細解説

TTSの処理タイミングと呼び出しフロー

1. 処理開始のトリガー

TTSの処理は RemotionのcalculateMetadataフック で開始されます:

  • 開発時: Remotion Studio でプレビューを開始する際
  • レンダリング時: 動画の生成処理を開始する際
  • プロパティ変更時: コンポーネントのプロパティ(text, voiceなど)が変更された際

2. 処理の実行順序(時系列)

2.1 calculateMetadataフック開始

ファイル: src/Root.tsx:24-42

calculateMetadata={async ({ props, abortSignal }) => {

2.2 ①デバウンス処理

ファイル: src/debounce.ts:3-25

await waitForNoInput(abortSignal, 1000);
  • 開発時: 1秒間待機(ユーザー入力完了を待つ)
  • レンダリング時: 即座にスキップ
  • 目的: リアルタイム編集での不要な処理を防止

2.3 ②音声ファイル存在確認

ファイル: src/tts.ts:86-109

const exists = await audioAlreadyExists({
  text: props.text,
  voice: props.voice,
});
  • 処理内容: S3に同じテキスト・音声の組み合わせが存在するかチェック
  • ファイル名: MD5ハッシュ (${md5({text}--{voice})}.mp3)
  • 効果: 重複する音声生成を防止

2.4 ③音声合成処理(条件実行)

ファイル: src/tts.ts:34-84

if (!exists) {
  await synthesizeSpeech(props.text, props.voice);
}

詳細フロー:

  1. Azure Speech Service設定

    const speechConfig = SpeechConfig.fromSubscription(
      env.AZURE_TTS_KEY,
      env.AZURE_TTS_REGION,
    );
    
  2. SSML生成

    const ssml = `
    <speak version="1.0" xml:lang="en-US">
      <voice name="${voiceMap[voice]}">
        <break time="100ms" /> ${text}
      </voice>
    </speak>`;
    
  3. 音声合成実行

    const result = await new Promise<SpeechSynthesisResult>((resolve, reject) => {
      synthesizer.speakSsmlAsync(ssml, resolve, reject);
    });
    
  4. S3アップロード

    await uploadTtsToS3(audioData, fileName);
    

2.5 ④S3 URL生成

ファイル: src/tts.ts:131-141

const fileName = createS3Url({
  text: props.text,
  voice: props.voice,
});

2.6 ⑤音声長さ取得と動画長さ計算

const duration = await getAudioDurationInSeconds(fileName);
return { props, durationInFrames: Math.ceil(duration * 30) };

2.7 ⑥音声ファイル使用

ファイル: src/HelloWorld.tsx:40

<Audio src={createS3Url({ text, voice })} />

3. 処理フロー図

[Remotion起動/プロパティ変更]

[calculateMetadata実行]

[waitForNoInput (1秒待機)]

[audioAlreadyExists (S3確認)]

    [ファイル存在?]
      ↙        ↘
   [Yes]      [No]
     ↓          ↓
[スキップ]  [synthesizeSpeech]
     ↓          ↓
     ↓    [Azure TTS実行]
     ↓          ↓
     ↓    [S3アップロード]
     ↓          ↓
     └─────────┘

[createS3Url (URL生成)]

[getAudioDurationInSeconds]

[durationInFrames計算]

[HelloWorldコンポーネント]

[Audio要素で音声再生]

4. 各段階での処理時間

開発時(初回)

  1. デバウンス: 1秒
  2. 存在確認: 100-300ms
  3. 音声合成: 2-5秒(テキスト長による)
  4. S3アップロード: 500ms-2秒
  5. 音声長さ取得: 200-500ms

開発時(キャッシュ済み)

  1. デバウンス: 1秒
  2. 存在確認: 100-300ms
  3. 音声合成: スキップ
  4. 音声長さ取得: 200-500ms

レンダリング時

  1. デバウンス: スキップ
  2. 存在確認: 100-300ms
  3. 音声合成: 必要時のみ実行
  4. 音声長さ取得: 200-500ms

5. エラーハンドリング

5.1 Azure TTS エラー

if (res.reason === ResultReason.SynthesizingAudioCompleted) {
  resolve(res);
} else if (res.errorDetails) {
  reject(new Error(res.errorDetails));
} else {
  reject(new Error("Speech Synthesis Error"));
}

5.2 S3 エラー

try {
  return await s3.send(new HeadObjectCommand({ Bucket, Key }));
} catch {
  return false; // ファイル存在しない場合
}

6. 最適化のポイント

6.1 キャッシュ機能

  • MD5ハッシュ: テキストと音声の組み合わせで一意のファイル名生成
  • S3での永続化: 同じ内容の音声は再利用
  • 高速確認: HeadObjectCommandで存在確認

6.2 デバウンス機能

  • 開発時のみ: レンダリング時は無効化
  • ユーザー体験: 入力完了まで待機して不要な処理を防止

6.3 非同期処理

  • 並列処理: 複数の音声生成が可能
  • AbortSignal: 処理の中断に対応

7. 音声品質設定

7.1 対応音声

export const voiceMap: { [key in Voice]: string } = {
  ptBRWoman: "pt-BR-FranciscaNeural",
  ptBRMan: "pt-BR-AntonioNeural", 
  enUSWoman1: "en-US-JennyNeural",
  enUSWoman2: "en-US-AriaNeural",
} as const;

7.2 SSML設定

  • 言語: en-US(固定)
  • ポーズ: 100ms の開始ポーズ
  • 形式: MP3出力

総括

このプロジェクトは、効率的で高品質なTTS機能を持つRemotionビデオ生成システムです。キャッシュ機能、デバウンス処理、エラーハンドリングなど、実用的な機能が組み込まれており、開発体験とパフォーマンスの両方を重視した設計になっています。

  • 開発効率: リアルタイムプレビューとキャッシュ機能
  • 品質: Azure Neural Voice とSSML対応
  • 拡張性: 新しい音声の追加やアニメーションのカスタマイズが容易
  • 安定性: 包括的なエラーハンドリングと処理中断対応

Discussion