先ほどのJavaScriptコードを以下に再掲する。ある意味、これが以下で見ていくコードのスケルトンといえる。
const record = require('node-record-lpcm16');
const fs = require('fs');
const filename = 'test.raw';
const file = fs.createWriteStream(filename);
const encoding = 'LINEAR16';
const sampleRate = 16000;
// 指定したサンプリング周波数/エンコード/プログラムで音声を取り込む
record.start({
sampleRateHertz: sampleRate,
encoding: encoding,
recordProgram: 'sox' // macOSでは'rec'を指定
}).pipe(file);
setTimeout(function () {
record.stop();
}, 7000);
このコードでは、マイクから音声を取り込んでファイルに保存している。そこでまずはこの音声ファイルを認識して、日本語のテキストに変換する方法を見てみよう。
Speech APIを使用すると、音声ファイルをテキストに変換できる。ここでは、Speech API(およびそれをラップしている@google-cloud/speechパッケージ)が提供するrecognizeメソッドを使用する。このメソッドは同期的なメソッドであり、引数に認識対象のファイルと、認識に必要な構成情報(JSON形式)を取る。なお、Speech APIが提供する全APIについては「API とリファレンス」を参照のこと。
本稿では、認識に必要な構成情報としては以下のフィールドを指定している。
他のフィールドについては「RecognitionConfig」ページを参照されたい。なお、RecognitionConfigオブジェクトは、この後で紹介する「ストリーミングを使用して、マイクからの音声を認識するコード」でも使用する。
これらの情報を設定して、recognizeメソッドを呼び出す手順は次のようになる。ここでは、recognizeメソッドの戻り値はJavaScriptのPromiseオブジェクトなので、thenメソッドでこれを受け取って処理を行っている。
// Speech APIの組み込み
const speech = require('@google-cloud/speech');
// クライアントの作成
const speechClient = speech();
// 音声ファイル認識に必要な情報
const filename = 'tmp.raw';
const encoding = 'LINEAR16';
const sampleRate = 16000;
// 音声認識で使用するパラメーターの設定(エンコード/サンプリング周波数/言語)
const config = {
encoding: encoding,
sampleRateHertz: sampleRate,
languageCode: 'ja-jp',
};
speechClient.recognize(filename, config) // Speech API呼び出し
.then((results) => {
// 認識が完了した後の処理をここに記述
// results[0]から認識後のテキストを取り出せる
});
これを先ほどのnode-record-lpcm16パッケージを利用した音声取り込みコードと組み合わせると、次のようになる(recognitionViaFile.jsファイル)。
const record = require('node-record-lpcm16');
const speech = require('@google-cloud/speech');
const translate = require('@google-cloud/translate');
const fs = require('fs');
const speechClient = speech();
const translateClient = translate();
const filename = 'tmp.raw';
const file = fs.createWriteStream(filename);
const encoding = 'LINEAR16';
const sampleRate = 16000;
// 指定したエンコード/サンプリング周波数を用いてSoXによる
// 音声取り込みを開始し、それをファイルに保存
record.start({
encoding: encoding,
sampleRate: sampleRate,
recordProgram: 'sox' // macOSでは'rec'を指定
}).pipe(file);
console.log('talk to your PC/Mac in 7 secs');
// 音声認識で使用するパラメーターの設定(エンコード/サンプリング周波数/言語)
const config = {
encoding: encoding,
sampleRateHertz: sampleRate,
languageCode: 'ja-jp',
};
// 7秒後に取り込みを終了し、ファイルに保存された音声の認識を行う
setTimeout(function () {
record.stop();
speechClient.recognize(filename, config) // Speech API呼び出し
.then((results) => {
const text = results[0].replace(/まる/g, '。');
console.log(text);
});
}, 7000);
音声の取り込みは7秒後に自動的に終了するようにして(setTimeout関数に渡しているコールバック関数内でrecord.stopメソッドを呼び出している)、それに続けて、recognizeメソッドを呼び出している。上述した通り、このメソッドはPromiseオブジェクトを返すので、thenメソッドではその結果を受け取り、「まる」というテキストがあれば、それを「。」に置換したものをコンソールに表示している。
これを実行すると次のようになる。
> node recognitionViaFile.js
talk to your PC/Mac in 7 secs
ご注文はいかがいたしますか。俺はうなぎ
1人で原稿を書きながら、PC(Mac)に向かって発声するのは結構ばからしいのだが、このように日本語の音声を日本語のテキストに変換できる(languageCodeフィールドに'ja-jp'を指定したおかげだ)。ただ残念なことに、このコンソールアプリでは「talk to your PC/Mac in 7 secs」と表示されてから、実際に音声が取り込まれるまでのタイムラグが発生している。そこはサンプルなので実際に試してみようという人も許してほしい。後は、Translation APIを使って、これを英語に翻訳するだけだ。
Copyright© Digital Advantage Corp. All Rights Reserved.