この記事はKIT Developer Advent Calendar 2016 22日目の記事です。
みなさんはじめまして。久しぶりの方はお久しぶりです。
@306_sanです。
普段はWebアプリエンジニアごっこやってますが、授業等でたまにはAndroidアプリを書きます。
しかしAndroidに関してはド素人なので間違っていたらどしどし編集リクエスト送ってください。
さて、Androidで音声合成をやりたいとき皆さんはどうしてますか?
OS標準のやつを使っていますか?
でも、アレ、日本語だと少し幼稚な感じがして聞き取りづらくないですか?
そんなわけで、探してみたところ、HOYA社提供のVoiceText Web APIが聞こえやすそうでした。(最近だとamazonもAmazon Pollyという音声合成サービスを出したようですが実装した時はリリース前でした)
APIをたたけば、バイナリでWave形式の音声データが降ってきます。エラーの場合はJsonで返ってきます。
音声合成のデモはこちらから→http://voicetext.jp/voicetextlab/#anchor01
APIのサイトはこちらから→https://cloud.voicetext.jp/webapi
今回の環境
- IDE: IntelliJ IDEA 2016.2.5 Build #IU-162.2228.15, built on October 14, 2016
- Ultimate版です。学生はただで使えるのでおすすめです。
- Androidプラグインを適用してAndroid開発をしています。
- Android Studioはこれをベースに作られています。
- OS: Windows10 Pro 64bit
- API Level: 23(Android6.0)
- ライブラリー: OkHttp 3.4.2
- AndroidでHTTP通信を書きやすくしてくれるライブラリーです。
- 標準でもかけますがこっちを使ったほうが短くかけるのでおすすめです
- 公式サイト: http://square.github.io/okhttp/
- 似たようなライブラリーでRetrofitがありますがこっちは受け取ったものをデフォルトではJsonで勝手にパースしちゃうので正常にやりとりできた場合はバイナリーをパースしようとしてエラーが出てしまい、使えません。
下準備
https://cloud.voicetext.jp/webapi/api_keys/newにアクセスして、利用登録を行いAPIキーを取得してください。
メールにAPIキーが送られてきます。
そして、APIキーをBASE64形式でエンコードしてください(やり方は省略します)
プロジェクトのbulid.gradleファイルに
dependencies {
compile 'com.squareup.okhttp3:okhttp:3.4.2'
}
を追記してライブラリーをDLしてください。
使い方
今回の場合は非同期処理というものをしないといけません。非同期処理とは画面の遷移と連動していなくても処理することです。(多分)
非同期処理をするには予め決められている関数を使って書く必要があります。(多分)
よくわかっていないのでサンプルコードを載せておきます。
package com.example.hoge.foo;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.os.AsyncTask;
import okhttp3.*;
import java.io.IOException;
public class Hoge extends AsyncTask<String,Void,Void> {
OkHttpClient client = new OkHttpClient();
@Override
protected Void doInBackground(String... params) {
RequestBody requestBody = new FormBody.Builder()
.add("text", String.valueOf(params[0]))
.add("speaker","hikari") //パラメーターはここでいじる
.build();
Request request = new Request.Builder()
.addHeader("Authorization", "Basic hogehoge=") //ここにBASE64にエンコードしたAPIキーを書く
.url("https://api.voicetext.jp/v1/tts")
.post(requestBody)
.build();
try
{
Response response = client.newCall(request).execute();
byte[] hoge = response.body().bytes();
// バッファサイズを取得
int bufSize = AudioTrack.getMinBufferSize(44100, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT);
// AudioTrackインスタンスを生成
AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_OUT_MONO,
AudioFormat.ENCODING_PCM_16BIT, bufSize, AudioTrack.MODE_STREAM);
// 再生
audioTrack.play();
audioTrack.write(hoge,0, hoge.length);
}
catch (IOException e)
{
e.printStackTrace();
}
return null;
}
}
あとは、呼び出したいところで
new Hoge().execute("なんらかの文字列");
と書けば終わりです。
あといい感じに権限を設定(ネットワーク周りと音声周りかな)して実行すれば動くはずです。
まとめ
2年ぐらいぶりにAndorid触りましたが、いろいろ仕様が変わっていて浦島太郎状態でつらかったです。
やっぱWebのほうが開発ししててタノシイ
明日の記事は@Hassanさんです。よろしくお願いします。