package cn.hieap.tts;
import static com.baidu.tts.sample.MainHandlerConstant.PRINT;
import static com.baidu.tts.sample.MainHandlerConstant.UI_CHANGE_INPUT_TEXT_SELECTION;
import static com.baidu.tts.sample.MainHandlerConstant.UI_CHANGE_SYNTHES_TEXT_SELECTION;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import androidx.annotation.NonNull;
import com.baidu.tts.chainofresponsibility.logger.LoggerProxy;
import com.baidu.tts.client.SpeechError;
import com.baidu.tts.client.SpeechSynthesizer;
import com.baidu.tts.client.SpeechSynthesizerListener;
import com.baidu.tts.client.TtsMode;
import com.baidu.tts.sample.control.InitConfig;
import com.baidu.tts.sample.control.MySyntherizer;
import com.baidu.tts.sample.control.NonBlockSyntherizer;
import com.baidu.tts.sample.listener.UiMessageListener;
import com.baidu.tts.sample.util.AutoCheck;
import com.baidu.tts.sample.util.IOfflineResourceConst;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.module.annotations.ReactModule;
import java.util.HashMap;
import java.util.Map;
@ReactModule(name = HiBaiduTtsModule.NAME)
public class HiBaiduTtsModule extends ReactContextBaseJavaModule implements SpeechSynthesizerListener {
public static final String NAME = "HiBaiduTts";
private String APP_ID;
private String API_KEY;
private String SECRET_KEY;
private MySyntherizer mySyntherizer;
private ReactApplicationContext myReactContext;
protected TtsMode ttsMode = IOfflineResourceConst.DEFAULT_SDK_TTS_MODE;
private Handler mainHandler;
private Promise promise;
public HiBaiduTtsModule(ReactApplicationContext reactContext) {
super(reactContext);
myReactContext = reactContext;
}
@Override
@NonNull
public String getName() {
return NAME;
}
// Example method
// See https://reactnative.dev/docs/native-modules-android
@ReactMethod
public void multiply(int a, int b, Promise promise) {
promise.resolve(a * b);
}
public static native int nativeMultiply(int a, int b);
@ReactMethod
public void initSDK(String apiKey, String secretKey, String appId) {
APP_ID = appId;
API_KEY = apiKey;
SECRET_KEY = secretKey;
if (mySyntherizer == null)
initialTts();
}
@ReactMethod
public void speak(String text, Promise promise) {
if (mySyntherizer != null) {
int result = mySyntherizer.speak(text);
if (result != 0) {
Log.e(NAME, "error code :" + result);
}
this.promise = promise;
}
}
@ReactMethod
public void setSpeaker(String speaker) {
if (mySyntherizer != null) {
Map<String, String> params = new HashMap<>();
params.put(SpeechSynthesizer.PARAM_SPEAKER, speaker);
mySyntherizer.setParams(params);
}
}
@ReactMethod
public void setVolume(int volume) {
if (mySyntherizer != null) {
Map<String, String> params = new HashMap<>();
params.put(SpeechSynthesizer.PARAM_VOLUME, String.valueOf(volume));
mySyntherizer.setParams(params);
}
}
@ReactMethod
public void setSpeed(int speed) {
if (mySyntherizer != null) {
Map<String, String> params = new HashMap<>();
params.put(SpeechSynthesizer.PARAM_SPEED, String.valueOf(speed));
mySyntherizer.setParams(params);
}
}
@ReactMethod
public void setPitch(int pitch) {
if (mySyntherizer != null) {
Map<String, String> params = new HashMap<>();
params.put(SpeechSynthesizer.PARAM_PITCH, String.valueOf(pitch));
mySyntherizer.setParams(params);
}
}
@ReactMethod
public void stop() {
if (mySyntherizer != null) {
mySyntherizer.stop();
}
}
@Override
public void onCatalystInstanceDestroy() {
if (mySyntherizer != null) {
mySyntherizer.release();
mySyntherizer = null;
}
super.onCatalystInstanceDestroy();
}
/**
* 初始化引擎,需要的参数均在InitConfig类里
* <p>
* DEMO中提供了3个SpeechSynthesizerListener的实现
* MessageListener 仅仅用log.i记录日志,在logcat中可以看见
* UiMessageListener 在MessageListener的基础上,对handler发送消息,实现UI的文字更新
* FileSaveListener 在UiMessageListener的基础上,使用 onSynthesizeDataArrived回调,获取音频流
*/
protected void initialTts() {
LoggerProxy.printable(true); // 日志打印在logcat中
// 设置初始化参数
// 此处可以改为 含有您业务逻辑的SpeechSynthesizerListener的实现类
mainHandler = new Handler() {
/*
* @param msg
*/
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
handle(msg);
}
};
SpeechSynthesizerListener listener = this;
InitConfig config = getInitConfig(listener);
mySyntherizer = new NonBlockSyntherizer(myReactContext, config, mainHandler); // 此处可以改为MySyntherizer 了解调用过程
}
protected InitConfig getInitConfig(SpeechSynthesizerListener listener) {
Map<String, String> params = getParams();
// 添加你自己的参数
InitConfig initConfig;
// appId appKey secretKey 网站上您申请的应用获取。注意使用离线合成功能的话,需要应用中填写您app的包名。包名在build.gradle中获取。
initConfig = new InitConfig(APP_ID, API_KEY, SECRET_KEY, ttsMode, params, listener);
// 如果您集成中出错,请将下面一段代码放在和demo中相同的位置,并复制InitConfig 和 AutoCheck到您的项目中
// 上线时请删除AutoCheck的调用
AutoCheck.getInstance(myReactContext).check(initConfig, new Handler() {
@Override
public void handleMessage(Message msg) {
if (msg.what == 100) {
AutoCheck autoCheck = (AutoCheck) msg.obj;
synchronized (autoCheck) {
String message = autoCheck.obtainDebugMessage();
Log.w("AutoCheckMessage", message);
}
}
}
});
return initConfig;
}
/**
* 合成的参数,可以初始化时填写,也可以在合成前设置。
*
* @return 合成参数Map
*/
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<>();
// 以下参数均为选填
// 设置在线发声音人: 0 普通女声(默认) 1 普通男声 3 情感男声<度逍遥> 4 情感儿童声<度丫丫>, 其它发音人见文档
params.put(SpeechSynthesizer.PARAM_SPEAKER, "0");
// 设置合成的音量,0-15 ,默认 5
params.put(SpeechSynthesizer.PARAM_VOLUME, "15");
// 设置合成的语速,0-15 ,默认 5
params.put(SpeechSynthesizer.PARAM_SPEED, "5");
// 设置合成的语调,0-15 ,默认 5
params.put(SpeechSynthesizer.PARAM_PITCH, "5");
return params;
}
protected void handle(Message msg) {
int what = msg.what;
switch (what) {
case PRINT:
String message = (String) msg.obj;
Log.i(NAME, message);
break;
case UI_CHANGE_INPUT_TEXT_SELECTION:
break;
case UI_CHANGE_SYNTHES_TEXT_SELECTION:
break;
default:
break;
}
}
@Override
public void onSynthesizeStart(String s) {
}
@Override
public void onSynthesizeDataArrived(String s, byte[] bytes, int i, int i1) {
}
@Override
public void onSynthesizeFinish(String s) {
}
@Override
public void onSpeechStart(String s) {
}
@Override
public void onSpeechProgressChanged(String s, int i) {
}
@Override
public void onSpeechFinish(String s) {
if (this.promise != null) {
this.promise.resolve(s);
this.promise = null;
}
}
@Override
public void onError(String s, SpeechError speechError) {
}
}