はじめに
緊急地震速報をGoogle Homeでアナウンスしてみよう と、Ubuntu14.04でgoogle-home-notifierを実行したところ、
Error: getaddrinfo -3008
が発生しました。以下、その時に行った内容のメモ書きになります。
browser.js の修正
いつものアレだ と、google-home-notifier の After "npm install" に従い、node_modules/mdns/lib/browser.js へ {families:[4]}
を追加しました。
--- browser.js (revision x)
+++ browser.js (working copy)
@@ -116,7 +116,7 @@
Browser.defaultResolverSequence = [
rst.DNSServiceResolve()
-, 'DNSServiceGetAddrInfo' in dns_sd ? rst.DNSServiceGetAddrInfo() : rst.getaddrinfo()
+, 'DNSServiceGetAddrInfo' in dns_sd ? rst.DNSServiceGetAddrInfo() : rst.getaddrinfo({families:[4]})
, rst.makeAddressesUnique()
];
ところが、結果は変わらず、エラー発生。Raspberry Piなどでは改善したのだけど...、違うのか。
Raspberry PI 2 getaddrinfo 3008 error #130 内のコメントにあった {families:[0]}
なども試してみましたが、これもダメ...。
IPアドレスを指定
node_modules/google-home-notifier/google-home-notifier.js を確認してみると、Google HomeのIPアドレスを指定すれば、mdnsを使わないことが分かりました。実際、
const googlehome = require('google-home-notifier')
googlehome.device('Google-Home', 'ja');
googlehome.ip('192.168.xxx.xxx'); //Google HomeのIPアドレスを指定
googlehome.notify('こんにちは。私はグーグルホームです。', function(res) {
console.log(res);
});
といった感じにすれば、エラーは回避できました。でも、できればIPアドレスは指定したくない...。
google-home-notifier.js の修正
結局のところ、Google HomeのIPアドレスを別の方法で取得すればよいのか、ということで、Google Homeの名前とIPアドレスを検出する方法 を参考にしました(ありがとうございます)。そちらでは multicast-dns を利用していたので、node_modules/google-home-notifier/google-home-notifier.js を以下のように修正しました。
--- google-home-notifier.js (revision x)
+++ google-home-notifier.js (working copy)
@@ -1,7 +1,6 @@
var Client = require('castv2-client').Client;
var DefaultMediaReceiver = require('castv2-client').DefaultMediaReceiver;
-var mdns = require('mdns');
-var browser = mdns.createBrowser(mdns.tcp('googlecast'));
+var mdns = require('multicast-dns')()
var deviceAddress;
var language;
@@ -25,17 +24,28 @@
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];
+ mdns.on('response', function (response) {
+ var name = '';
+ var ip = '';
+ for (const additional of response.additionals) {
+ if (additional.type == 'TXT') name = additional.name;
+ if (additional.type == 'A') ip = additional.data;
+ }
+ console.log('Device "%s" at %s', name, ip);
+ if (name.includes(device.replace(' ', '-'))){
+ deviceAddress = ip;
getSpeechUrl(message, deviceAddress, function(res) {
callback(res);
});
+ mdns.destroy();
}
- browser.stop();
});
+
+ mdns.query('_googlecast._tcp.local', 'PTR');
+
+ setTimeout(function () {
+ mdns.destroy();
+ }, 2500);
}else {
getSpeechUrl(message, deviceAddress, function(res) {
callback(res);
とりあえずはこの修正で動いているようです(IPアドレスを指定することなく)。最初に応答のあったGoogle Homeのみに通知しているので、オリジナルとは動作が異なる気がしますが...。
おわりに
今回は場当たり的な対処しか行わなかったので、時間が出来たら根本の原因を調査してみようと思います(調査ってどうやるのだろう...)。