はじめに
@yskmjp さんが enebular との組み合わせで使われている話を SNS で投稿などされていた「Koeiromap」が気になって、そして API を JavaScript で扱えたらと思い、技術情報周りを調べたりなどした際のメモです。
※ 見かけた投稿やツイートの一例はこちら↓
Koeiromap の概要
まず、「Koeiromap」に関する大まかな情報を書いてみます。
以下の情報は、記事執筆時点(2023年4月8日時点)のものです。最新情報は、公式ページをご確認ください。
- 音声合成が行えるサービス
- 公式サイト上・API経由で行える音声合成は、Koeiromap および関連するサービスの検証、開発、実用化等を目的として、期間限定で無償提供中(※ 利用に関して、注意事項あり)
- 注意時項の 1つ ⇒ 生成された音声の利用は「非商用利用限定」
- その他、データ利用範囲や動作保証などに関する内容があり、詳細は「Koeiromap & Koeiro APIご利用上の注意」を参照
上記の内容は「Koeiromap のページ」にアクセスした際に見られる、「Koeiromap & Koeiro APIご利用上の注意」の内容を見て書きました。
提供元
公式の Twitterアカウントは以下で、提供元は「rinna(株)」になるようです。
●Koeiromap【正式サービス化決定】(@ koeiromap)さん / Twitter
https://twitter.com/koeiromap
Koeiromap の仕様
音声合成のパラメータに関する仕様
音声合成の仕様について、API のパラメータ仕様から内容を確認してみます。
入力パラメータ
「Koeiromap のページ」で試す場合、上で書かれていたパラメータのうち「seed以外」が GUI上で設定できるっぽいです。
以下は、Koeiromap のページ上で text(合成したい文章)のみを指定してみた際の画面のキャプチャです。
「speaker_x」・「speaker_y」の値や、「style(全6通り: "talk", "happy", "sad", "angry", "fear", "surprised")」を変化させた時の合成音声への影響は、ページ上で実際に確認してみてください。
なお、音声合成を API経由で利用する場合は、パラメータの値をランダムに決める「seed」というシード値も指定できるようです。
出力パラメータ
音声合成用のデータは、「wav形式の音声データがbase64エンコードされた文字列」で返ってくるようです。
音声合成を API経由で試してみる
実際に、API経由で音声合成を試してみます。その場合、公式の情報を見ると POSTリクエストで扱う形のようです。
公式の APIガイドで、curl を用いた例が示されています。
curl を使って試す
上で書いた、入力パラメータに関する仕様の記載によると、必須パラメータは「合成したい文章を日本語で書いた "text" のみ」のようです。
公式サンプルで、必須パラメータのみを残したコマンドは、以下になるようです。
curl --location 'https://api.rinna.co.jp/models/cttse/koeiro' --header 'Content-Type: application/json' --data '{"text": "こんにちは"}'
上記のコマンドを実行して、レスポンスが得られることを確認できました。
実行結果では、「wav形式の音声データがbase64エンコードされた文字列」の部分がかなり長くなりました。そのため、以下のコマンドを実行して、レスポンスをテキストに書き出し、その内容のエンコードされた文字列部分などを省略した内容を掲載してみます。
curl --location 'https://api.rinna.co.jp/models/cttse/koeiro' --header 'Content-Type: application/json' --data '{"text": "こんにちは"}' -o 【出力先のパス】/koeiro.txt
{
"audio": "data:audio/x-wav;base64,【base64エンコードされた文字列】",
"phonemes": [
"sil","k","o","N","n","i","ch","i","w","a","sil"
],
"seed": 【用いられたSeed値】
}
なお、オプションのパラメータ「speaker_x・speaker_y・style」を指定した場合も、レスポンスとして得られる JSON の構造は、上記と同じでした。
JavaScript で試す
それでは、JavaScript から API を使ってみます。
とりあえず簡単に試せる方法として、ブラウザの Fetch API を使ったやり方を試します。
プログラムは、以下の必須パラメータのみを指定した curlコマンドを元に、ChatGPT(GPT-3.5版)に作ってもらいました。
curl --location 'https://api.rinna.co.jp/models/cttse/koeiro' --header 'Content-Type: application/json' --data '{"text": "こんにちは"}'
ChatGPT のページ上でのやりとりの様子は以下のとおりです。
得られた結果は以下のとおりで、そのまま動作させられるものが出てきました。
fetch('https://api.rinna.co.jp/models/cttse/koeiro', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
text: 'こんにちは'
})
})
.then(response => response.json())
.then(data => console.log(data));
それでは、簡単に試せるやり方で、具体的にはブラウザの開発者ツールのコンソールで実行するやり方で、レスポンスの内容を確認します。その結果、以下のように「wav形式の音声データがbase64エンコードされた文字列」が得られていることを確認できました。
あとは、音声データを再生する部分を付け足します。
この処理の前提として、「単発で実行して、とりあえず試せれば良い(そして、シンプルな処理にする)」という想定をしています。
具体的には、得られたレスポンスの audio
の部分、つまり「wav形式の音声データがbase64エンコードされた文字列」を取り出し、そのデータを再生する処理を付け加えれば OK です。
ブラウザで動かすなら、HTMLAudioElement を使った、以下の処理で再生できます。
const voice = new Audio("data:audio/x-wav;base64,【base64エンコードされた文字列】");
voice.play();
それを加えた内容は、以下のとおりです。
fetch("https://api.rinna.co.jp/models/cttse/koeiro", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
text: "こんにちは",
}),
})
.then((response) => response.json())
.then((data) => {
console.log(data.audio);
const voice = new Audio(data.audio);
voice.play();
});
これを実行して、合成された音声が再生されることを確認できました。
【追記】 その後のお試し
その後、p5.js を使った実装も試してみました。
こちらでは、base64エンコードされた文字列の声データを、音として再生する部分で「p5.MediaElement」を使っています。