ユーザーが音声で質問したことに回答してくれる、夢のデバイス、スマートスピーカー。
スマートスピーカー向けのアプリケーションをつくるのも比較的簡単で、これまで僕も何本かリリースしてきました。
https://amzn.to/2Z7Koiyamzn.to
しかし、スマートスピーカーというのは基本的にユーザーの問いに答えるマシーンなので、スマートスピーカーが急に喋り出すことはありません。
Siriもそうですよね。こちらが話しかけるまでは一切喋りません。
勝手に話し始める機能を開放してしまうと、スマートスピーカーが広告をずーっと喋っていることになりそうですからね。賢明な判断です。
ただ、勝手に喋ってくれると便利なシーンというのもあるはずで、
ミーティングの10分前に「10分後にミーティングが始まりそうですよ」とか、
急な夕立が降ってきそうな時に「そろそろ雨が降ってきそうですよ」とか、
家に泥棒が入った時に「こら!泥棒!」とか、喋ってくれるアプリがあると非常に便利な気がしております。
で、調べてみるとGoogleHomeに音楽ファイルを配信できるnpmを見つけたので、試してみることにしました。
当初は、こちらのパッケージを使おうと思ったのですが、どうやらGoogleのAPIの変更の煽りを受けて、そのままでは動かず、その対策のプルリクエストもあるのですが、1年半ぐらいマージされず、という状況なので、ソースを参考にさせてもらうに止まりました。
ソースを見るに内部で使っているのは、castv2-clientだったので、直接こっちを使ってしまおうという判断です。
JavaScript
const { Client, DefaultMediaReceiver } = require('castv2-client'); const ip = require('ip'); const express = require('express'); const app = express(); const http = require('http').Server(app); const client = new Client(); const mdns = require('mdns'); const browser = mdns.createBrowser(mdns.tcp('googlecast')); const port = 3000; let host = ''; browser.on('serviceUp', function(service) { if (host || !service.addresses[0]) { return; } host = service.addresses[0]; app.use('/', express.static(__dirname + '/public')); http.listen(port, '0.0.0.0'); const media = { contentId: `http://${ip.address()}:${port}/audio.mp3`, contentType: 'audio/mp3', streamType: 'BUFFERED', }; client.connect(host, () => { client.launch(DefaultMediaReceiver, (err, player) => { player.load(media, { autoplay: true }, (err, status) => { if (err) { console.error(err); } }); }); }); browser.stop(); }); browser.start();
こちらのコードを実行すると、同一WiFi内にあるGoogleHomeを探し、最初に見つけたpublic直下のaudio.mp3を再生します。
ドキュメントを読んでもよくわからない箇所が多かったので、ソースを読んだり、node-castv2のソースを読んだり、console.dirでログを出しまくりながら頑張って動かしました。GoogleHome Mini(第一世代)とNest WiFiの拡張ポイントで動作確認済みです。
あとは、
- audio.mp3に「10分後にミーティングが始まりそうですよ」とか「こら!泥棒!」とかいう音声を録音しておく
- 再生のきっかけをサーバー起動時ではなく任意のタイミングにする
の2点を施せば、勝手に喋り始める便利なアプリケーションができあがりそうです。
また、事前に録音されたmp3を流すのではなく、テキストを渡した際にそれを読み上げるバージョンもつくれそうなので、そちらは引き続き制作します。