1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Androidの通知をゆっくりに喋ってもらう

Last updated at Posted at 2020-03-08

MacrodroidというAndroidアプリとRaspberry piを使って、スマホの通知をゆっくりボイスが喋ってくれるシステムを作ってみました。

概要

MacrodroidはAndroidでタスク自動化ができるアプリです。
Androidでの何らかのイベントをトリガーに様々なアクションを自動で実行できます。

これとラズパイに立てた簡易webサーバーとを連携させ、通知が来たらその内容をwebサーバーに送りAquesTalkPiで音声を出力します。

環境

  • Android10
  • Raspberry pi 3b (Raspbian stretch)
    • dockerインストール済み
  • 3.5mmイヤホンジャックスピーカー

ラズパイ側の設定

ラズパイを使っていると、SDカードを交換して環境を作り直すことがあります。そんなときDockerfileがあると、いちいち環境構築の方法を思い出さずに済みます。

ということで簡易webサーバーをDockerで動かします。
(今回はコード量も殆ど無いのでDockerは大げさな気もしますが)

今回作成したDockerfileは次の通りです。

Dockerfile
FROM balenalib/rpi-raspbian:buster

RUN apt-get update && \
    apt-get -y install --no-install-recommends  alsa-utils python3 && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*

# https://www.a-quest.com/products/aquestalkpi.htmlのプログラム使用許諾を読んだ上で下記のダウンロードを行う
RUN mkdir /root/bin && \
    curl -kL "https://www.a-quest.com/cgi-bin/download.php?download=1&readed=yes" -o /tmp/aquestalk.tgz && \
    tar xzvf /tmp/aquestalk.tgz -C /tmp && \
    mv /tmp/aquestalkpi/AquesTalkPi /root/bin && \
    mv /tmp/aquestalkpi/aq_dic /root/bin && \
    rm /tmp/aquestalk.tgz && rm -r /tmp/aquestalkpi
ADD ./softalk_server.py /root/bin

EXPOSE 8000
CMD ["python3", "/root/bin/softalk_server.py"]

また簡易webサーバーはPythonで動かしました。

softalk_server.py
# -*- coding:utf-8 -*-
from http.server import HTTPServer, SimpleHTTPRequestHandler
from urllib import parse
import subprocess
KEYS = ["app", "title", "message"]


# textをゆっくりボイスにしゃべってもらう
def talk(text):
    p1 = subprocess.Popen(
        ["/root/bin/AquesTalkPi", text],
        stdout=subprocess.PIPE,
        stderr=subprocess.STDOUT,
    )
    p2 = subprocess.Popen(
        ["aplay"],
        stdin=p1.stdout, stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT
    )
    p1.stdout.close()  # SIGPIPE if p2 exits.
    p2.communicate()[0]


# [app, title, messa]のキーからなる辞書text_dicをもとに
# 発話メッセージを用意する
def format_message(text_dic):
    if text_dic['title'] is None:
        return None
    if text_dic['message'] is None:
        return None

    if len(text_dic['message']) < 40:
        formatted = '{app}から{title}というタイトルのメッセージです。{message}'.format(
            **text_dic
        )
    else:
        formatted = '{app}から{title}というタイトルのメッセージです。'.format(
            **text_dic
        )
    return formatted


# 簡易webサーバー
# GETリクエストを受け取ったら、そのパラメータをもとに
# スピーカーからゆっくりボイスを再生する
class RequestHandler(SimpleHTTPRequestHandler, object):
    def do_GET(self):
        query = parse.urlparse(self.path).query
        query_dic = parse.parse_qs(query)
        self.send_response(200)
        for key in KEYS:
            if key not in query_dic:
                query_dic[key] = None
            else:
                query_dic[key] = query_dic[key][0]
        print('query = {}'.format(query_dic))
        formatted = format_message(query_dic)
        # GETリクエストのパラメータが想定されているものと
        # 違う場合はformattedはNoneになり音声は再生されない
        if formatted is not None:
            talk(formatted)
        self.end_headers()


if __name__ == '__main__':
    text = '通知サーバを開始しました'
    talk(text)

    httpd = HTTPServer(("", 8000), RequestHandler)
    httpd.serve_forever()

そしてDockerfilesoftalk_server.pyがあるディレクトリで以下のコマンドを実行します。

$ docker build -t softalk_notification .
$ docker run -d --name notification_server --device /dev/snd -p 8000:8000 --restart=always softalk_notification

--restart=alwaysのオプションをつけることで、再起動したときにも(dockerデーモンが停止したときにも)自動でコンテナを立て直すようになり便利です。

また、ALSAを使ってスピーカーの音を再生するためにdev/snd--deviceに渡しています。

加えてwebサーバーのポートはコンテナもホストも8000に設定しています。

うまくいっていたら次のGETリクエストでゆっくりが喋ってくれるはずです。

$ curl localhost:8000 --get --data-urlencode 'app=ゆっくり' --data-urlencode 'title=テスト' --data-urlencode 'message=ゆっくりしていってね'

Android側の設定

続いてAndroidに通知が来たときにwebサーバにGETリクエストを出しましょう。これはMacrodroidで実現できます。

Google PlayからMacrodroidをインストールしたら、以下のマクロを作成します。

  • トリガー

    • 「機器のイベント」 > 「通知」 をタップ
    • 「通知が表示された時」 > 「どれかのアプリ」 > OK をタップ (場合によっては通知領域に関する権限設定が必要)
  • アクション

    • 「アプリケーション」 > 「Webサイトを開く / HTTP GET」をタップ
    • 「エンコード・パラメータURL」にチェック
    • URLを入力の部分に以下を入力(ラズパイのIPアドレスが192.168.0.2の場合)して右下のOKをタップ
    URL

192.168.0.2:8000?app=[not_app_name]&title=[not_title]&message=[notification]


トリガーとアクションの設定が終わったら画面右下のチェックマークをタップ。カテゴリーやマクロ名は適当に入力してください。

以上で設定は終了です。

# おわりに
今回は最低限の設定ですので実用的には細かな微調整が必要かなと思います。以下は現状で思い浮かぶ設定項目です。

- 全てのアプリの通知を読み上げるのか : Macrodroid側である程度指定可能
- 常に読み上げを行うのか: Macrodroidの時刻のトリガー(Nature remoと組み合わせて明るさで判定するのも面白そう)

興味を持たれた方は試してみてはいかがでしょうか。
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?