Raspberry PiとBluetoothスピーカーとRuby + Sinatraで天の声APIを作ってみる
最近,研究室でRaspberry Piを借りてきたのでせっかくだから喋らせてみることにしました
なんかもうあった
カレーメシ先輩( id:nwpct1 )がラズパイ内で音声合成して喋らせていたのでコレを参考にしてみようと思ったのですが,docomo developer supportにはいっているHOYAサービスの音声合成APIを使ってRESTで殴って生成済み音声データを持って来て再生する仕組みにしておうちの中でPOSTすると喋らせてみることにします.
用意するもの
- Raspberry Pi(今回は2Bを利用)
- LANケーブルか無線LANドングル
- Bluetoothドングル
- Bluetoothスピーカー
docomo developer supportに登録
にアクセスしてアカウントを取得します.取得したら,マイページからAPI利用申請・管理にアクセスしてアプリケーションを登録します.基本情報を入力し,『音声合成 【Powerd by HOYAサービス】』を選択してAPIキーを取得しましょう.
APIエンドポイントを作る
まずはGemfileの定義から.
source "https://rubygems.org" gem 'sinatra' gem 'sinatra-contrib'
ただ喋らせるだけなのでこれで十分です.DB用意したりして工夫する際は適宜追加しましょう.完了したら bundle install --path /vender/bundle
でインストールします.
app.rb
にエンドポイントを定義します.今回は適当に /api/v1/speech
とします.ついでに /api/v1/speech/test
にテスト用のエンドポイントも用意します.
#!/usr/bin/env ruby # coding:utf-8 require 'sinatra' require 'sinatra/json' require 'json' require './speech.rb' # API get '/api/v1/speech/test' do speech = Speech.new data = {result: speech.do_speech("これはテストです.音量などを確認してください.")} if data[:result] == 'success' then status 200 else status 400 end json data end post '/api/v1/speech', provides: :json do params = JSON.parse(request.body.read, {:symbolize_names => true}) text = params[:text] speech = Speech.new data = {result: speech.do_speech(text)} if data[:result] == 'success' then status 200 else status 400 end json data end
実際に喋らせるSpeechクラスを実装します.do_speech
メソッドだけですが.
require 'net/http' require 'uri' API_KEY = '(docomo developer supportで取得したAPIキー)' class Speech def do_speech(text) endpoint = URI.parse('https://api.apigw.smt.docomo.ne.jp/voiceText/v1/textToSpeech') endpoint.query = 'APIKEY=' + API_KEY request_body = { 'text'=>text, 'speaker'=>'hikari' } res = Net::HTTP.post_form(endpoint, request_body) case res when Net::HTTPSuccess file_name = "voice.wav" File.binwrite(file_name, res.body) `aplay voice.wav` #Macに喋らせたいときはafplayにしましょう File.delete(file_name) return "success" else return res.body end end end
ちなみに上のコメントにあるようにaplayをafplayにするとmacで喋れるようになります.この時点で,とりあえず bundle exec ruby app.rb -o 0.0.0.0
で起動して localhost:4567/api/v1/speech
に
{ "text": "ほげほげ" }
みたいなJSONをPOSTするとPCが喋ると思います.
Raspberry Pi側の環境構築
とりあえず頑張ってRaspberry Piにrubyをインストールします.
Raspberry Piなのでインストールには凄い時間がかかりますが気長に待ちましょう.
完了したら
gem install bundler
でbundlerをインストールします.完了したらさっきのsinatraアプリケーションをgitなりでRaspberry Pi上に移動して bundle install --path /vender/bundle
して, bundle exec ruby app.rb -o 0.0.0.0
で起動します.この時点で,Raspberry Piのイヤホンジャックにイヤホン等を繋いで '(Raspberry PiのIP):4567/api/v1/speech' に先程のJSONをPOSTすると喋るのですが,今回はBluetoothスピーカーに喋らせるので
apt-get install bluetooth bluez bluez-tools pulseaudio pulseaudio-module-bluetooth
でbluezとpulseaudioをインストールします.インストールしたら pulseaudio --start
でpulseaudioを起動します.終了は pulseaudio -k
です.
続いて,Bluetoothスピーカーの電源を入れ,bluetoothctlでペアリングを行います.
$ bluetoothctl -a [bluetooth]# power on //パワーオン [bluetooth]# scan on //スキャン開始 [NEW] Device A0:E9:xx:xx:xx:xx BT Speaker name // Bluetoothスピーカーを見つける [bluetooth]# connect A0:E9:xx:xx:xx:xx [bluetooth]# trust A0:E9:xx:xx:xx:xx [bluetooth]# exit
ペアリングが完了したらデフォルトをそのスピーカーに設定して
$ pacmd set-default-sink bluez_sink.A0_E9_xx_xx_xx_xx
音量を設定します,
$ pactl set-sink-volume bluez_sink.A0_E9_xx_xx_xx_xx 60% または $ alsamixer
これで,Raspberry PiのAPIを叩くとBluetoothスピーカーからおもむろに声が鳴り響くと思います.天井付近に設置すれば天の声っぽくなる…か?