tktts.py ライブラリ技術ドキュメント

ライブラリの機能や目的

tktts.py は、複数のテキスト読み上げ (Text-to-Speech, TTS) エンジンを統合し、統一されたインターフェースで利用可能にするPythonライブラリです。ユーザーは、ファイルやクリップボードからのテキスト読み込み、話者ごとの音声の割り当て、生成された音声の結合、そして再生またはファイル保存を簡単に行うことができます。

このライブラリの主な目的は以下の通りです。

  • 多様なTTSエンジンの統合: pyttsx3VoiceVoxAquesTalkPlayerOpenAI (TTS-1) といった複数の異なるTTSエンジンを、共通のAPIを通じて利用できるようにします。これにより、ユーザーは特定のエンジンに依存することなく、ニーズに合わせて選択・切り替えが可能です。

  • 対話形式テキストの音声化: カンマ区切りで話者とセリフが記述されたテキストファイル(例: 話者名,セリフ)を解析し、各話者に異なる音声を割り当てて、自然な対話形式の音声を生成する機能を提供します。

  • 柔軟な音声カスタマイズ: 話者名と音声のマッピング、デフォルト音声の設定、読み上げ速度の調整(pyttsx3 の場合)、一時ファイルディレクトリの指定など、きめ細やかな設定をサポートします。

  • 開発効率の向上: TTSエンジンの複雑な初期化や音声生成ロジックを抽象化し、シンプルな関数やクラスメソッドを通じて、アプリケーションへのTTS機能組み込みを容易にします。

tktts.py は、例えば物語の朗読、プレゼンテーションのナレーション、対話シミュレーションなど、テキストを音声に変換して利用する幅広いユースケースで、開発の時間と労力を削減することを目指しています。

importする方法

tktts.py ライブラリを他のPythonプログラムから利用するには、以下のいずれかの方法でインポートします。

ライブラリ全体をインポートする場合:

import tktts

# tkTTSクラスのインスタンスを作成
tts_client = tktts.tkTTS(tts_name="pyttsx3")

# その他の関数を呼び出す場合
dialogue_data = tktts.load_text("dialogue.txt")

特定のクラスや関数をインポートする場合:

from tktts import tkTTS, load_text

# tkTTSクラスのインスタンスを作成
tts_client = tkTTS(tts_name="voicevox")

# load_text関数を直接呼び出す
dialogue_data = load_text("clip", monologue=True)

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

tktts.py を実行するためには、いくつかの非標準ライブラリと外部ツールが必要です。

Pythonライブラリ:

以下のライブラリは pip コマンドを使用してインストールできます。

pip install pyttsx3 openai pydub chardet pyperclip simpleaudio
  • pyttsx3: オフラインで動作するテキスト読み上げエンジンです。

  • openai: OpenAIのTTS-1 APIを利用するためのクライアントライブラリです。

  • pydub: 音声ファイルを操作(結合、フォーマット変換など)するためのライブラリです。

  • chardet: テキストファイルのエンコーディングを検出するためのライブラリです。

  • pyperclip: クリップボードへのアクセスを提供します。

  • simpleaudio: pydub と連携し、生成された音声を再生するために使用されます。

外部ツール:

  • FFmpeg: pydubsimpleaudio が音声ファイルの処理と再生を行うために、バックエンドとしてFFmpegが必要です。FFmpegはPythonライブラリではないため、別途ダウンロードしてシステムにインストールし、その実行ファイルへのパスをシステムのPATH環境変数に設定する必要があります。

    FFmpeg公式サイト からお使いのOSに合ったバイナリをダウンロードし、インストール手順に従ってください。

    PATH設定の例 (Windows):

    1. FFmpegをダウンロードし、C:\ffmpeg のように適当なディレクトリに展開します。

    2. C:\ffmpeg\bin ディレクトリへのパスをシステムの環境変数PATHに追加します。

    PATH設定の例 (macOS/Linux): パッケージマネージャー (Homebrew, apt, yumなど) を使うと簡単にインストールできます。

    # macOSの場合 (Homebrew)
    brew install ffmpeg
    
    # Debian/Ubuntuの場合
    sudo apt update
    sudo apt install ffmpeg
    

importできる変数と関数

グローバル変数

  • TTS_ENGINES (dict): 利用可能なTTSエンジンの設定を定義する辞書です。各キーはエンジン名(例: "pyttsx3")、値はそのエンジンのモジュール、デフォルト音声、一時ファイル拡張子 (ext) を含む辞書です。

グローバル関数

  • apply_replacements(text, replacements) 指定された置換辞書 replacements を使用して、入力テキスト text 内の文字列を置換します(大文字小文字を区別しません)。

    • 引数:

      • text (str): 置換処理を行う元のテキスト。

      • replacements (dict): {"置換前の文字列": "置換後の文字列"} の形式の辞書。キーは正規表現として扱われます。

    • 戻り値:

      • str: 置換処理後のテキスト。

  • load_text(input_path, monologue=False, wait_for_clipboard=True) 指定された入力元(ファイルパスまたはクリップボード)からテキストを読み込み、読み上げに適した形式のリストに変換します。

    • 引数:

      • input_path (str): テキストの入力元。"clip" を指定するとクリップボードから、それ以外の場合はファイルパスとして扱われます。

      • monologue (bool, オプション): True の場合、テキストを独話形式として扱い、すべて単一話者 (None) に割り当てます。False の場合、カンマ区切りの対話形式 (話者名,セリフ) を期待します。デフォルトは False

      • wait_for_clipboard (bool, オプション): input_path が "clip" の場合、True であればユーザーがEnterキーを押すまで待機し、クリップボードへのコピーを促します。デフォルトは True

    • 戻り値:

      • list[tuple[str | None, str]] | None: (話者名, セリフ) のタプルのリスト。ファイルが見つからない、読み込みエラーが発生した場合は None

  • create_temp_dir(temp_dir) 指定されたパスに一時ディレクトリを作成します。既に存在する場合は何もしません。

    • 引数:

      • temp_dir (str): 作成する一時ディレクトリのパス。

    • 戻り値:

      • str: 作成された(または既存の)一時ディレクトリのパス。

  • get_speaker_dict(tts_engine, dialogue, voices, ...) 対話データ dialogue と、ユーザーが指定した音声リスト voices に基づいて、話者と音声名のマッピング辞書を作成します。

    • 引数:

      • tts_engine (str): 使用するTTSエンジンの名前(例: "pyttsx3", "voicevox")。

      • dialogue (list[tuple[str | None, str]]): load_text 関数から返されるような対話のリスト。

      • voices (str): セミコロン区切りで指定される音声リスト(例: "話者1=VoiceA;話者2=VoiceB;VoiceC")。

      • default_voicevox_voice, default_pyttsx3_voice, default_aqt_preset, default_optnai_voice (str, オプション): 各エンジンのデフォルト音声名。

    • 戻り値:

      • dict[str | None, str] | None: 話者名から音声名へのマッピング辞書。tts_engine が無効な場合は None

  • get_tts(tts_engine) 指定されたTTSエンジンのモジュールオブジェクトを取得します。このモジュールは、tktts_pyttsx3.py のように tktts_ プレフィックスが付いた外部ファイルとしてインポートされます。

    • 引数:

      • tts_engine (str): 取得したいTTSエンジンの名前。

    • 戻り値:

      • module | None: TTSエンジンのモジュールオブジェクト。インポートに失敗した、またはエンジン名が無効な場合は None

  • get_available_voices_info(endpoint=None) 指定されたTTSエンジン(tts_engine グローバル変数に依存)が利用可能な音声の詳細情報を取得します。これは、内部で get_tts を呼び出し、取得したモジュールの get_available_voices_info メソッドを呼び出すラッパー関数です。

    • 引数:

      • endpoint (str, オプション): VoiceVoxなどの場合、APIエンドポイントのURL。

    • 戻り値:

      • list[dict] | None: 利用可能な音声の詳細情報を含む辞書のリスト。

  • get_available_voices(endpoint=None) 指定されたTTSエンジンが利用可能な音声の名前リストを取得します。get_available_voices_info と同様に、内部モジュールのメソッドを呼び出すラッパーです。

    • 引数:

      • endpoint (str, オプション): VoiceVoxなどの場合、APIエンドポイントのURL。

    • 戻り値:

      • list[str] | None: 利用可能な音声名のリスト。

  • list_available_voices(tts_engine, endpoint=None) 指定されたTTSエンジンの利用可能な音声リストを標準出力に表示します。

    • 引数:

      • tts_engine (str): 音声リストを表示したいTTSエンジンの名前。

      • endpoint (str, オプション): VoiceVoxなどの場合、APIエンドポイントのURL。

    • 戻り値:

      • bool: 処理が成功した場合は True、失敗した場合は False

  • normalize_speaker(speaker, tts_engine) 話者名を正規化します。主に、話者名に括弧やスタイル情報が含まれている場合に、純粋な話者名を抽出します。

    • 引数:

      • speaker (str | None): 正規化する話者名。

      • tts_engine (str): 使用するTTSエンジンの名前。

    • 戻り値:

      • str | None: 正規化された話者名。

  • parse_kv_string(kv_string, keys=[], allow_no_key_kv_string=False) key=val;key=val 形式の文字列を辞書に変換します。キーがない場合はインデックスとして扱われます。

    • 引数:

      • kv_string (str): 解析するキーバリュー形式の文字列。

      • keys (list[str], オプション): kv_string にキーが指定されていない場合に、インデックスに対応する話者名として使用するリスト。

      • allow_no_key_kv_string (bool, オプション): True の場合、= を含まない文字列も値として受け入れ、インデックスまたは keys に基づいて割り当てます。デフォルトは False

    • 戻り値:

      • dict[str | int, str]: 解析結果の辞書。

  • speak_dialogue(args, dialogue, voice_map=None, speakers={}, replacements=None, ..., output_format='mp3') 対話データ dialogue に基づいて音声ファイルを生成し、結合し、指定されたフォーマットで保存または再生します。

    • 引数:

      • args (object): コマンドライン引数を模倣したオブジェクト (例: argparse.Namespace のインスタンス)。tts (tts_engine 名)、outfile (出力ファイルパス)、monologuespeak_ratetinterval (話者間の無音時間)、voicestemp_dir などの属性が必要です。

      • dialogue (list[tuple[str | None, str]]): load_text 関数から返されるような対話のリスト。

      • voice_map (dict[str | None, str], オプション): 話者名から音声名への明示的なマッピング辞書。None の場合、get_speaker_dict を呼び出して作成します。

      • speakers (dict, オプション): 既存の話者辞書。

      • replacements (dict, オプション): apply_replacements に渡す置換辞書。

      • endpoint (str, オプション): VoiceVoxなどのAPIエンドポイント。

      • output_format (str, オプション): 出力音声ファイルのフォーマット(例: "mp3", "wav")。デフォルトは "mp3"。

    • 戻り値:

      • str | False: 処理が成功した場合、出力ファイルのパス。失敗した場合は False

クラス: tkTTS

tkTTS クラスは、tktts.py ライブラリの主要なインターフェースを提供します。インスタンスを作成することで、特定のTTSエンジンを設定し、その設定に基づいてテキスト読み上げ操作を実行できます。

  • __init__(self, tts_name=None, config={}) tkTTS クラスの新しいインスタンスを初期化します。

    • 引数:

      • tts_name (str, オプション): 使用するデフォルトのTTSエンジンの名前(例: "pyttsx3", "voicevox")。None の場合、後で set_engine で設定できます。

      • config (object, オプション): コマンドライン引数を模倣した設定オブジェクト。endpointaquestalk_path などの属性を持つことができます。

  • set_engine(self, tts_name) 使用するTTSエンジンを設定します。

    • 引数:

      • tts_name (str): 設定するTTSエンジンの名前。

  • set_endpoint(self, endpoint) VoiceVoxなどのAPIエンドポイントを設定します。

    • 引数:

      • endpoint (str): APIエンドポイントのURL。

  • set_aquestalk_path(self, aquestalk_path) AquesTalkPlayerエンジンの実行可能ファイルへのパスを設定します。

    • 引数:

      • aquestalk_path (str): AquesTalkPlayerのパス。

  • get_tts_name(self, tts_name) 現在のTTSエンジン名、または指定された tts_name を返します。

    • 引数:

      • tts_name (str, オプション): 優先的に使用するTTSエンジン名。

    • 戻り値:

      • str: TTSエンジン名。

  • get_default_voice(self, tts_name=None) 指定されたTTSエンジン(または現在のエンジン)のデフォルト音声名を返します。

    • 引数:

      • tts_name (str, オプション): デフォルト音声名を取得したいTTSエンジン名。

    • 戻り値:

      • str | None: デフォルト音声名。

  • normalize_speaker(self, speaker, tts_name=None) 話者名を正規化します。インスタンスのTTSエンジン設定を利用します。

    • 引数:

      • speaker (str | None): 正規化する話者名。

      • tts_name (str, オプション): 使用するTTSエンジン名。

    • 戻り値:

      • str | None: 正規化された話者名。

  • list_available_voices(self, tts_name=None, endpoint=None) 指定されたTTSエンジン(または現在のエンジン)で利用可能な音声リストを標準出力に表示します。

    • 引数:

      • tts_name (str, オプション): 音声リストを表示したいTTSエンジン名。

      • endpoint (str, オプション): VoiceVoxなどのAPIエンドポイント。

    • 戻り値:

      • bool: 処理が成功した場合は True、失敗した場合は False

  • show_voice_map(self, infile, voices, VOICE_MAPS, is_monologue, tts_name=None, endpoint=None) 入力ファイルから話者を解析し、指定された音声マッピングと組み合わせて、最終的な話者と音声のマッピングを標準出力に表示します。

    • 引数:

      • infile (str): テキスト入力ファイルのパス。

      • voices (str): セミコロン区切りの音声指定文字列。

      • VOICE_MAPS (dict): 既存の音声マッピング辞書。

      • is_monologue (bool): 独話形式かどうか。

      • tts_name (str, オプション): 使用するTTSエンジン名。

      • endpoint (str, オプション): VoiceVoxなどのAPIエンドポイント。

    • 戻り値:

      • bool: 処理が成功した場合は True、失敗した場合は False

  • load_text(self, input_path, monologue=False, wait_for_clipboard=True) tktts.load_text グローバル関数と同じ機能を提供します。

  • get_speakers_from_dialogue(self, dialogue) 対話データ dialogue から、重複のない話者名のリストを抽出して返します。

    • 引数:

      • dialogue (list[tuple[str | None, str]]): 対話のリスト。

    • 戻り値:

      • list[str | None]: 検出された話者名のリスト。

  • parse_kv_string(self, kv_string, keys=[], allow_no_key_kv_string=False) tktts.parse_kv_string グローバル関数と同じ機能を提供し、インスタンスの normalize_speaker を利用します。

  • update_voice_map(self, voice_map={}, voices="", speakers={}) 既存の voice_map を、指定された voices 文字列と speakers リストに基づいて更新します。

    • 引数:

      • voice_map (dict, オプション): 更新対象の音声マッピング辞書。

      • voices (str, オプション): セミコロン区切りの音声指定文字列。

      • speakers (list, オプション): 検出された話者名のリスト。

    • 戻り値:

      • dict[str | int | None, str]: 更新された音声マッピング辞書。

  • speak_dialogue(self, dialogue=None, voice_map=None, speakers={}, replacements=None, endpoint=None, output_format='mp3', config=None) tktts.speak_dialogue グローバル関数と同じ機能を提供し、インスタンスの設定 (config, endpoint など) を利用します。

main scriptとして実行したときの動作

tktts.py ライブラリには、Pythonスクリプトとして直接実行されたときに特別な処理を行う if __name__ == "__main__": ブロックが明示的に定義されていません。

しかし、スクリプトの冒頭に、必要な非標準ライブラリがすべてインストールされているかを確認するコードが含まれています。この部分は、tktts.py が直接実行された場合、または他のスクリプトからインポートされた場合のいずれにおいても、モジュールのロード時に実行されます。

具体的な動作:

  1. pydub, pyperclip, chardet, pyttsx3, openai, simpleaudio の各ライブラリがシステムにインストールされているかを確認します。

  2. これらのライブラリのいずれかが不足している場合、以下のエラーメッセージとインストール手順をコンソールに出力します。

    Error: Missing libraries:
    [不足しているライブラリ名]
    ------------------------------------------------------------------
    インストールが必要です:
      pip install pyttsx3 openai pydub chardet pyperclip
    
    [FFmpeg のインストール]
      pydub, simpleaudio の利用に必要です。公式サイトからダウンロードし、PATHを設定してください。
    ------------------------------------------------------------------
    
    Press ENTER to terminate>>
    
  3. ユーザーがEnterキーを押すのを待ち、その後 sys.exit(1) を呼び出してプログラムを終了します。

この動作により、tktts.py を利用する前に、必要な依存関係が満たされていることを確実にチェックし、不足している場合はユーザーに明確なガイダンスを提供します。