Programming > Java > am > ik > voicetext4j
Mar 1, 2020
Apr 3, 2020
N/A Views
MD
warning
この記事は2年以上前に更新されたものです。情報が古くなっている可能性があります。

CIの結果を音声合成で喋らせたいということがあったので実現方法を共有します。

音声合成ソフトはいろいろあるけど、今回はWeb APIで使えるVoiceTextを使いました。
そして、昔作ったVoiceText4Jを引っ張り出してきました。

まずはシンプルにこのVoiceText4JをSpring Boot経由で呼ぶだけのsyaberuというアプリを作りました。

image

ローカルでSyaberuを実行

こちらから最新のjarファイルをダウンロードしてください。

java -jar syaberu-0.0.1*.jar

API Keyをこちらから取得してください。

API_KEY=...
curl http://localhost:8080 -H "X-Api-Key: ${API_KEY}" -d text=こんにちは

speakerパラメータで話者を変えることもできます。

curl http://localhost:8080 -H "X-Api-Key: ${API_KEY}" -d text=こんにちは -d speaker=haruka
curl http://localhost:8080 -H "X-Api-Key: ${API_KEY}" -d text=こんにちは -d speaker=hikari

インターネット経由でローカルのSyaberuを実行

ローカルで音声合成を鳴らすのは簡単にできました。しかし、任意のCIサーバーからビルド結果を鳴らすにはインターネットを経由してSyaberuにリクエストを送る必要があります。
このSyaberuをクラウドにデプロイしても意味がありません。音声が鳴るのはスピーカーがついている端末上で、かつ聞こえないと意味がないです。
なので、ローカルで起動しているSyaberuにインターネット経由でFirewallを超えてアクセスしてもらう必要があります。

まず思いつくのはngrokを使う方法です。Syaberuの隣にngrokサーバーを立てて、ngrokが払い出すport/hostnameを経由してlocalhost:8080にアクセスさせることは可能です。
無料プランだとngrokのport/hostnameがrestartするたびに変わるのでCIに設定するには都合が悪いです。そこで、同じような仕組みを作りました。

ここで役に立つのが双方向プロトコルであるRSocketです。RSocketはSpring Boot 2.2から簡単に利用できるようになっています。興味のある人はこちらの資料を見てください。

RSocketを使って、SyaberuのProxy Serverを作成し、これをクラウド上におき、CIからはクラウド上のProxyサーバーにアクセスしてもらいます。Syaberuは起動時にProxyとRSocketでつなぎに行きます。ProxyはHTTPでリクエストをもらったらボディをそのままRSocketでつながっているSyaberuに送信し、このリクエストをSyaberuはVoiceTextに送ることで音声合成を鳴らすことができます。

図に示すと次のようになります。

image

ソースはこちら

Syaberu RSocket Proxyをローカルで実行

こちらから最新のjarファイルをダウンロードしてください。

java -jar syaberu-rsocket-proxy-0.0.1*.jar

Syaberuの起動時にsyaberu.proxy-uriにRSocket ProxyのURLを指定します。syaberu.proxy-subscription-idはチャネル名みたいなものです。

java -jar syaberu-0.0.1*.jar --syaberu.proxy-uri=http://localhost:8082/rsocket --syaberu.proxy-subscription-id=test 

これで次のようにProxy経由でSyaberuにリクエストを送れます。

curl http://localhost:8082/proxy/test -H "X-Api-Key: ${API_KEY}" -d text=こんにちは

Syaberu RSocket ProxyをCloud Foundryで実行

Syaberu RSocket ProxyをCloud Foundryにデプロイする場合はcf pushするだけです。

cf push syaberu-rsocket-proxy -p syaberu-rsocket-proxy-0.0.1*.jar

Syaberu RSocket ProxyはトランスポートレイヤにWebSocketを使っているため、Pivotal Web Servicesを使う場合は8443ポートを経由してアクセスする必要があります。

お試し用としてhttps://syaberu-rsocket-proxy.cfapps.io:8443にデプロイしてあるので、以下のように使えます。syaberu.proxy-subscription-idは被らないようにした方が良いです。

java -jar syaberu-0.0.1*.jar --syaberu.proxy-uri=https://syaberu-rsocket-proxy.cfapps.io:8443/rsocket --syaberu.proxy-subscription-id=test 

CIからは次のようにアクセスすれば良いです。

curl https://syaberu-rsocket-proxy.cfapps.io:8443/proxy/test -H "X-Api-Key: ${API_KEY}" -d text=こんにちは

Concourseからビルド結果を喋らせる

Concourseから鳴らしたい場合、はtaskcurlを叩けば十分なのですが、putで鳴らしたい場合は、以前Line Notifyに通知したのと同じような方法で実現できます。

サンプルパイプラインを貼っておきます。

resource_types:
- name: http-api
  type: docker-image
  source:
    repository: aequitas/http-api-resource
resources:
- name: syaberu
  type: http-api
  source:
    uri: https://syaberu-rsocket-proxy.cfapps.io:8443/proxy/((syaberu_subscription_id))
    method: POST
    headers:
      X-Api-Key: ((voicetext_api_token)) 
    form_data:
      text: "{text}"
      speaker: "{speaker}"
      emotion: "{emotion}"

jobs:
- name: hello
  plan:
  - task: say-hello
    config:
      platform: linux
      image_resource:
        type: docker-image
        source:
          repository: alpine
      run:
        path: sh
        args:
        - -c
        - |
          echo "Hello"
          # わざと失敗させたいとき
          # exit 1
    on_success:
      put: syaberu
      params:
        speaker: hikari
        text: タスクが成功しました
        emotion: happiness
    on_failure:
      put: syaberu
      params:
        speaker: hikari
        text: タスクが失敗しました
        emotion: sadness
Found a mistake? Update the entry.
Share this article: