【Google Home mini】音量を調整できないか調べていたら音声を変えることができたという話

以前、Google Home mini で音楽を流すことに成功しました。

しかし、メッセージをしゃべる時と、音楽が流れる時では、音量に違いがあり、使いにくい部分がありました。

なので、Google Home mini の音量をプログラムで変えることはできないかと、いろいろ探していましたが、まだ見つかっていません。

そんな中、Google Notifer を使って出す声が変更できることがわかりました。

簡単にいうと、Googleのテキスト音声変換APIを使っていたのを、他の音声変換サービスを利用するといったところです。

そのサービスとは、以前にも試したことのある「HOYAのVoiceText Web API」です。

これによって、今までは、ロボットのようなAIっぽい声でしたが、かなり人の自然な喋り方に近づきました。

手順

google-tts-api 」の代わりに「voice text api」を使用するように設定します。

音楽ファイルを呼ぶローカルパソコンの中に、node.js を入れた後に、「voicetext」モジュールをインストールします。

npm install voicetext

後は、↓以下のサイトの通りに、「google-home-notifier.js」を変更したり、「VoiceTextWriter.js」を作ればできあがりです。

VoiceTextWriter.js を追加

var os = require('os');
var ips = os.networkInterfaces();
var ip = ips['en1'][1].address;

var fs = require('fs');
var VoiceText = require('voicetext');
var voice = new VoiceText('APIキー');
var OUT_PATH = '/Library/WebServer/Documents/voice/test.wav'
var OUTPUT_URL = 'http://' + ip + '/voice/test.wav';

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)
    .volume(150)
    .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;

google-home-notifier.js を変更

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;
//↓この2行を追加
var VoiceTextWriter = require('./VoiceTextWriter');
var voiceTextWriter = new VoiceTextWriter();

var device = function(name, lang = 'ja') {
  device = name;
  //deviceAddress = address;
  language = lang;
  return this;
};

var ip = function(ip) {
  deviceAddress = ip;
  return this;
}
//↓多分いらない
var googletts = require('google-tts-api');
var googlettsaccent = 'ja';
var accent = function(accent) {
  googlettsaccent = accent;
  return this;
}

var notify = function(message, callback = function() {}) {
  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 = function() {}) {
  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) {
//  googletts(text, language, 1).then(function (url) {
//    onDeviceUp(host, url, function(res){
//      callback(res)
//    });
//  }).catch(function (err) {
//    console.error(err.stack);
//  });

     voiceTextWriter.convertToText(text).then(function(result, reject){
       onDeviceUp(host, result, function(res){
        callback(res)
        });
    }).catch(function onRejected(error){
        console.error(error);
    });

};

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) {

     // console.log(url);
      var media = {
        contentId: url,
        contentType: 'audio/mp3',
        streamType: 'BUFFERED' // or LIVE
      };
      //wavとoggも一応入れといてみるか
      if(url.endsWith('wav')){
        media.contentType = 'audio/wav';
      }else if(url.endsWith('ogg')){
        media.contentType = 'audio/ogg';
      }
      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;

テスト用 js

const googlehome = require('./google-home-notifier')

var msg = 'このメッセージを喋ります';

googlehome.device('Google-Home-Mini');  //←Google Home mini のデバイス名
googlehome.notify(msg, function(res) {
  console.log(res);
});

結局、Google Home の 音量変更はプログラムではできていませんが、今回の voice text で作る音声ファイルの音量は調整できるので、とりあえず、そちらで対応しました。