音声合成サービスは、Java用SDKを提供しています。このトピックでは、SDKのダウンロードとインストール方法について説明します。また、SDKを使用するためのサンプルコードも提供します。
前提条件
SDKの仕組みを理解していること。詳細については、「概要」をご参照ください。
ダウンロードとインストール
Mavenリポジトリから最新バージョンのSDKをダウンロードします。nls-sdk-java-demoパッケージをダウンロードするには。
<dependency>
<groupId>com.alibaba.nls</groupId>
<artifactId>nls-sdk-tts</artifactId>
<version>2.1.6</version>
</dependency>.zipデモパッケージを解凍します。 pomディレクトリから mvn package コマンドを実行します。実行可能なJARパッケージnls-example-tts-2.0.0-jar-with-dependencies.jarがtargetディレクトリに生成されます。 JARパッケージをデスティネーションサーバーにコピーします。 JARパッケージを使用して、サービスのクイック検証とストレステストを実行できます。
サービス検証:
次のコマンドを実行し、プロンプトに従ってパラメータを設定します。
その後、コマンドを実行したディレクトリにlogs/nls.logファイルが生成されます。
java -cp nls-example-tts-2.0.0-jar-with-dependencies.jar com.alibaba.nls.client.SpeechSynthesizerDemoストレステスト:
次のコマンドを実行し、プロンプトに従ってパラメータを設定します。
サービスURLを wss://nls-gateway.cn-shanghai.aliyuncs.com/ws/v1 に設定します。購入したリソースに基づいて、最大同時呼び出し数を設定します。
java -jar nls-example-tts-2.0.0-jar-with-dependencies.jarストレステストを実行するために3回以上同時に呼び出した場合、課金されます。
主要オブジェクト
NlsClient: 音声処理クライアント。クライアントを使用して、短文認識、リアルタイム音声認識、音声合成タスクを処理できます。このオブジェクトはスレッドセーフです。グローバルに1つのNlsClientオブジェクトを作成できます。
SpeechSynthesizer: 音声合成プロセッサ。このオブジェクトを使用して、リクエストパラメータを設定し、リクエストを送信できます。このオブジェクトはスレッドセーフではありません。
SpeechSynthesizerListener: 音声合成結果リスナー。合成結果をリッスンします。このオブジェクトはスレッドセーフではありません。次の2つの抽象メソッドを実装します。
/** * 合成された音声データをバイナリ形式で受信します。 */ abstract public void onMessage(ByteBuffer message); /** * 合成タスクが完了したことをクライアントに通知します。 * * @param response */ abstract public void onComplete(SpeechSynthesizerResponse response);詳細については、「Java API概要」をご参照ください。
SDK呼び出しに関する注意事項:
グローバルに1つのNlsClientオブジェクトを作成し、必要に応じて再利用できます。 Nettyに基づいて、NlsClientオブジェクトの作成には時間とリソースが消費されますが、作成されたNlsClientオブジェクトは再利用できます。プロジェクトのライフサイクルに基づいて、NlsClientオブジェクトを作成および無効にすることをお勧めします。
SpeechSynthesizerオブジェクトは再利用できません。認識タスクごとにSpeechSynthesizerオブジェクトを作成する必要があります。たとえば、 N個のテキストファイルから音声を合成するには、 N個のSpeechSynthesizerオブジェクトを作成して、 N個の合成タスクを完了する必要があります。
1つのSpeechSynthesizerListenerオブジェクトは、1つのSpeechSynthesizerオブジェクトに対応します。複数のSpeechSynthesizerオブジェクトに1つのSpeechSynthesizerListenerオブジェクトを使用することはできません。そうしないと、合成タスクを区別できない場合があります。
Java用SDKはNettyに依存しています。アプリケーションがNettyに依存している場合は、Nettyのバージョンが 4.1.17.Final以降であることを確認してください。
サンプルコード
デモでは、合成された音声はファイルに保存されます。合成された音声をリアルタイムで再生する必要がある場合は、ストリーム再生を使用することをお勧めします。ストリーム再生モードでは、音声データを受信しながら合成された音声を再生できます。合成タスクが完了するまで待つ必要はありません。これにより、レイテンシが短縮されます。
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import com.alibaba.nls.client.protocol.NlsClient;
import com.alibaba.nls.client.protocol.OutputFormatEnum;
import com.alibaba.nls.client.protocol.SampleRateEnum;
import com.alibaba.nls.client.protocol.tts.SpeechSynthesizer;
import com.alibaba.nls.client.protocol.tts.SpeechSynthesizerListener;
import com.alibaba.nls.client.protocol.tts.SpeechSynthesizerResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* このサンプルコードは、次の操作を実行する方法を示しています。
* 音声合成サービスのAPIを呼び出します。
* 動的にトークンを取得します。
* ストリームモードでテキストから音声を合成します。
* 最初のパケットレイテンシを計算します。
*/
public class SpeechSynthesizerDemo {
private static final Logger logger = LoggerFactory.getLogger(SpeechSynthesizerDemo.class);
private static long startTime;
private String appKey;
NlsClient client;
public SpeechSynthesizerDemo(String appKey, String accessKeyId, String accessKeySecret) {
this.appKey = appKey;
// グローバルに NlsClient オブジェクトを作成します。デフォルトのエンドポイントは、音声合成サービスのインターネットアクセスURLです。
// トークンを取得します。現在のトークンの有効期限が切れる前に、別のトークンを取得する必要があります。 accessToken.getExpireTime() メソッドを呼び出して、トークンの有効期限を照会できます。
AccessToken accessToken = new AccessToken(accessKeyId, accessKeySecret);
try {
accessToken.apply();
System.out.println("get token: " + accessToken.getToken() + ", expire time: " + accessToken.getExpireTime());
client = new NlsClient(accessToken.getToken());
} catch (IOException e) {
e.printStackTrace();
}
}
public SpeechSynthesizerDemo(String appKey, String accessKeyId, String accessKeySecret, String url) {
this.appKey = appKey;
AccessToken accessToken = new AccessToken(accessKeyId, accessKeySecret);
try {
accessToken.apply();
System.out.println("get token: " + accessToken.getToken() + ", expire time: " + accessToken.getExpireTime());
if(url.isEmpty()) {
client = new NlsClient(accessToken.getToken());
}else {
client = new NlsClient(url, accessToken.getToken());
}
} catch (IOException e) {
e.printStackTrace();
}
}
private static SpeechSynthesizerListener getSynthesizerListener() {
SpeechSynthesizerListener listener = null;
try {
listener = new SpeechSynthesizerListener() {
File f=new File("tts_test.wav");
FileOutputStream fout = new FileOutputStream(f);
private boolean firstRecvBinary = true;
// 合成タスクを完了します。
@Override
public void onComplete(SpeechSynthesizerResponse response) {
// onComplete イベントは、音声合成のすべてのテキストデータが受信されたことを示します。レイテンシは合成タスク全体で計算されます。レイテンシが大きいため、リアルタイム再生は実装されない場合があります。
System.out.println("name: " + response.getName() +
", status: " + response.getStatus()+
", output file :"+f.getAbsolutePath()
);
}
// 合成されたバイナリ音声データを受信します。
@Override
public void onMessage(ByteBuffer message) {
try {
if(firstRecvBinary) {
// クライアントが初めて音声データを受信したときに、最初のパケットレイテンシを計算します。クライアントは、最初のオーディオストリームを受信すると再生を開始します。これにより、特にリアルタイムの音声対話中に、応答速度が向上します。
firstRecvBinary = false;
long now = System.currentTimeMillis();
logger.info("tts first latency : " + (now - SpeechSynthesizerDemo.startTime) + " ms");
}
byte[] bytesArray = new byte[message.remaining()];
message.get(bytesArray, 0, bytesArray.length);
fout.write(bytesArray);
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onFail(SpeechSynthesizerResponse response){
// タスクIDは、呼び出し元とサーバー間のインタラクションを示す一意の識別子です。タスクIDを記録する必要があります。エラーが発生した場合は、チケットを送信し、トラブルシューティングを容易にするためにタスクIDをAlibaba Cloudに提供できます。
System.out.println(
"task_id: " + response.getTaskId() +
// ステータスコード。コード 20000000 は、認識が成功したことを示します。
", status: " + response.getStatus() +
// エラーメッセージ。
", status_text: " + response.getStatusText());
}
};
} catch (Exception e) {
e.printStackTrace();
}
return listener;
}
public void process() {
SpeechSynthesizer synthesizer = null;
try {
// オブジェクトを作成し、接続を確立します。
synthesizer = new SpeechSynthesizer(client, getSynthesizerListener());
synthesizer.setAppKey(appKey);
// 返される音声ファイルの音声符号化形式を設定します。
synthesizer.setFormat(OutputFormatEnum.WAV);
// 返される音声ファイルの音声サンプリングレートを設定します。
synthesizer.setSampleRate(SampleRateEnum.SAMPLE_RATE_16K);
// スピーカーの種類。
synthesizer.setVoice("siyue");
// オプション。スピーカーのイントネーション。有効な値: -500~500。デフォルト値: 0。
synthesizer.setPitchRate(100);
// スピーカーの速度。有効な値: -500~500。デフォルト値: 0。
synthesizer.setSpeechRate(100);
// 音声合成に使用するテキストを設定します。
synthesizer.setText("Alibaba Cloudの音声合成サービスへようこそ。明日の北京の天気はどうですか、と言うことができます。");
// 生成された音声の字幕を有効にするかどうかを指定します。デフォルトでは、この機能は無効になっています。すべてのスピーカータイプが字幕に対応しているわけではないことに注意してください。
synthesizer.addCustomedParam("enable_subtitle", false);
// 前のパラメータ設定をJSON形式にシリアル化します。次に、JSONファイルをサーバーに送信して確認します。
long start = System.currentTimeMillis();
synthesizer.start();
logger.info("tts start latency " + (System.currentTimeMillis() - start) + " ms");
SpeechSynthesizerDemo.startTime = System.currentTimeMillis();
// 合成タスクが完了するまで待ちます。
synthesizer.waitForComplete();
logger.info("tts stop latency " + (System.currentTimeMillis() - start) + " ms");
} catch (Exception e) {
e.printStackTrace();
} finally {
// サーバーからクライアントを切断します。
if (null != synthesizer) {
synthesizer.close();
}
}
}
public void shutdown() {
client.shutdown();
}
public static void main(String[] args) throws Exception {
String appKey = "Your appkey";
String id = "Your AccessKey ID";
String secret = "Your AccessKey secret";
String url = ""; // デフォルト値: wss://nls-gateway.cn-shanghai.aliyuncs.com/ws/v1。
if (args.length == 3) {
appKey = args[0];
id = args[1];
secret = args[2];
} else if (args.length == 4) {
appKey = args[0];
id = args[1];
secret = args[2];
url = args[3];
} else {
System.err.println("run error, need params(url is optional): " + "<app-key> <AccessKeyId> <AccessKeySecret> [url]");
System.exit(-1);
}
SpeechSynthesizerDemo demo = new SpeechSynthesizerDemo(appKey, id, secret, url);
demo.process();
demo.shutdown();
}
}