Microsoft Edge のTTSを簡単に使える「edge-tts」を試す
GitHubレポジトリ
edge-tts
edge-ttsは、Python コード内から、または提供されているedge-ttsまたはedge-playbackコマンドを使用して、Microsoft Edge のオンラインテキスト読み上げサービスを利用できる Python モジュールです。
インストール
Colaboratoryで。
パッケージインストール
!pip install edge-tts
!pip freeze | grep -i edge-tts
edge-tts==7.0.0
CLIでの利用(edge-ttsコマンド)
CLIはedge-ttsコマンドとedge-playbackコマンドがある。edge-ttsコマンドはファイルへの出力、edge-playbackコマンドはどうやらその場で再生される様子(mpvというCLIのプレイヤーが別途必要になる)
Colaboratoryだとその場で再生はできないと思うので、edge-ttsコマンドでファイル出力してIPythonで再生させて試す。
まずUsage。
!edge-tts --help
usage: edge-tts [-h] [-t TEXT] [-f FILE] [-v VOICE] [-l] [--rate RATE] [--volume VOLUME]
[--pitch PITCH] [--words-in-cue WORDS_IN_CUE] [--write-media WRITE_MEDIA]
[--write-subtitles WRITE_SUBTITLES] [--proxy PROXY]
Text-to-speech using Microsoft Edge's online TTS service.
options:
-h, --help show this help message and exit
-t TEXT, --text TEXT what TTS will say
-f FILE, --file FILE same as --text but read from file
-v VOICE, --voice VOICE
voice for TTS. Default: en-US-EmmaMultilingualNeural
-l, --list-voices lists available voices and exits
--rate RATE set TTS rate. Default +0%.
--volume VOLUME set TTS volume. Default +0%.
--pitch PITCH set TTS pitch. Default +0Hz.
--words-in-cue WORDS_IN_CUE
number of words in a subtitle cue. Default: 10.
--write-media WRITE_MEDIA
send media output to file instead of stdout
--write-subtitles WRITE_SUBTITLES
send subtitle output to provided file instead of stderr
--proxy PROXY use a proxy for TTS and voice list.
ではサンプル。
「Hello, World」と発話させたものをファイルに出力させてみる。
!edge-tts --text "Hello, world!" --write-media hello.mp3 --write-subtitles hello.srt
再生して確認
from IPython.display import Audio
display(Audio("hello.mp3", autoplay=True))
実際に生成されたものは以下
--write-subtitlesで字幕用のタイムスタンプ入りのテキストが出力される。
!cat hello.srt
1
00:00:00,050 --> 00:00:00,887
Hello world
音声は--voiceで指定できる。利用可能な音声の一覧は--list-voicesで確認できる。
!edge-tts --list-voices
めっちゃたくさんある。全142言語、全324音声。一部抜粋。
Name Gender ContentCategories VoicePersonalities
--------------------------------- -------- --------------------- --------------------------------------
af-ZA-AdriNeural Female General Friendly, Positive
af-ZA-WillemNeural Male General Friendly, Positive
am-ET-AmehaNeural Male General Friendly, Positive
am-ET-MekdesNeural Female General Friendly, Positive
ar-AE-FatimaNeural Female General Friendly, Positive
(snip)
ja-JP-KeitaNeural Male General Friendly, Positive
ja-JP-NanamiNeural Female General Friendly, Positive
(snip)
zh-TW-HsiaoChenNeural Female General Friendly, Positive
zh-TW-HsiaoYuNeural Female General Friendly, Positive
zh-TW-YunJheNeural Male General Friendly, Positive
zu-ZA-ThandoNeural Female General Friendly, Positive
zu-ZA-ThembaNeural Male General Friendly, Positive
日本語の場合は、男性用がja-JP-KeitaNeural、女性用がja-JP-NanamiNeuralになるみたい。
日本語で試してみる。
!edge-tts --voice ja-JP-KeitaNeural --text "あけましておめでとうございます。今年の競馬も楽しみですね!" --write-media jp_male.mp3
!edge-tts --voice ja-JP-NanamiNeural --text "あけましておめでとうございます。今年の競馬も楽しみですね!" --write-media jp_female.mp3
display(Audio("jp_male.mp3", autoplay=True))
display(Audio("jp_female.mp3", autoplay=True))
それぞれこんな感じ
発話を調整できる。
-
--rate: 発話スピード。%で指定。プラスで速く、マイナスで遅くなる。ex)+50%,-50% -
--volume: 発話の音量。%で指定。プラスで大きく、マイナスで小さくなる。ex)+50%,-50% -
--pitch: 声の高さ。Hzで指定。プラスで高く、マイナスで低くなる。ex)+50Hz,-50Hz
発話スピードを少し下げて、ボリュームを大きく、ピッチも上げてみた。
!edge-tts --voice ja-JP-KeitaNeural --text "あけましておめでとうございます。今年の競馬も楽しみですね!" --write-media jp_male_change.mp3 --rate=-20% --volume=+50% --pitch=+50Hz
display(Audio("jp_male_change.mp3", autoplay=True))
実際のものは以下
なお、以前はSSMLが使えていたようなのだが、今はもう使えないらしい。
Microsoft Edge 自体で生成できない SSML の使用を Microsoft が禁止しているため、カスタム SSML のサポートは廃止されました。つまり、カスタム SSML が役立つであろうすべてのケースはサポートできません。サービスでは、1つの <voice> タグ内に1つの <prosody> タグのみを許可しているためです。 <prosody> タグで使用できるカスタマイズオプションは、ライブラリまたはコマンドライン自体ですでに利用可能です。
Pythonでの利用
READMEには個別に書いていないのだが、以下にPythonで利用する場合のサンプルがある。
import edge_tts
from IPython.display import Audio
communicate = edge_tts.Communicate(
"あけましておめでとうございます。今年の競馬も楽しみですね!",
"ja-JP-NanamiNeural",
rate="+10%",
volume="+10%",
pitch="+10Hz",
)
communicate.save_sync("jp_female.mp3")
非同期の場合
import edge_tts
from IPython.display import Audio
import asyncio
# notebook環境では必要
import nest_asyncio
nest_asyncio.apply()
async def amain() -> None:
communicate = edge_tts.Communicate(
"あけましておめでとうございます。今年の競馬も楽しみですね!",
"ja-JP-NanamiNeural",
rate="+10%",
volume="+10%",
pitch="+10Hz",
)
await communicate.save("jp_female.mp3")
if __name__ == "__main__":
asyncio.run(amain())
非同期ストリーミング、かつ、字幕ファイルを生成する場合。
import edge_tts
from IPython.display import Audio
import asyncio
# notebook環境では必要
import nest_asyncio
nest_asyncio.apply()
async def amain() -> None:
communicate = edge_tts.Communicate(
"あけましておめでとうございます。今年の競馬も楽しみですね!",
"ja-JP-NanamiNeural",
rate="+10%",
volume="+10%",
pitch="+10Hz",
)
submaker = edge_tts.SubMaker()
with open("jp_female.mp3", "wb") as file:
async for chunk in communicate.stream():
if chunk["type"] == "audio":
file.write(chunk["data"])
elif chunk["type"] == "WordBoundary":
submaker.feed(chunk)
with open("jp_female.srt", "w", encoding="utf-8") as file:
file.write(submaker.get_srt())
if __name__ == "__main__":
asyncio.run(amain())
あとは、音声を個別に指定するのではなく、言語・性別・ロケール等で動的に選択するやり方についても記載がある。
特にAPIキー等不要で使えるようなのだけど、これはどういう理屈なんだろう?ドキュメント的なものを探してみたけど、見当たらなかった。
TTSのクオリティはそんなに悪くはないように思えるので、個人レベルでお手軽に使うにはありかもしれない。ただ、商用では流石に使えなさそう。