はじめに
VOICEVOXは皆さんご存知でしょうか?
VOICEVOXは音声合成ソフトで、ずんだもんなどの合成音声を作成することができます。
個人的な私の推しは「春日部つむぎ」と「冥鳴ひまり」です。
そんなVOICEVOXですがなんと無料で利用することができる上に、なんとAPIまで提供されてるのです!
いやー助かるーー。
この記事ではそんなVOICEVOXをPower Platformで利用して、テキストを読み上げてもらうやり方の基礎をまとめた記事です。
実際動かしてみた動画はこちら。
#PowerApps でVOICEVOXを利用してテキストを読み上げてもらいました。
— コルネ (@koruneko32767) April 16, 2023
※音が出るので注意! pic.twitter.com/C7hhunZXBx
VOICEVOXのAPI仕様について
VOICEVOXのAPIはAPIサーバを公式が提供しているわけではなく、VOICEVOXを起動するとGUIアプリケーションだけでなく、ローカルにHTTPサーバが立ち上がるのでそのHTTPサーバを叩くことでAPIを利用することができるようになっています。
VOICEVOXを起動してみた後、http://localhost:50021/docsにアクセスしてみてください。
すると下記のようなOpenAPIの仕様を確認することができます。
他パラメータなどの仕様を確認したい場合は以下公式ドキュメントも役に立ちつと思います。
ちなみにDocker Imageも用意されています。
Power Platformからlocalhostを呼び出す
Power AppsやPower Automateからlocalhostにアクセスするには、オンプレミスデータゲートウェイを利用する必要があります。
オンプレミスデータゲートウェイの設定は私が以前投稿した下記記事を参考にしてください。
"Base Resource URL"が"http://localhost:50021"になりますね。
接続の作成が完了したらPower AutomateのHTTP with AzureADアクションで適当なAPIを叩いてみてください。
設定が問題なければlocalhostのAPIが実行できるはずです。
Power Appsで入力されたテキストを音声合成する
Power AppsでHTTP with Azure ADアクションを利用する(できなかった)
Power AppsにHTTP with AzureADコネクタを追加して呼び出してみたのですが、以下エラーが発生して上手くいかなかったのでPower Automateから呼び出すことにしました。
HTTP with AzureADなんもわからん。
Power Automateでテキストを合成音声に変換する
フローの全体像はこんな感じ。
Power Appsからは最低限のパラメータとして、変換したいテキストだけを渡すようにしています。
まずは音声合成用のクエリを作成します。
POST /audio_query
実際のアクションはこんな感じ。
要求のURLは以下です。
http://localhost:50021/audio_query?text=@{triggerBody()['text']}&speaker=1
"speaker"で選んだキャラクターでクエリが作成されます。
speaker=1
だと、ずんだもんのあまあまらしいです。
"speaker"は以下で一覧を取得できます。
GET http://localhost:50021/speakers
続いて先ほどのアクションで出力されたクエリを基に音声ファイルを作成します。
APIは以下ですね。
POST /synthesis
実際のアクションはこんな感じ。
要求のURLは以下です。
http://localhost:50021/synthesis?speaker=1&enable_interrogative_upspeak=true
"enable_interrogative_upspeak"は「疑問系のテキストが与えられたら語尾を自動調整する」オプションです。
Defaultがtrue
なので省略してもOK。
要求の本文は以下を指定しています。
setProperty( body('HTTP_要求を呼び出します(audio_query)'), 'volumeScale', 5 )
"volumeScale"はボイスの音量です。
デフォルトだとPower Appsで再生したときに少し小さかったのでここで調整しています。
もっと大きくしたい場合はここのパラメータを調整してください。
その他にも以下スキーマが存在するようなので各自好みで調整してください。
このアクションで出力されたwavファイルをPower Appsに返します。
ただしそのまま返してもPower AppsのAudioコントロールで再生できないので少し加工します。
"/synthesis"で出力された結果は以下のような形式で返ってきます。
{ "$content-type": "audio/wav", "$content": "..." }
Power Appsでこれを再生可能な形式に変換するにはDataUri形式に変換してあげる必要があります。
よってPower Appsに返す値は以下のようにしてください。
dataUri(body('HTTP_要求を呼び出します(synthesis)')
Power AppsからPower Automateを呼び出す
最後にPower Appsから先ほど作成したPower Automateを呼び出して、返ってきた値をAudioコントロールにセットします。
先ほどのPower Automateの作成でほぼほぼできてるのでここは消化試合ですね。
Power AppsからPower Automateにはテキストを渡します。
ただし、渡すテキストはエンコードされたテキストを渡します。
Set( synthesis, VOICEVOX.Run(EncodeUrl(TextInput1.Text)).media );
フロー側でエンコードしてもよかったんですけどね。お好みで。
最後にAudioコントロールにPower Automateから返ってきた音声をセットします。
Audio.Media
synthesis
これでPower Appsでお手軽に、しかして高性能なテキスト読み上げ機能を実装することができます。
おわりに
今回ご紹介した方法だと、アプリ利用者のローカルでHTTPサーバが立ち上がっている必要があります。
なので多くの人に利用してもらおうとするともう一工夫必要になってきますね。
いくつか解決策はあると思いますが、解決方法の一例をあげるとDocker Imageも公開されていることですので、Azure Functionsとかにデプロイしてあげるといいんじゃないでしょうか?
もしくはVOICEVOXの辞書機能などを考慮するとAzure Container Appsも選択肢の一つとしていいですかね?
(MSサービス関連の紹介でしたのであえてAzureに限定して記載しましたが、もちろんLambdaやECSなんかでもいいと思いますよ!)