Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
15
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

@7shi

PythonでWindows 10の音声合成を使用する

以下の記事で作成した VBScript のコードを移植して、簡単に使えるようにコマンド化します。

このコマンドで動画を作成する方法は以下の記事を参照してください。

発音の指定方法については以下の記事を参照してください。

他の言語での利用については以下の記事を参照してください。

準備

Windows 10 でサポートされる音声の一覧です。

日本語以外の言語を使用する場合は追加します。

COM を使用するため pip で pywin32 をインストールします。

ライブラリのインストール
py -m pip install pywin32

移植

使用可能な音声を取得します。

voices2.py
import win32com.client
cat  = win32com.client.Dispatch("SAPI.SpObjectTokenCategory")
cat.SetID(r"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech_OneCore\Voices", False)
for token in cat.EnumerateTokens():
    print(token.GetDescription())
実行結果
Microsoft Ayumi - Japanese (Japan)
Microsoft Naayf - Arabic (Saudi)
Microsoft Ivan - Bulgarian (Bulgaria)
Microsoft Herena - Catalan (Catalan)
Microsoft Jakub - Czech (Czech Republic)
(以下略)

音声を指定して読み上げる例です。

sayaka.py
import win32com.client
sapi = win32com.client.Dispatch("SAPI.SpVoice")
cat  = win32com.client.Dispatch("SAPI.SpObjectTokenCategory")
cat.SetID(r"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech_OneCore\Voices", False)
v = [t for t in cat.EnumerateTokens() if t.GetAttribute("Name") == "Microsoft Sayaka"]
if v:
    oldv = sapi.Voice
    sapi.Voice = v[0]
    sapi.Speak("こんにちは、世界")
    sapi.Voice = oldv

【注意】 ソースは UTF-8 で保存してください。

音声をファイル sayaka.wav に出力する例です。

sayaka-wav.py
import win32com.client
sapi = win32com.client.Dispatch("SAPI.SpVoice")
cat  = win32com.client.Dispatch("SAPI.SpObjectTokenCategory")
cat.SetID(r"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech_OneCore\Voices", False)
v = [t for t in cat.EnumerateTokens() if t.GetAttribute("Name") == "Microsoft Sayaka"]
if v:
    fs = win32com.client.Dispatch("SAPI.SpFileStream")
    fs.Open("sayaka.wav", 3)
    sapi.AudioOutputStream = fs
    oldv = sapi.Voice
    sapi.Voice = v[0]
    sapi.Speak("こんにちは、世界")
    sapi.Voice = oldv
    fs.Close()

COM さえ使えてしまえば、後は普通の Python です。

コマンド

読み上げや保存を簡単に行えるようにするためコマンド化しました。他から参照すればライブラリとしても使えます。

使用例
py wintts.py -l
py wintts.py -l ja en
py wintts.py こんにちは、世界
py wintts.py -v sayaka -r 5 こんにちは、世界
py wintts.py -v sayaka -o sayaka.wav -i hello.txt
py wintts.py -v zira -p "h eh - l ow 1"
py wintts.py -v zira -s ipa "hɛ.ˈloʊ"

WSL

WSL の Python から COM は呼べませんが、WSL から Windows 側の Python を呼ぶことはできます。

wintts.py をどこか Windows から見える場所に置きます。次のような簡単なラッパーを書いて、WSL でパスが通っている場所に置いて実行属性を付けます。

wintts
#!/bin/sh
py.exe 'C:\スクリプト置き場\wintts.py' "$@"

これであたかも WSL のコマンドのように使うことができます。

使用例
$ py wintts.py -l de fr
de-AT, German (Austria): Microsoft Michael
de-CH, German (Switzerland): Microsoft Karsten
de-DE, German (Germany): Microsoft Hedda
de-DE, German (Germany): Microsoft Katja
de-DE, German (Germany): Microsoft Stefan
fr-CA, French (Canada): Microsoft Caroline
fr-CA, French (Canada): Microsoft Claude
fr-CA, French (Canada): Microsoft Nathalie(Canada)
fr-CH, French (Switzerland): Microsoft Guillaume
fr-FR, French (France): Microsoft Hortense
fr-FR, French (France): Microsoft Julie
fr-FR, French (France): Microsoft Paul
$ wintts -v julie bonjour
$ wintts -o de.wav -v hedda guten tag
$ winplay de.wav

最後に呼び出している winplay は、以下の記事で作成した自作スクリプトです。

関連リンク

この記事を書いた後に、いくつか Python で SAPI を扱う記事などを見掛けたので追記します。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
15
Help us understand the problem. What are the problem?