google-tts-apiからHOYA社のVoice Text Web APIへ
Google Home Notifierは、テキストをgoogle-tts-apiを用いて、音声変換を実施しております。十分に内容は把握できますし、実利用には支障はないのですが、HOYA社より優れたWeb APIが公開されているので、HOYA社のVoice Text Web APIを用いた音声に変更を実施します。HOYA株式会社 VoiceText Web API
- HOYA社Voice Text Web APIの利用登録
- 「voicetext」のインストール
- google-home-notifierソースコード修正
参考サイト
前提条件
- (Raspberry Piの)Google Home Notifier導入が終わっている「google-home-notifier」導入
- (Raspberry Piの)PHPが動作するWEBサーバがセットアップされている
導入手順
1.HOYA社Voice Text Web APIの利用登録
HOYA株式会社 VoiceText Web APIの「無料利用登録」より利用登録を実施して下さい。利用登録後に、API KEYがメールで送付されて来ます。
2.「voicetext」のインストール
以下のコマンドで、「voicetext」をインストールします。
@raspberrypi:~ $ cd google-home-notifier/ @raspberrypi:~/google-home-notifier $ sudo npm update @raspberrypi:~/google-home-notifier $ sudo npm install voicetext npm WARN deprecated superagent@0.18.2: Please note that v5.0.1+ of superagent removes User-Agent header by default, therefore you may need to add it yourself (e.g. GitHub blocks requests without a User-Agent header). This notice will go away with v5.0.2+ once it is released. + voicetext@0.0.7 updated 1 package and audited 293 packages in 5.994s found 8 vulnerabilities (3 low, 3 moderate, 2 high) run `npm audit fix` to fix them, or `npm audit` for details ╭────────────────────────────────────────────────────────────────╮ │ │ │ New minor version of npm available! 6.9.0 → 6.10.0 │ │ Changelog: https://github.com/npm/cli/releases/tag/v6.10.0 │ │ Run npm install -g npm to update! │ │ │ ╰────────────────────────────────────────────────────────────────╯ @raspberrypi:~/google-home-notifier $ sudo npm install -g npm /usr/local/bin/npm -> /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npx -> /usr/local/lib/node_modules/npm/bin/npx-cli.js + npm@6.10.0 added 14 packages from 10 contributors, removed 5 packages and updated 17 packages in 30.759s
3.google-home-notifierソースコード修正
「google-home-notifier.js」ファイルの修正
以下を参考に2箇所追加および1箇所コメントアウト(削除)を実施します。
var Client = require('castv2-client').Client; var DefaultMediaReceiver = require('castv2-client').DefaultMediaReceiver; var mdns = require('mdns'); var browser = mdns.createBrowser(mdns.tcp('googlecast')); var deviceAddress; var language; //Add ((((((((((( var VoiceTextWriter = require('./VoiceTextWriter'); var voiceTextWriter = new VoiceTextWriter(); //Add )))))))))) var device = function(name, lang = 'en') { device = name; language = lang; return this; }; var ip = function(ip, lang = 'en') { deviceAddress = ip; language = lang; return this; } var googletts = require('google-tts-api'); var googlettsaccent = 'us'; var accent = function(accent) { googlettsaccent = accent; return this; } var notify = function(message, callback) { if (!deviceAddress){ browser.start(); browser.on('serviceUp', function(service) { console.log('Device "%s" at %s:%d', service.name, service.addresses[0], service.port); if (service.name.includes(device.replace(' ', '-'))){ deviceAddress = service.addresses[0]; getSpeechUrl(message, deviceAddress, function(res) { callback(res); }); } browser.stop(); }); }else { getSpeechUrl(message, deviceAddress, function(res) { callback(res); }); } }; var play = function(mp3_url, callback) { if (!deviceAddress){ browser.start(); browser.on('serviceUp', function(service) { console.log('Device "%s" at %s:%d', service.name, service.addresses[0], service.port); if (service.name.includes(device.replace(' ', '-'))){ deviceAddress = service.addresses[0]; getPlayUrl(mp3_url, deviceAddress, function(res) { callback(res); }); } browser.stop(); }); }else { getPlayUrl(mp3_url, deviceAddress, function(res) { callback(res); }); } }; var getSpeechUrl = function(text, host, callback) { //Delete (((((((((( // googletts(text, language, 1, 1000, googlettsaccent).then(function (url) { // onDeviceUp(host, url, function(res){ // callback(res) // }); // }).catch(function (err) { // console.error(err.stack); // }); //Delete ))))))))) //Add ((((((((( voiceTextWriter.convertToText(text).then(function(result, reject){ onDeviceUp(host, result, function(res){ callback(res) }); }).catch(function onRejected(error){ console.error(error); }); //Add ))))))))) }; var getPlayUrl = function(url, host, callback) { onDeviceUp(host, url, function(res){ callback(res) }); }; var onDeviceUp = function(host, url, callback) { var client = new Client(); client.connect(host, function() { client.launch(DefaultMediaReceiver, function(err, player) { var media = { contentId: url, contentType: 'audio/mp3', streamType: 'BUFFERED' // or LIVE }; player.load(media, { autoplay: true }, function(err, status) { client.close(); callback('Device notified'); }); }); }); client.on('error', function(err) { console.log('Error: %s', err.message); client.close(); callback('error'); }); }; exports.ip = ip; exports.device = device; exports.accent = accent; exports.notify = notify; exports.play = play;
「VoiceTextWriter.js」ファイルの新規作成
- 「@APIKEY@」を利用登録時に受信したAPIKEYに変更
- 「@WEBPAHT@」にWEBサーバの公開フォルダに格納する音声ファイルを指定
例:/var/www/html/voice-text.wav - 「@URL@」にWEBサーバの音声ファイルへアクセスする際のURLを指定
例:http://192.168.0.200/voice-text.wav
var fs = require('fs'); var VoiceText = require('voicetext'); var voice = new VoiceText('@APIKEY@'); var OUT_PATH = '@WEBPAHT@'; var OUTPUT_URL = '@URL@'; class VoiceTextWriter{ convertToText(text){ return new Promise(function(resolve,reject){ voice .speaker(voice.SPEAKER.HIKARI) .emotion(voice.EMOTION.HAPPINESS) // .emotion_level(voice.EMOTION_LEVEL.HIGH) .emotion_level(2) .speed(100) .volume(120) .speak(text, function(e, buf){ if(e){ console.error(e); reject(e); }else{ fs.writeFileSync(OUT_PATH, buf, 'binary'); resolve(OUTPUT_URL); } }); }); } } module.exports = VoiceTextWriter;
VoiceText Web APIマニュアルを参考に、speedやvolumeなどのオプション指定を変更して、好みの音声に変更して下さい。設定ファイル変更時には、Google Home Notifierの再起動が必要となります。