Newer
Older
react-native-hi-baidu-tts / android / src / main / java / cn / hieap / tts / HiBaiduTtsModule.java
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.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 {
    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;

    public HiBaiduTtsModule(ReactApplicationContext reactContext) {
        super(reactContext);
        myReactContext = reactContext;
        mainHandler = new Handler() {
            /*
             * @param msg
             */
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                handle(msg);
            }

        };
    }

    @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 appId, String apiKey, String secretKey) {
        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);
            } else {
                promise.resolve(result);
            }
        }
    }

    @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);
        }
    }

    @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的实现类
        SpeechSynthesizerListener listener = new UiMessageListener(mainHandler);
        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;
        }
    }
}