C#でVoicevoxのAPIを操作する方法
C#でVoicevoxのAPIを操作
半年ほど前に話題になったVOICEVOXについて、気になったのでインストールして遊んでみた。
普通に使用する場合は、こちらのリンクに記載のダウンロード方法や使い方を参考にGUIで操作が可能です。
GUI操作の場合は、そこまで使い方に悩むことなく合成音声を作成して遊ぶことが可能です。
ただしかし、GUI操作だと他プログラムから操作することができないので、今回はVOICEVOXを立ち上げると使用できるAPIを活用する方法を紹介します。
なお、今回は私が使い慣れているC#で構築してみます。
下準備
先程APIを利用すると言いましたが、VOICEVOXはexeを起動するとデフォルトでLoaclhostの50021ポートでサーバを立てます。
この状態であれば、localhost:50021宛に通信を行うとレスポンスを得ることができるのです。
ちなみに起動オプションでIPアドレスを指定してあげれば、そのIPアドレスでサーバ起動することができます。
VOICEVOXをダウンロードしたら、下記コマンドをコンソールで実行します。
※通常は「C:\Users\ユーザー名\AppData\Local\Programs\VOICEVOX」にダウンロードされているはず。
C:\Users\ユーザー名\AppData\Local\Programs\VOICEVOX\run.exe --host 192.168.0.5
「--host」以降はIPを指定しない場合は不要です。
起動ができたら、ブラウザを立ち上げ下記リンクでアクセスしてみてください。
http://192.168.0.5:50021/docs
するとAPI情報を確認することができるページが開くはずです。必要となるAPIはこの画面で調べます。※なおアプリ起動の際に「--host」以降を指定していない場合は「htpp://localhost:50021/docs」になります。以降必要に応じて「192.168.0.5」と「localhost」を読み替えてください。
APIを呼び出すコードを作成
準備ができたので、いよいよC#でコードを記載していきます。この記事の最後にサンプルを載せているGitのリンクを貼っているので参考にしてみてください。
先程のAPI一覧の画面で最低限必要になるAPIを確認すると「audio_query」と「synthesis」であることがわかります。
それぞれのAPI詳細に必要になるパラメータとリクエストの記載が確認できるので、1つ1つ作成をしていきます。
- audio_queryの作成
必要になるパラメータは「読み上げるテキスト」と「話者番号」です。
話者番号は一覧などが確認できていないので、どの値でどのキャラクターなのかは1回ずつ確認するしかない気がします。
ちなみに「1」はずんだもんです。笑
仮に「こんにちは」を「ずんだもん」に読み上げさせるためのクエリ作成は、下記リクエストになります。
curl -X 'POST' \ 'http://192.168.0.5:50021/audio_query?text=%E3%81%93%E3%82%93%E3%81%AB%E3%81%A1%E3%81%AF&speaker=1' \ -H 'accept: application/json' \ -d ''これをC#用に変換します。すると
using (var httpClient = new HttpClient())
{
using (var request = new HttpRequestMessage(new HttpMethod("POST"), "http://192.168.0.5:50021/audio_query?text=こんにちは&speaker=1"))
{
request.Headers.TryAddWithoutValidation("accept", "application/json");
request.Content = new StringContent("");
request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/x-www-form-urlencoded");
var response = await httpClient.SendAsync(request);
}
}
になります。
続いて先程のクエリ作成リクエスト出えたJSONをもとに作成リクエストを作成します。
必要になるパラメータは「話者番号」と「疑問形の語尾調整」です。
個人的にまた話者番号を指定するのか。。と思いましたが、再度パラメータに組み込みます。
再度ずんだもんで読み上げさせる場合のリクエストは下記になります。
※-dの"JsonData"には先程audio_queryで入手したデータを投入します
curl -X 'POST' \ 'http://192.168.0.5:50021/synthesis?speaker=1&enable_interrogative_upspeak=true' \ -H 'accept: audio/wav' \ -H 'Content-Type: application/json' \ -d '"JSOLData"'これをC#用に変換します。
using (var httpClient = new HttpClient())
{
using (var request = new HttpRequestMessage(new HttpMethod("POST"), "http://192.168.0.5:50021/synthesis?speaker=1&enable_interrogative_upspeak=true"))
{
request.Headers.TryAddWithoutValidation("accept", "audio/wav");
request.Content = new StringContent("\"JSOLData\"");
request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");
var response = await httpClient.SendAsync(request);
}
}
です。なお、「response.StatusCode」で条件分岐しているところは、Voicevoxで作成した音声データをファイル化する処理を組み込んでいます。
以上でVoicevoxのAPIを呼び出すコードの作成は完了です。さいごにこれをそれっぽくクラス化しておきます。
public class VoicevoxFunction
{
private readonly string ipPort;
public VoicevoxFunction(string _ipAdress, string _port)
{
ipPort = "http://" + _ipAdress + ":" + _port;
}
private async Task MakeQuery(string _text, int _speakerId)
{
string jsonQuery;
using (var httpClient = new HttpClient())
{
string url = ipPort + "/audio_query?text=" + _text + "&speaker=" + _speakerId;
using (var request = new HttpRequestMessage(new HttpMethod("POST"), url))
{
request.Headers.TryAddWithoutValidation("accept", "application/json");
request.Content = new StringContent("");
request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/x-www-form-urlencoded");
var response = await httpClient.SendAsync(request);
jsonQuery = await response.Content.ReadAsStringAsync();
}
}
return jsonQuery;
}
public async Task MakeSound(string _title, string _text, bool _upspeak, int _speakerId)
{
using (var httpClient = new HttpClient())
{
string url = ipPort + "/synthesis?speaker=" + _speakerId + "&enable_interrogative_upspeak=" + _upspeak;
using (var request = new HttpRequestMessage(new HttpMethod("POST"), url))
{
request.Headers.TryAddWithoutValidation("accept", "audio/wav");
request.Content = new StringContent(await MakeQuery(_text, _speakerId));
request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");
var response = await httpClient.SendAsync(request);
if (response.StatusCode == HttpStatusCode.OK)
{
string fileName = _title + ".wav";
using (var fileStream = File.Create(fileName))
{
using (var httpStream = await response.Content.ReadAsStreamAsync())
{
httpStream.CopyTo(fileStream);
fileStream.Flush();
}
}
}
else
{
Console.WriteLine("Error");
}
}
}
}
}
VoicevoxFunctionのインスタンス化時にアクセス先のIPアドレスとポート番号を指定します。これでいちいちメソッド呼び出しの際にIP情報を記載する必要性がなくなります。
稼働確認
先程作成したコードを呼び出す処理をメインメソッドに記載して稼働確認を行います。
稼働確認なので簡単な記載で済ませます。
VoicevoxFunction voicevoxFunction = new("192.168.0.5", "50021");
await voicevoxFunction.MakeSound("sample", "こんにちは世界", true, 1);
これを実行すると、所定のフォルダにWAVファイルが作成されていることがわかります。あとはこれを再生して合成音声が作成できているかの確認を行って完了です。
現状「MakeSoundメソッド」を呼び出すだけなので、引数をいじってあげれば読み上げテキストや話者を変更することが可能です。
さいごに
今回はVoicevoxのAPIを使う方法。特にC#で呼び出す方法をまとめました。
作成したコードの全量はGitに公開しているので合わせて参考にしてみてください。そのままVisualStudioにクローンすれば最低限の動きはするはずです。
必要に応じてIPなどの情報を更新してください。
・https://github.com/flying-YT/Voicevox4net
今回はこのへんで。ではまた。
小話
スペック面の話。。
私はVoicevox用のサーバをHyper-v上のWindowsに立てています。そのためVoicevoxはGPUなし版を使っています。そのためか読み上げ処理作成時にCPU使用率が70%を超えます。
また動的メモリで特段上限を設定していないので、このサーバだけで20GB以上確保しています。。しかも処理が終了しても開放してくれないので、日次再起動を入れています。

コメント
コメントを投稿