add_notes_voice_pptx.py 技術ドキュメント

プログラムの動作

このプログラム add_notes_voice_pptx.py は、PowerPoint (PPTX) ファイルのノート内容を音声ファイルに変換し、その音声ファイルを元のPPTXファイルに自動再生リンクとして埋め込むことを目的としています。特に、Windows環境のPowerPointと連携し、プレゼンテーションのナレーション作成プロセスを自動化します。

主な機能:

  1. PPTXノートまたは外部テキストからのナレーション抽出:

    • 既存のPPTXファイルから各スライドのノート内容を読み込みます。

    • または、特定の形式で記述された外部テキストファイル (narration_txt) から、スライド番号に対応するナレーションテキストを抽出します。

  2. 音声ファイル生成:

    • 抽出したナレーションテキストを、指定されたTTS (Text-to-Speech) エンジン(pyttsx3VOICEVOXAquesTalkPlayerOpenAI)を用いて音声ファイル(WAVまたはMP3)に変換します。

    • 話者マッピング、読み上げ速度、ピッチなどの詳細設定が可能です。

  3. PPTXへの音声リンク埋め込みと自動再生設定:

    • 生成された音声ファイルをPowerPointのスライドに埋め込みます。

    • スライドショー再生時に、そのスライドの音声ファイルが自動的に再生されるように設定します。音声アイコンはスライドの右下に配置されます。

  4. TTSエンジンとボイスの管理:

    • 利用可能なTTSエンジンやボイスの一覧表示、またはテキストファイル内の話者とTTSエンジンのボイスとのマッピングを表示するモードも提供されます。

解決する課題:

PowerPointプレゼンテーションに手動でナレーションを追加する作業は時間と手間がかかります。このプログラムは、テキストベースのノートから自動で音声を生成し、プレゼンテーションに統合することで、このプロセスを大幅に効率化し、一貫性のある音声付きプレゼンテーションの作成を支援します。

原理

本プログラムは、主に以下の技術とアルゴリズムに基づいて動作します。

  1. PowerPoint COM (Component Object Model) オートメーション:

    • Windows環境に特有の win32com.client ライブラリを使用して、PowerPointアプリケーションをCOMインターフェース経由で操作します。これにより、PythonスクリプトからPowerPointの機能(ファイル開閉、スライドアクセス、ノートの読み書き、シェイプの追加、アニメーション設定など)をプログラム的に制御できます。

    • ノートの読み書き: pres.Slides(idx).NotesPage.Shapes を通じて各スライドのノートページにアクセスし、特定のプレースホルダーシェイプのテキストフレームからノート内容を取得したり、設定したりします。

    • メディアオブジェクトの追加: slide.Shapes.AddMediaObject2() メソッドを使用して、生成した音声ファイル(WAV/MP3)をスライドに埋め込みます。LinkToFile=True, SaveWithDocument=False の設定により、音声ファイルはプレゼンテーションファイル内にコピーされず、外部ファイルとしてリンクされます。

    • 自動再生設定: 埋め込まれたメディアシェイプの AnimationSettings.PlaySettings.PlayOnEntry = True を設定することで、スライド表示と同時に音声が再生されるようにします。さらに、slide.TimeLine.MainSequence.AddEffect() メソッドを msoAnimEffectMediaPlay (9) と msoAnimTriggerWithPrevious (2) の引数で呼び出すことで、スライドが切り替わると同時に音声が再生されるようにトリガーを設定します。

  2. 外部TTS (Text-to-Speech) エンジンとの連携:

    • プログラムは tktts というモジュールを介して、複数のTTSエンジン(pyttsx3VOICEVOXAquesTalkPlayerOpenAI)と連携します。tktts はこれらの異なるTTSエンジンのAPIや実行可能ファイルを抽象化し、統一されたインターフェース(tkTTS クラス)を提供します。

    • tkTTS.speak_dialogue() メソッドは、話者情報とテキストのリストを受け取り、各TTSエンジンの設定(速度、ピッチ、ボイスなど)を適用して音声ファイルを生成します。

    • 話者マッピング: VOICE_MAPS 辞書と tktts.update_voice_map() 関数は、スクリプト内で定義された抽象的な話者名(例: "四国めたん")と、各TTSエンジンで実際に利用可能な具体的なボイス名(例: pyttsx3 の "Zira"、OpenAI の "nova")とを対応させます。これにより、ユーザはTTSエンジンに依存しない話者名でナレーションを作成できます。

  3. ナレーションテキストの解析:

    • parse_narration_file() 関数は、外部ナレーションテキストファイルからスライドごとのテキストを抽出するために正規表現を使用します。具体的には、# Slide N という形式の行をスライド番号の区切りとして認識し、それ以下のテキストをそのスライドのノート内容として収集します。

必要な非標準ライブラリとインストール方法

このプログラムの実行には、いくつかの非標準ライブラリが必要です。

  1. pywin32: PowerPointのCOMオートメーション機能を利用するために必要です。

    pip install pywin32
    
  2. tktts: TTSエンジンを統合するためのカスタムモジュールです。

    • このモジュールは標準ライブラリには含まれていません。tktts.py ファイルが add_notes_voice_pptx.py と同じディレクトリに存在するか、Pythonのパスが通っている場所に配置されている必要があります。

    • インストールコマンドは通常存在しないため、ファイルを直接配置してください。

上記に加えて、使用するTTSエンジンに応じて以下のライブラリやツールが必要になります。

  • pyttsx3 (デフォルト): PythonのオフラインTTSエンジン。

    pip install pyttsx3
    
  • VOICEVOX: VOICEVOXエンジンと連携する場合。

    • VOICEVOX アプリケーション自体が別途インストールされ、起動している必要があります。APIエンドポイントは --endpoint オプションで指定します。

    • Pythonライブラリとしての追加インストールは不要な場合がありますが、tktts 内部で requests などのHTTPクライアントが使われる場合はそちらのインストールが必要です (pip install requests)。

  • AquesTalkPlayer: AquesTalkPlayer.exe を使用する場合。

    • AquesTalkPlayer.exe が別途インストールされている必要があります。実行パスは --aquestalk_path オプションで指定します。

  • OpenAI: OpenAIのTTS APIを使用する場合。

    pip install openai
    
    • OpenAI APIキーの設定が必要になる場合があります。これは通常、環境変数 OPENAI_API_KEY を設定するか、tktts 内部でキーを直接渡すことで行われます。

必要な入力ファイル

プログラムの動作には、主に以下の入力ファイルが必要です。

  1. 元のPowerPointプレゼンテーションファイル (.pptx)

    • コマンドライン引数: --input_path または -i

    • 概要: 音声リンクを追加したいPowerPointファイルです。このファイルは変更されず、出力ファイルが新たに生成されます。

  2. ナレーションテキストファイル (.txt)

    • コマンドライン引数: --narration_txt または -n

    • 概要: 各スライドのノート内容を含むテキストファイルです。このファイルの内容は、まず元のPPTXにノートとして書き込まれ、その後そのノートから音声が生成されます。PPTXファイルにすでにノートが書き込まれている場合はこのファイルを省略できますが、本プログラムでは input_pathnarration_txt の両方が必須とされています(ただし、generate_audio_files_tktts はPPTXから直接ノートを読み込むため、用途によっては narration_txt は中間ノート書き込み用と解釈できます)。

    • ファイル形式:

      • スライドごとに # Slide N (Nはスライド番号) で区切ります。

      • # Slide N の行に続くテキストがそのスライドのノート内容として扱われます。

      • 空行や # で始まる行、(...) で囲まれた行はコメントとして無視されます。

      • 例:

        # Slide 1
        これは最初のスライドのナレーションです。
        複数行にわたることも可能です。
        
        # Slide 2
        次のスライドのナレーションは、
        システムが自動で読み上げます。
        ---
        # Slide 3
        最後のスライドです。
        (この括弧内のテキストは無視されます)
        
      • --monologue 0 (デフォルトではない) の場合、行の最初のカンマより前の部分を話者名として認識し、カンマより後の部分をテキストとして扱います。--monologue 1 の場合は、行全体をテキストとして扱います。

生成される出力ファイル

プログラムの実行により、以下のファイルが生成されます。

  1. 音声リンクが追加されたPowerPointプレゼンテーションファイル (.pptx)

    • コマンドライン引数: --output_path または -o

    • 概要: --input_path で指定されたPPTXファイルを基に、生成された音声ファイルへの自動再生リンクが設定された新しいPPTXファイルです。元の入力ファイルは変更されません。

  2. 生成された音声ファイル (.wav または .mp3)

    • コマンドライン引数: --audio_dir または -a (デフォルト: audio_output)

    • 概要: 各スライドのナレーションから変換された音声ファイルが保存されるディレクトリです。ファイル名は slideN.wav (または slideN.mp3) の形式になります(例: slide1.wav, slide2.wav)。

  3. 一時ファイル (.pptx, .wav)

    • コマンドライン引数: --temp_dir (デフォルト: tts_temp_wavs_pptx)

    • 概要:

      • temp_notes_added.pptx: narration_txt が指定された場合、元のPPTXファイルにナレーションテキストがノートとして書き込まれた一時ファイルです。音声生成はこのファイルから行われます。プログラムの終了時に自動的に削除されます。

      • TTSエンジンによっては、このディレクトリ内に一時的な音声ファイルなどが生成されることがあります。これらもプログラムの終了時に削除されます。

コマンドラインでの使用例 (Usage)

add_notes_voice_pptx.py は、以下の基本的な構文で実行されます。

利用可能なオプションの確認:

python add_notes_voice_pptx.py --help

モード: list (利用可能な音声名を表示)

python add_notes_voice_pptx.py --mode list [--tts <engine>] [--endpoint <url>]
  • <engine>: pyttsx3, voicevox, aquestalkplayer, atp, openai のいずれか。

  • --endpoint: voicevox エンジンの場合のみ、Voicevox EngineのURLを指定。

モード: map (発言テキストファイルの話者とボイスのマッピングを表示)

python add_notes_voice_pptx.py --mode map --narration_txt <narration.txt> [--tts <engine>] [--voices <map>] [-m <monologue>]
  • <narration.txt>: 発言テキストファイルのパス。

  • <engine>: 使用するTTSエンジン。

  • <map>: 話者名=ボイス名;話者名=ボイス名 の形式でボイスマッピングを上書き。

  • -m <monologue>: 独話形式 (0=対話形式, 1=独話形式)。

モード: conv (音声ファイルを生成しPPTXにリンク)

python add_notes_voice_pptx.py --mode conv -i <input.pptx> -n <narration.txt> -o <output.pptx> [オプション]
  • -i <input.pptx>: ノートを追加する元のPPTXファイルパス。

  • -n <narration.txt>: ノート内容を含む発言テキストファイルパス (既存ノートがない場合)。

  • -o <output.pptx>: 音声リンクが追加された出力PPTXファイルパス。

主なオプション:

  • --tts {pyttsx3,voicevox,aquestalkplayer,atp,openai}: 使用するTTSエンジンを選択 (デフォルト: pyttsx3)。

  • --audio_dir <dir_name>: 生成された音声ファイルを保存するディレクトリ (デフォルト: audio_output)。

  • --speak_rate <rate>: 読み上げ速度 (WPM for pyttsx3, 速度比 for AQT)。

  • --tinterval <seconds>: 音声ファイル間に挿入する無音区間の長さ(秒)。

  • --voices <map>: 話者名=ボイス;話者名=ボイス の形式でボイスマッピングを上書き。

  • --replace <rule>: key=val;key=val の形式で文字列置換ルールを設定。

  • --monologue {0,1}: 独話形式 (カンマのない行も読み込む)。

  • --endpoint <url>: VOICEVOXエンジンを使用する場合のAPIエンドポイント。

  • --aquestalk_path <path>: AquesTalkPlayer.exe の実行パス。

  • --instruction <text>: OpenAI TTS APIへの追加指示。

コマンドラインでの具体的な使用例

ここでは、いくつかの具体的なコマンドライン使用例と、その実行結果を説明します。

事前に、以下のファイルが準備されていると仮定します。

  • presentation.pptx: 元のPowerPointプレゼンテーションファイル。

  • narration.txt: 各スライドのナレーションテキストを含むファイル(上記「必要な入力ファイル」の形式)。

1. 利用可能な音声名の一覧表示 (pyttsx3の場合)

pyttsx3 で利用可能なボイス名を確認します。

python add_notes_voice_pptx.py --mode list --tts pyttsx3

実行結果の例:

--- pyttsx3 で利用可能なボイス ---
Name: Microsoft David Desktop - English (United States), ID: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech\Voices\Tokens\TTS_MS_EN-US_DAVID_11.0, Languages: [b'409'], Gender: male, Age: unknown
Name: Microsoft Zira Desktop - English (United States), ID: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech\Voices\Tokens\TTS_MS_EN-US_ZIRA_11.0, Languages: [b'409'], Gender: female, Age: unknown

(システムにインストールされているボイスにより表示は異なります。)

2. 利用可能な音声名の一覧表示 (VOICEVOXの場合)

VOICEVOX Engineが http://127.0.0.1:50021 で起動している状態で、利用可能なボイス名を確認します。

python add_notes_voice_pptx.py --mode list --tts voicevox --endpoint http://127.0.0.1:50021

実行結果の例:

--- VOICEVOX で利用可能なボイス ---
0: 四国めたん (standard)
1: ずんだもん (standard)
2: 四国めたん (ame)
3: ずんだもん (ame)
...

(VOICEVOX Engineのバージョンやインストールされているスタイルにより表示は異なります。)

3. 発言テキストファイルの話者とボイスマッピングの確認

narration.txt ファイル内の話者と、デフォルトのマッピング(または指定された --voices)がどのように関連付けられるかを確認します。

narration.txt の内容が以下であると仮定します(--monologue 1 のため話者区切りは無視されるが、tktts は話者名自体を抽出できる)。

# Slide 1
四国めたん, こんにちは、今日はプレゼンテーションにお越しいただきありがとうございます。

# Slide 2
ずんだもん, このスライドでは、私たちのプロジェクトについて説明します。
python add_notes_voice_pptx.py --mode map --narration_txt narration.txt --tts pyttsx3 --monologue 1

実行結果の例:

✅ テキストファイルを解析しました: 2 スライド分のノートを検出。
  Speakers in [narration.txt]
    00: 四国めたん
    01: ずんだもん

Voice map updated:
  (speaker) 四国めたん: (voice) Zira
  (speaker) ずんだもん: (voice) David
  (speaker) None: (voice) Zira
=== 検出された話者とvoice ===
- ずんだもん: David
- 四国めたん: Zira
  (独話): Zira

VOICE_MAPS の定義に基づき、pyttsx3ZiraDavid が割り当てられています。)

4. PowerPointへの音声リンク追加 (pyttsx3使用)

presentation.pptxnarration.txt の内容をノートとして書き込み、その後、そのノートから pyttsx3 で音声を生成し、output.pptx に音声リンクを設定します。

python add_notes_voice_pptx.py --mode conv -i presentation.pptx -n narration.txt -o output.pptx --tts pyttsx3 --audio_dir my_audio_output --speak_rate 180 --monologue 1

実行結果の例:

--- 💻 PowerPointナレーション作成プログラム (CONVモード) 開始 ---
  TTS engine  : pyttsx3
  is monologue: 1
  入力PPTX    : presentation.pptx
  入力テキスト: narration.txt
  出力PPTX    : output.pptx
  音声フォルダ: my_audio_output
--------------------------------------------------

[narration.txt]を解析します:
✅ テキストファイルを解析しました: 2 スライド分のノートを検出。
  Speakers in [narration.txt]
    00: 四国めたん
    01: ずんだもん

Voice map updated:
  (speaker) 四国めたん: (voice) Zira
  (speaker) ずんだもん: (voice) David
  (speaker) None: (voice) Zira
=== 検出された話者とvoice ===
- ずんだもん: David
- 四国めたん: Zira
  (独話): Zira

  ノートを一時ファイルに書き込み中...
✅ ノートを一時PPTXファイルに書き込みました: temp_notes_added.pptx (2件)

音声ファイルを生成します:
--- 📝 PPTXからノートを取得中 ---
  ✅ ノートを検出: 2 スライド

--- 🗣️ スライドごとに PYTTSX3 で音声ファイルを生成中 ---

スライド #1 の音声ファイルを生成しています...
  ✅ 生成完了: slide1.wav (スライド 1)

スライド #2 の音声ファイルを生成しています...
  ✅ 生成完了: slide2.wav (スライド 2)

🗑️ 一時ディレクトリ tts_temp_wavs_pptx を削除しました。
✅ 音声ファイル生成完了 (2件)

音声ファイルを[temp_notes_added.pptx]にリンクします:
--- 🔗 PPTXに音声ファイルをリンクし、自動再生を設定中 ---
  🔗 リンク追加: スライド 1 (...my_audio_output\slide1.wav)
  🔗 リンク追加: スライド 2 (...my_audio_output\slide2.wav)

✅ PowerPoint更新完了: output.pptx

一時ファイル [temp_notes_added.pptx] を削除します:
  クリーンアップ完了
--- 🎉 プログラム終了 ---

Press ENTER to terminate>>

この実行により、my_audio_output ディレクトリに slide1.wavslide2.wav が生成され、output.pptx にこれらの音声ファイルへのリンクが自動再生設定付きで埋め込まれます。output.pptx をPowerPointで開いてスライドショーを開始すると、各スライドで対応するナレーションが自動的に再生されます。