1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Node.jsでVOICEROIDをしゃべらせてみる

Last updated at Posted at 2024-10-14

概要

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本体の起動も必要です。
image.png
上記が完了している状態でnpm run devを実行すると、製品スキャンを行い、一番最初にリストアップされているキャラクターがしゃべるようになっています。
サンプルでは、ピッチ等も上げていますが、キャラクターによってはemotionsのテキスト等のパラメータを変更する必要がありそうなので、client.GetDefaultParams2で取得したデータと比較しながら書き換えてください。firstEntryの部分はCIDが入ります。CIDについては、AssistantSeikaのリファレンスを読むのがいいかと思います。

完成版

今回作成したものをリポジトリとしてアップしていますのでお使いください。

さいごに

今回は、AssistantSeikaのWCFClientを使用して動作させてみましたが、Web APIやSeikaSay2でも行けるようです。ただ、Web APIはAssistantSeika側で設定が必要なことや、SeikaSay2では読み上げに時間がかかったためWCFClientを採用しました。
Node.js側でVOICEROIDを制御できたので次はReact上で動かしてみたいです。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?