概要
WebフレームワークでVOICEROIDを操作してみたいな~とふと考え付いたので、いずれReactなどで動かすためにまずはNode.jsでVOICEROIDを操作できるかという技術検証です。実際にReactでも動くかはまだ試せていないのでいずれやります。
Node.jsで動かす方法
といってもVOICEROID製品はほとんどC#で作られていることが多くNode.jsから直接制御するのは大変そうということがわかりました。ただ、調べるとどうやらAssistantSeikaというアプリケーションを使えば行けそうだということがわかりそのラッパーであるNode-Seikaというものがあることを知ったのでこれを使ってみようと思います。
使うライブラリなど
大前提として、喋らせるVOICEROIDの正規ライセンス、AssistantSeikaが必要になります。なお、AssistantSeikaはVOICEVOX等にも対応しているようなので持っていない方はそちらで代用してもいいかもしれません。
- Node.js(v20.10.0)
- TypeScript
- VOICEROID 製品
- AssistantSeika
実装してみる
それでは実装してみます。今回はNode.jsを使うということでせっかくなのでTypeScriptも使います。
今回はパッケージツールとしてnpmを使用していますがお好きなものに変えてください。
npm i -D @types-node concurrently nodemon ts-node typescript
インストール後、node-seika
を入れます。
npm i nusu-github/node-seika
ディレクトリにtsconfig.json
を作成し、次に置き換えます。
{
"compilerOptions": {
"module": "esnext",
"target": "es2020",
"strict": true,
"sourceMap": true,
"outDir": "dist",
"moduleResolution": "node",
"allowSyntheticDefaultImports": true
},
"include": ["src/**/*"]
}
次に、package.json
を修正します。
{
"name": "nodeseika-example",
"version": "1.0.0",
"main": "index.js",
+ "type": "module",
+ "scripts": {
+ "start": "node --experimental-specifier-resolution=node dist/index.js",
+ "dev": "tsc && concurrently \"tsc -w\" \"nodemon --experimental-specifier-resolution=node dist/index.js\"",
+ "build": "tsc"
},
"keywords": [],
"author": "Crysta1221",
"license": "ISC",
...
}
緑色になっている場所と対応する行を探し、置き換えてください。(デフォルトではscriptsの中身がtestのみになっているため、testを削除して上記のものに置き換えるほか、プロジェクトをmoduleとして認識させます)
次に、src/index.ts
を作成し、次のように置き換えます。
import { Wcfclient } from "node-seika";
const client = new Wcfclient();
// NodeSeikaのバージョン取得
console.log("[INFO] NodeSeika Version:");
const version = await client.Version();
console.log(version);
// VOICEROID製品のスキャン
console.log("[INFO] Scanning All VOICEROID Products...");
await client.ProductScan();
// 検出完了したキャラクター一覧を取得
console.log("[INFO] Listing scanned VOICEROID Products...");
const ver = await client.AvatorList();
console.table(ver);
// 最初のキャラの詳細を取得
const firstEntry = ver.entries().next().value?.[0];
if (firstEntry === undefined) {
throw new Error("No entries found in ver");
}
const logs = await client.GetDefaultParams2(firstEntry);
console.table(logs);
// しゃべらせる
console.log("[INFO] tts running");
await client.Talk(
firstEntry,
"こんにちは。きずなあかりです。のーどじぇいえすから実行しています。",
{ filepath: undefined, emotions: [["喜び", 0.3]] }
);
今回は、A.I.VOICEの紲星あかりを使っています。プログラムを実行する前にAssistantSeikaをダウンロードしてインストールして起動していること、使用したいVOICEROIDにチェックをいれておくほか、VOICEROID本体の起動も必要です。
上記が完了している状態でnpm run dev
を実行すると、製品スキャンを行い、一番最初にリストアップされているキャラクターがしゃべるようになっています。
サンプルでは、ピッチ等も上げていますが、キャラクターによってはemotions
のテキスト等のパラメータを変更する必要がありそうなので、client.GetDefaultParams2
で取得したデータと比較しながら書き換えてください。firstEntry
の部分はCIDが入ります。CIDについては、AssistantSeikaのリファレンスを読むのがいいかと思います。
完成版
今回作成したものをリポジトリとしてアップしていますのでお使いください。
さいごに
今回は、AssistantSeikaのWCFClientを使用して動作させてみましたが、Web APIやSeikaSay2でも行けるようです。ただ、Web APIはAssistantSeika側で設定が必要なことや、SeikaSay2では読み上げに時間がかかったためWCFClientを採用しました。
Node.js側でVOICEROIDを制御できたので次はReact上で動かしてみたいです。