件名の通り、Windows端末でSlackのメッセージが書き込まれたらVOICEVOXで音声読み上げをやる記事です。
※記事はたくさん出てきたのですが、細かい内容の記載がなかったりしたので備忘録的に。。。
※前回同様、割と雑な記事ですみません。
1. Slack設定
以下のサイトを参考にさせていただきました。(Slackの設定はまんま下記の記事通りです)
https://dev.classmethod.jp/articles/slack-api-bolt-js-getting-start/
2. nodejsのインストール
下記サイトより推奨版をインストールしました。
https://nodejs.org/ja/
3. Visual Studioインストール(インストール後は再起動しましょう)
下記サイトを参考にインストールしました。
https://resanaplaza.com/visual-studio-2022-%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E6%89%8B%E9%A0%86/
※必ず「C++によるデスクトップ開発」ワークロードを選択してインストールしましょう。
4. VOICEVOXインストール
下記サイトよりダウンロードしてインストールします。
https://voicevox.hiroshiba.jp/
※自分はGPU/CPU版をインストールしました。
5. VOICEVOX起動
GUIでもコマンドプロンプトでもどちらでも。
もし、別ノードからアクセスさせることを前提にするなら下記の通り実施。
cd AppData\Local\Programs\VOICEVOX
run.exe --host [ローカルIP]
6. ライブラリインストール
適当なフォルダを作成して、下記コマンドを実行
npm init
npm install @slack/bolt
npm install node-fetch@2.6.1
npm install speaker
npm install web-audio-api
7. コード実装(app.js)
const { App } = require('@slack/bolt');
const fetch = require('node-fetch');
const { AudioContext } = require('web-audio-api');
const context = new AudioContext();
const Speaker = require('speaker');
const app = new App({
token: "xoxb-XXXXXXXXXXXXXXXXXXXX", #自分が取得した値に置き換えてください。
signingSecret: "XXXXXXXXXXXXXXXXXXXX", #自分が取得した値に置き換えてください。
socketMode: true,
appToken: "xapp-XXXXXXXXXXXXXXXXXXXX", #自分が取得した値に置き換えてください。
port: process.env.PORT || 3000
});
app.message(async ({ message }) => {
// 読み上げたいメッセージを Slack から取得
const msg = message.text;
// メッセージが存在しない場合は処理を終了
if (!msg) {
return;
}
// クエリ作成
const audio_query_response = await fetch(
"http://xx.xx.xx.xx:50021/audio_query?text=" + encodeURIComponent(msg) + "&speaker=0",
{
method: 'post',
headers: {'Content-Type': 'application/json'}
}
);
const audio_query_json = await audio_query_response.json();
// 音声合成
const synthesis_response = await fetch(
"http://xx.xx.xx.xx:50021/synthesis?speaker=0",
{
method: 'post',
body: JSON.stringify(audio_query_json),
headers: {"accept": "audio/wav", 'Content-Type': 'application/json'},
}
);
const synthesis_response_buffer = await synthesis_response.buffer();
// 再生
context.outStream = new Speaker({
channels: context.format.numberOfChannels,
bitDepth: context.format.bitDepth,
sampleRate: context.sampleRate
});
context.decodeAudioData(synthesis_response_buffer, function(audioBuffer) {
// サンプルレートを一致させる
const sourceSampleRate = audioBuffer.sampleRate;
const destinationSampleRate = context.sampleRate;
const ratio = sourceSampleRate / destinationSampleRate;
const length = audioBuffer.length / ratio;
const targetBuffer = context.createBuffer(
audioBuffer.numberOfChannels,
length,
destinationSampleRate
);
for (let channel = 0; channel < audioBuffer.numberOfChannels; channel++) {
const inputData = audioBuffer.getChannelData(channel);
const outputData = targetBuffer.getChannelData(channel);
for (let i = 0; i < length; i++) {
const index = i * ratio;
const floor = Math.floor(index);
const ceil = Math.ceil(index);
const fraction = index - floor;
const value = inputData[floor] + (inputData[ceil] - inputData[floor]) * fraction;
outputData[i] = value;
}
}
var bufferNode = context.createBufferSource();
bufferNode.connect(context.destination);
bufferNode.buffer = targetBuffer;
//bufferNode.loop = true;
bufferNode.start(0);
});
});
(async () => {
// Start your app
await app.start();
console.log('⚡️ Bolt app is running!');
})();
8. アプリ起動
作成したアプリを起動します。
node app.js
9. Slackへメッセージ書き込み
1番の手順で、作成したアプリを参加させたチャネルでメッセージを書き込んでみてください。うまく動作すればスピーカーから音声が聞こえてきます。