tts-voiceover について
tts-voiceoverは、PowerPointのコンテンツディレクトリにあるYAMLのspeaker_notesから、スライドごとのWAVナレーションを生成し、PPTXに埋め込めるスキルです。スライドに合成音声を付けるチーム向けで、SSMLによる発音制御と認証情報不要のドライランに対応します。
主な機能
- 01speaker_notesからスライド別WAVを生成
- 02Azure AI Speechのニューラル音声を使用
- 03SSMLエイリアスで用語の発音を制御
- 04認証情報不要のドライランでテンプレート検証
- 05ナレーション音声をPPTXに埋め込み
活用シーン
- 01プレゼンテーションの各スライドをナレーション化
- 02音声を作らずSSMLテンプレートを確認
- 03技術略語の発音エイリアスを設定
- 04PPTXにナレーションと再生タイミングを追加
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ microsoft/ hve-core --skill tts-voiceoverインストール後、Claude Code で/tts-voiceoverを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
pip-audit-known-vulnerabilities.txtpyproject.tomlSECURITY.mduv.lockscripts/embed_audio.pyembed-audio.shgenerate_voiceover.pygenerate-voiceover.shInvoke-EmbedAudio.ps1Invoke-GenerateVoiceover.ps1scripts/Modules/TtsVoiceoverHelpers.psm1tests/conftest.pyfuzz_harness.pyInvoke-GenerateVoiceover.Tests.ps1test_embed_audio_integrity.pytest_embed_audio.pytest_generate_voiceover_boundaries.pytest_generate_voiceover.pyTtsVoiceoverHelpers.Tests.ps1tests/corpus/0_acronym_text0_empty0_ssml_fragment0_valid_yaml詳細
TTS ナレーションスキル
Azure AI Speech のニューラル音声と SSML による発音制御を使い、YAML の speaker_notes からスライドごとの WAV ナレーションファイルを生成します。
概要
このスキルは、PowerPoint スキルのコンテンツディレクトリにある content.yaml ファイルを読み込み、speaker_notes フィールドを抽出し、技術用語を正しく発音するための頭字語エイリアスを適用して、スライドごとに WAV ファイルを 1 つ生成します。Azure の認証情報なしで SSML テンプレートを検証できるドライランモードに対応しています。
音声合成には、en-US-Andrew:DragonHDLatestNeural などの HD 音声を含む Azure AI Speech のニューラル音声を使用します。HD 音声は一部の Azure リージョンでのみ提供されています。SPEECH_REGION を選択する前に、Speech サービスのリージョンを確認してください。
このスキルで生成されるナレーションは合成音声です。Microsoft の合成音声に関する開示デザインガイドラインに従い、音声が AI によって生成されたことを聴取者に伝えてください。HVE デモ素材の CI では音声合成は行わず、無音の動画を生成します。
前提条件
- Azure Speech リソース:無料利用枠と HD 音声の料金については、Azure AI Speech の料金を参照してください。
- 認証:Microsoft Entra ID(
SPEECH_RESOURCE_ID、推奨)またはリソースキー(SPEECH_KEY)。 - リージョン:音声合成には
SPEECH_REGIONが必須で、デフォルト値はありません。ドライランモードでは不要です。 - 仮想環境の管理に
uvを使用する Python 3.11 以降。 - データ取り扱いに関する注意:音声合成のため、スピーカーノートの内容は設定した
SPEECH_REGIONに送信されます。事前構築済みのニューラル音声について、Microsoft は入力テキストも出力音声も Microsoft のログに保存されないと説明しています。詳しくは、テキスト読み上げに関するデータ、プライバシー、セキュリティを参照してください。ただし、運用担当者は承認済みのリージョンを設定し、規制対象または機密性の高いナレーションを送信しないようにしてください。
Microsoft Entra ID 認証(推奨)
Entra ID を使用すると、長期間有効なキーを保存せずに済みます。Speech リソースにカスタムドメインを設定し、サインインしている ID に Cognitive Services Speech User ロールを割り当てる必要があります。スクリプトは DefaultAzureCredential を通じて ID を解決するため、az login セッション、マネージド ID、または azure/login による GitHub Actions の OIDC ログインを使用できます。
export SPEECH_RESOURCE_ID="/subscriptions/.../Microsoft.CognitiveServices/accounts/your-resource"
export SPEECH_REGION="eastus"
キーベースの認証
export SPEECH_KEY="your-speech-key"
export SPEECH_REGION="eastus"
SPEECH_KEY と SPEECH_RESOURCE_ID の両方が設定されている場合、スクリプトは警告を表示してキーを使用します。Entra ID を使用するには、SPEECH_KEY の設定を解除してください。
依存関係をインストールします:
# run from this skill folder
uv sync
クイックスタート
音声を生成せずに SSML テンプレートを検証します:
uv run scripts/generate_voiceover.py --dry-run --content-dir path/to/content
ナレーションの WAV ファイルを生成します:
uv run scripts/generate_voiceover.py --content-dir path/to/content --output-dir voice-over
音声を PPTX デッキに埋め込みます:
uv run scripts/embed_audio.py --input deck.pptx --audio-dir voice-over --output deck-narrated.pptx
パラメーターリファレンス
話者を変える場合は、--slide <number> 引数を繰り返し指定して、1 回の実行につき選択したスライドの音声を 1 人分生成します。指定された正規の slide-NNN フォルダーのみを読み込み、その WAV ファイルを置き換えます。他の話者の出力には影響しません。デッキ全体を合成するには、--slide を省略してください。
generate_voiceover.py
| パラメーター | 型 | デフォルト値 | 説明 |
|---|---|---|---|
--dry-run | フラグ | false | 音声を生成せずに SSML を出力します |
--voice | 文字列 | en-US-Andrew:DragonHDLatestNeural | Azure AI Speech の音声名 |
--rate | 文字列 | +10% | 音声のプロソディ速度 |
--content-dir | パス | content | スライドコンテンツディレクトリへのパス |
--output-dir | パス | voice-over | WAV 出力ディレクトリへのパス |
--slide | 整数 | すべてのスライド | 選択した正規のスライド番号のみを合成するには、繰り返し指定します |
--lexicon | パス | (自動検出) | カスタム acronyms.yaml のパス |
--collapse-newlines | フラグ | false | 合成前にスピーカーノート内の改行と連続する空白を単一のスペースにまとめます |
--verbose / -v | フラグ | false | 詳細な(DEBUG)ログ出力を有効にします |
embed_audio.py
WAV ファイルを対応する PPTX スライドに埋め込み、PowerPoint が動画のエクスポート時に音声を認識できるよう、ナレーションのタイミングを示す XML を追加します。ファイル > エクスポート > ビデオの作成 > 記録されたタイミングとナレーションを使用から動画をエクスポートできます。
| パラメーター | 型 | デフォルト値 | 説明 |
|---|---|---|---|
--input | パス | (必須) | 入力元 PPTX ファイルのパス |
--audio-dir | パス | voice-over | slide-NNN.wav が格納されたディレクトリ |
--output | パス | *-narrated.pptx | 出力 PPTX ファイルのパス |
--verbose / -v | フラグ | false | 詳細な(DEBUG)ログ出力を有効にします |
各 WAV ファイルは、ファイル名の番号に基づいてスライドに対応付けられます。そのため、slide-1.wav と slide-001.wav はどちらもスライド 1 に対応します。同じスライドに対応するファイルが 2 つある場合は、エラーで埋め込みを停止し、出力ファイルは作成されません。最後のスライド番号を超える番号の WAV ファイルは、警告を出して無視されます。読み取れない WAV ファイルがある場合はその旨が報告され、該当するスライドは変更されませんが、残りのスライドへの埋め込みは続行されます。
スクリプトリファレンス
カスタム音声と速度で生成します:
uv run scripts/generate_voiceover.py \
--content-dir content \
--output-dir voice-over \
--voice "en-US-Jenny:DragonHDLatestNeural" \
--rate "+5%"
カスタムの語彙リストを使用します:
uv run scripts/generate_voiceover.py \
--content-dir content \
--lexicon custom-acronyms.yaml
スピーカーノートの改行をまとめます(改行がそのままだと間として読み上げられる、ブロックスカラーの | 形式のノートで推奨されます):
uv run scripts/generate_voiceover.py \
--content-dir content \
--collapse-newlines
生成した音声を埋め込みます:
uv run scripts/embed_audio.py \
--input slide-deck/presentation.pptx \
--audio-dir voice-over \
--output slide-deck/presentation-narrated.pptx
頭字語の語彙リスト
語彙リストでは、頭字語や専門用語に対する SSML の <sub alias> 置換を設定します。acronyms.yaml ファイルを作成します:
acronyms:
HVE-Core: "H V E Core"
OWASP: "Oh wasp"
SBOM: "S Bomb"
SLSA: "Salsa"
CI/CD: "C I C D"
語彙リストの解決順序:
--lexicon引数で指定したパス。- コンテンツディレクトリ内の
acronyms.yaml。 - 一般的な技術系の頭字語を網羅した組み込みのデフォルト設定。
SSML テンプレート
各スライドから SSML ドキュメントが生成されます:
<speak version="1.0" xmlns="http://www.w3.org/2001/10/synthesis"
xmlns:mstts="http://www.w3.org/2001/mstts" xml:lang="en-US">
<voice name="en-US-Andrew:DragonHDLatestNeural">
<prosody rate="+10%">
Text with <sub alias="Oh wasp">OWASP</sub> aliases applied.
</prosody>
</voice>
</speak>
PowerPoint Skill との連携
このスキルは、PowerPoint skill のコンテンツディレクトリ構造から読み込みます:
content/
├── slide-001/
│ └── content.yaml # Must include speaker_notes: field
├── slide-002/
│ └── content.yaml
└── ...
各 content.yaml には、ナレーションテキストを含む speaker_notes: フィールドが必要です。生成される WAV ファイルの名前は、ディレクトリ名に対応する slide-NNN.wav 形式です。
トラブルシューティング
| 問題 | 解決方法 |
|---|---|
Set SPEECH_KEY ... or SPEECH_RESOURCE_ID | SPEECH_REGION とともに、SPEECH_KEY(キー認証)または SPEECH_RESOURCE_ID(Entra ID)をエクスポートします。 |
SPEECH_REGION must be set | 承認済みの Azure リージョンを指定して SPEECH_REGION をエクスポートします。音声合成にはデフォルトのリージョンがありません。 |
Multiple WAV files map to slide N | 重複する WAV ファイル(例:slide-001.wav と同じ場所にある slide-1.wav)を削除し、embed_audio.py を再実行します。 |
| Entra ID 認証で 401 が発生する | Speech リソースのカスタムドメインと Cognitive Services Speech User ロールを確認します。RBAC の反映には最大 5 分かかります。 |
| WAV ファイルが空、またはスライドがスキップされる | content.yaml に speaker_notes: があり、空でないことを確認します。 |
| 頭字語の読み上げが正しくない | 発音表記を使った項目を acronyms.yaml に追加します。 |
azure-cognitiveservices-speech package is required | スキルのディレクトリで uv sync を実行します。 |
| PPTX で音声アイコンが表示される | 埋め込み後に PowerPoint で音声オブジェクトの位置またはサイズを変更します。 |
| 埋め込み後に作成済みのスライドアニメーションが失われる | embed_audio.py は既存の p:timing をナレーションのタイミングに置き換えます。音声の埋め込み後に、PowerPoint でアニメーションを再適用します。 |
| 埋め込み後、クリックしてもスライドが進まなくなる | embed_audio.py は自動進行のために advClick="0" を設定します。再度有効にするには、PowerPoint ですべてのスライドを選択し、「画面切り替え」タブで スライドを進める > マウスクリック時 をオンにします。 |
| 動画のエクスポート時に「タイミングが記録されていません」と表示される | ナレーションのタイミング XML を自動的に追加する、更新済みの embed_audio.py で音声を再度埋め込みます。 |