Elsaの技術日記(徒然なるままに)

主に自分で作ったアプリとかの報告・日記を記載

MENU

pythonでテキストや文字列を読み上げる

今回はpythonでテキストや文字列を読み上げる方法についてまとめていきます。



■準備

今回読み上げを行うにあたり、pyttsx3を用います。

【pyttsx3とは】
pyttsx3は、pythonのテキスト読み上げ変換ライブラリです。
代替ライブラリとは異なり、オフラインで動作し、Python2と3の両方と互換性があります。

pyttsx3は下記でインストールが可能です。

pip install pyttsx3

or 

pip3 install pyttsx3

自分は発生しなかったのですが、、
もしこちらのようなエラーメッセージが出た場合、pypiwin32のインストールが必要なようです。

No module named win32com.client

or 

No module named win32

or

No module named win32api

pypiwin32をインストールするためには、

pip install pypiwin32

or 

pip3 install pypiwin32

でOK。

■簡単な文字列を読み上げてみる

では早速、簡単な文字列の読み上げのためのコードです。
コードはこちら。

import pyttsx3

engine = pyttsx3.init()
engine.say("こんにちは。こんばんは。")
engine.runAndWait()

こちらを実行すると、

こんにちは。こんばんは。

と音声が出力されるかと思います。

■英語の文章を読み上げてみる。

次に英語をしゃべらせてみます。
デフォルトだと日本語になっているので、

engine.say("Hello world")

としても、日本語の発音で英文を読むだけになってしまい、
ネイティブが発音したようにはいきません。

そこで、発話するidを切り替える必要があります。
現在登録されているidを確認するコードはこちら。

import pyttsx3

engine = pyttsx3.init()
voices = engine.getProperty('voices')
for voice in voices:
    print("Voice: %s" % voice.name)
    print(" - ID: %s" % voice.id)

こちらを実行すると、各種IDや言語が一覧で出力されます。
今回はついでに人物名も出力しています。

自分の環境では、

Voice: Microsoft Haruka Desktop - Japanese
 - ID: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech\Voices\Tokens\TTS_MS_JA-JP_HARUKA_11.0

Voice: Microsoft Zira Desktop - English (United States)
 - ID: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech\Voices\Tokens\TTS_MS_EN-US_ZIRA_11.0

となります。

コードを見ると分かるように、voicesが配列になっております。
2番目に出力された、

Microsoft Zira Desktop - English (United States)

が英語のようですので、idを指定して出力させてみたいと思います。
コードはこちら。

import pyttsx3

engine = pyttsx3.init()
voices = engine.getProperty('voices')
engine.setProperty("voice", voices[1].id)
engine.say("Hello world")
engine.runAndWait()

こちらを実行することでネイティブな発音で、"Hello world"が出力されます。

■音量や発話速度を変更

デフォルトのままですと、個人的に少し読み上げるのが早い気がします。
そこで、速度を落としたり音量を変化させたりしてみたいと思います。

まずは、発話速度です。
速度の設定は、

engine = pyttsx3.init()
rate = engine.getProperty('rate')
engine.setProperty('rate', 発話速度)

で可能です。
このrateですが、
1分あたりの単語数で表した整数の発話速度。
とのこと。

自分は、

engine = pyttsx3.init()
rate = engine.getProperty('rate')
engine.setProperty('rate', rate-50)

とすることにしました。

次に音量ですが、

engine = pyttsx3.init()
rate = engine.getProperty('rate')
engine.setProperty('volume', 音量)

でプロパティの設定が可能です。
音量ですが、0.0 ~ 1.0までの範囲で設定が可能なようです。

■読み上げた音声を録音する

音声を録音するためには、

engine.save_to_file(文字列 , '出力ファイル名')

で実行可能です。
例えば、

import pyttsx3

engine = pyttsx3.init()
voices = engine.getProperty('voices')
engine.save_to_file("Hello world" , 'hello.mp3')
engine.runAndWait()

といったコードを作成し、実行すると
hello.mp3が生成され、再生すると
Hello world
と出力されるかと思います。

■テキストを読み上げてみる

最後に、これらの上記を組み合わせてテキストを読み上げてみたいと思います。
コードはこちら。

import pyttsx3

engine = pyttsx3.init()
rate = engine.getProperty('rate')
engine.setProperty('rate', rate-50)

with open("file.txt",encoding="utf-8") as f:
    s = f.read()
    engine.save_to_file(s , 'japan.mp3')
    engine.say(s)
    engine.runAndWait()

file.txtには下記文言を格納しました。

文がいくつか集まり、かつ、まとまった内容を表すもの。内容のうえで前の文と密接な関係をもつと考えられる文は、そのまま続いて書き継がれ、前の文と隔たりが意識されたとき、次の文は行を改めて書かれる。すなわち、段落がつけられるということであり、これは、書き手がまとまった内容を段落ごとにまとめようとするからである。この、一つの段落にまとめられる、いくつかの文の集まりを一文章というが、よりあいまいに、いくつかの文をまとめて取り上げるときにそれを文章と称したり、文と同意義としたりすることもあるなど文章はことばの単位として厳密なものでないことが多い。これに対して、時枝誠記(ときえだもとき)は、文章を語・文と並ぶ文法上の単位として考えるべきことを主張し、表現者が一つの統一体ととらえた、完結した言語表現を文章と定義した。これによれば、一編の小説は一つの文章であり、のちに続編が書き継がれた場合には、この続編をもあわせたものが一つの文章ということになる。俳句、和歌の一句・一首は、いずれも一つの文章であり、これをまとめた句集・歌集は、編纂(へんさん)者の完結した思想があることにおいて、それぞれ一つの文章ということになる。

こちらのテキストを元にコードを実行するとテキストが読み上げられるかと思います。
また、japan.mp3が生成されるかと思います。

次に英語です。
英語の場合には、idの切り替えが必要になりますので、

import pyttsx3

engine = pyttsx3.init()
voices = engine.getProperty('voices')
engine.setProperty("voice", voices[1].id)
rate = engine.getProperty('rate')
engine.setProperty('rate', rate-50)

with open("file2.txt",encoding="utf-8") as f:
    s = f.read()
    engine.save_to_file(s , 'us.mp3')
    engine.say(s)
    engine.runAndWait()

これでOKです。

file2.txtにこちらを書き込んで実行してみると、

Kishida calls election for end of October
Fumio Kishida became Japan’s prime minister on Oct. 4. He was elected by lawmakers in the Diet’s two houses.
Later the same day, Kishida told reporters that he will call a general election on Oct. 31.
The 64-year-old takes office as Japan continues to struggle with the pandemic. He said he wants to fight the coronavirus and make drastic changes to the economy.

英語でテキスト読み上げが実行されます。
また、us.mp3が生成されるかと思います。

■最後に

今回は日本語や英語テキストの読み上げ方法に関してまとめてみました。