集成百度离在线语音唤醒/语音合成sdk
生活随笔
收集整理的這篇文章主要介紹了
集成百度离在线语音唤醒/语音合成sdk
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
在libs和jniLibs加入對應(yīng)jar包和so庫
/*** 喚醒*/ public class WakeUpUtils {private final String TAG = this.getClass().getSimpleName();private static WakeUpUtils utils = null;private EventManager eventManager;private EventListener listener;private boolean isInited = false;private static Handler handler;private final int WAKEUP = 1010;// 是否加載離線資源private boolean isOfflineEngineLoaded = false;public WakeUpUtils(){init();}public static WakeUpUtils getIntance(Handler mHandler){handler = mHandler;if (utils == null){synchronized (WakeUpUtils.class){if (utils == null){utils = new WakeUpUtils();}}}return utils;}private void init(){if (isInited){LogUtils.log(TAG,"還未調(diào)用release(),請勿新建一個新類");return;}isInited = true;//創(chuàng)建喚醒事件管理器eventManager = EventManagerFactory.create(MyApplication.context,"wp");//注冊喚醒事件監(jiān)聽器eventManager.registerListener(new EventListener() {@Overridepublic void onEvent(String name, String params1, byte[] bytes, int i, int i1) {try{listener = this;if ("wp.data".equals(name)){LogUtils.log("喚醒", params1);TTSUtils.getInstance().speak(MyApplication.context.getString(R.string.wakeup_yes), true); // handler.sendEmptyMessage(WAKEUP); // RecognizerUtils.getIntance(handler).start();}else if ("wp.exit".equals(name)){LogUtils.log("喚醒退出", params1);}} catch (Exception e) {e.printStackTrace();}}});loadOfflineEngine(fetchOfflineParams());}/*** 離線命令詞,在線不需要調(diào)用** @param params 離線命令詞加載參數(shù),見文檔“ASR_KWS_LOAD_ENGINE 輸入事件參數(shù)”*/private void loadOfflineEngine(Map<String, Object> params) {String json = new JSONObject(params).toString();// SDK集成步驟(可選)加載離線命令詞(離線時使用)eventManager.send(SpeechConstant.ASR_KWS_LOAD_ENGINE, json, null, 0, 0);isOfflineEngineLoaded = true;// 沒有ASR_KWS_LOAD_ENGINE這個回調(diào)表試失敗,如缺少第一次聯(lián)網(wǎng)時下載的正式授權(quán)文件。}private Map<String, Object> fetchOfflineParams() {Map<String, Object> map = new HashMap<String, Object>();map.put(SpeechConstant.DECODER, 2);map.put(SpeechConstant.ASR_OFFLINE_ENGINE_GRAMMER_FILE_PATH, "assets:///baidu_speech_grammar.bsg");map.putAll(fetchSlotDataParam());return map;}private Map<String, Object> fetchSlotDataParam() {Map<String, Object> map = new HashMap<String, Object>();try {JSONObject json = new JSONObject();json.put("name", new JSONArray().put("媽媽").put("老伍")).put("appname", new JSONArray().put("手百").put("度秘"));map.put(SpeechConstant.SLOT_DATA, json);} catch (JSONException e) {e.printStackTrace();}return map;}public void start() {if (eventManager != null){HashMap params = new HashMap();params.put("kws-file","assets:///WakeUp.bin");eventManager.send("wp.start",new JSONObject(params).toString(), null,0,0);}}public void stop() {if (eventManager != null){eventManager.send(SpeechConstant.WAKEUP_STOP, null, null, 0, 0);}}public void release() {isInited = false;stop();if (eventManager != null){if (isOfflineEngineLoaded) {// SDK集成步驟 如果之前有調(diào)用過 加載離線命令詞,這里要對應(yīng)釋放eventManager.send(SpeechConstant.ASR_KWS_UNLOAD_ENGINE, null, null, 0, 0);isOfflineEngineLoaded = false;}eventManager.unregisterListener(listener);eventManager = null;utils = null;}}} // 合成 public class TTSUtils {private static TTSUtils utils = null;private SpeechSynthesizer mSpeechSynthesizer;private boolean isWakeUp = false;public TTSUtils(){new Thread(new Runnable() {@Overridepublic void run() {init();}}).start();}public static TTSUtils getInstance(){if (utils == null){synchronized (TTSUtils.class){if (utils == null){utils = new TTSUtils();}}}return utils;}/*** speak 實際上是調(diào)用 synthesize后,獲取音頻流,然后播放。* 獲取音頻流的方式見SaveFileActivity及FileSaveListener* 需要合成的文本text的長度不能超過1024個GBK字節(jié)。*/public void speak(String text) {// 需要合成的文本text的長度不能超過1024個GBK字節(jié)。if (mSpeechSynthesizer != null){mSpeechSynthesizer.speak(text);}}/*** speak 實際上是調(diào)用 synthesize后,獲取音頻流,然后播放。* 獲取音頻流的方式見SaveFileActivity及FileSaveListener* 需要合成的文本text的長度不能超過1024個GBK字節(jié)。*/public void speak(String text, boolean isWakeUp) {this.isWakeUp = isWakeUp;// 需要合成的文本text的長度不能超過1024個GBK字節(jié)。if (mSpeechSynthesizer != null){mSpeechSynthesizer.speak(text);}}public void pause() {// 需要合成的文本text的長度不能超過1024個GBK字節(jié)。if (mSpeechSynthesizer != null){mSpeechSynthesizer.pause();}}public void resume() {// 需要合成的文本text的長度不能超過1024個GBK字節(jié)。if (mSpeechSynthesizer != null){mSpeechSynthesizer.resume();}}public void stop() {// 需要合成的文本text的長度不能超過1024個GBK字節(jié)。if (mSpeechSynthesizer != null){mSpeechSynthesizer.stop();}}public void release() {// 需要合成的文本text的長度不能超過1024個GBK字節(jié)。if (mSpeechSynthesizer != null){mSpeechSynthesizer.release();}}private void init(){mSpeechSynthesizer = SpeechSynthesizer.getInstance();mSpeechSynthesizer.setContext(MyApplication.context.getApplicationContext());mSpeechSynthesizer.setSpeechSynthesizerListener(new SpeechSynthesizerListener() {@Overridepublic void onSynthesizeStart(String s) { // LogUtils.log("TTSUtils", "onSynthesizeStart" + "--" + s);}@Overridepublic void onSynthesizeDataArrived(String s, byte[] bytes, int i) { // LogUtils.log("TTSUtils", "onSynthesizeDataArrived" + "--" + s);}@Overridepublic void onSynthesizeFinish(String s) { // LogUtils.log("TTSUtils", "onSynthesizeFinish" + "--" + s);}@Overridepublic void onSpeechStart(String s) { // LogUtils.log("TTSUtils", "onSpeechStart" + "--" + s);}@Overridepublic void onSpeechProgressChanged(String s, int i) { // LogUtils.log("TTSUtils", "onSpeechProgressChanged" + "--" + s);}@Overridepublic void onSpeechFinish(String s) { // LogUtils.log("TTSUtils", "onSpeechFinish" + "--" + s);if (isWakeUp){isWakeUp = false;RecognizerUtils.getIntance().start();}}@Overridepublic void onError(String s, SpeechError speechError) { // LogUtils.log("TTSUtils", "onError" + "--" + s + "--" +speechError.description);}});/*這里只是為了讓Demo運行使用的APPID,請?zhí)鎿Q成自己的id。*/mSpeechSynthesizer.setAppId("15692915");/*這里只是為了讓Demo正常運行使用APIKey,請?zhí)鎿Q成自己的APIKey*/mSpeechSynthesizer.setApiKey("R2XiXKorcR75HyIejnBROSMm","Co85H7ZXROB0DEM4WfLgAlEojUd5GXFi");// 授權(quán)檢測接口(只是通過AuthInfo進(jìn)行檢驗授權(quán)是否成功。選擇純在線可以不必調(diào)用auth方法。AuthInfo authInfo = mSpeechSynthesizer.auth(TtsMode.MIX);if (!authInfo.isSuccess()) {// 離線授權(quán)需要網(wǎng)站上的應(yīng)用填寫包名。本demo的包名是com.baidu.tts.sample,定義在build.gradle中String errorMsg = authInfo.getTtsError().getDetailMessage();LogUtils.log("TTSUtils","鑒權(quán)失敗 =" + errorMsg);} else {LogUtils.log("TTSUtils","驗證通過,離線正式授權(quán)文件存在。");}getParams();// 初始化ttsint result = mSpeechSynthesizer.initTts(TtsMode.MIX);if (result != 0) {LogUtils.log("TTSUtils","【error】initTts 初始化失敗 + errorCode:" + result);return;}// 此時可以調(diào)用 speak和synthesize方法LogUtils.log("TTSUtils", "合成引擎初始化成功");}/*** 合成的參數(shù),可以初始化時填寫,也可以在合成前設(shè)置。** @return*/protected Map<String, String> getParams() {Map<String, String> params = new HashMap<>();// 離線資源文件,從assets目錄中復(fù)制到臨時目錄,需要在initTTs方法前完成setOfflineVoiceType(VOICE_FEMALE);// 文本模型文件路徑 (離線引擎使用), 注意TEXT_FILENAME必須存在并且可讀mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_TTS_TEXT_MODEL_FILE, textFilename);// 聲學(xué)模型文件路徑 (離線引擎使用), 注意TEXT_FILENAME必須存在并且可讀mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_TTS_SPEECH_MODEL_FILE, modelFilename);// 以下參數(shù)均為選填// 設(shè)置在線發(fā)聲音人: 0 普通女聲(默認(rèn)) 1 普通男聲 2 特別男聲 3 情感男聲<度逍遙> 4 情感兒童聲<度丫丫>params.put(SpeechSynthesizer.PARAM_SPEAKER, "0");// 設(shè)置合成的音量,0-9 ,默認(rèn) 5params.put(SpeechSynthesizer.PARAM_VOLUME, "9");// 設(shè)置合成的語速,0-9 ,默認(rèn) 5params.put(SpeechSynthesizer.PARAM_SPEED, "5");// 設(shè)置合成的語調(diào),0-9 ,默認(rèn) 5params.put(SpeechSynthesizer.PARAM_PITCH, "5");params.put(SpeechSynthesizer.PARAM_MIX_MODE, SpeechSynthesizer.MIX_MODE_HIGH_SPEED_SYNTHESIZE);// 該參數(shù)設(shè)置為TtsMode.MIX生效。即純在線模式不生效。// MIX_MODE_DEFAULT 默認(rèn) ,wifi狀態(tài)下使用在線,非wifi離線。在線狀態(tài)下,請求超時6s自動轉(zhuǎn)離線// MIX_MODE_HIGH_SPEED_SYNTHESIZE_WIFI wifi狀態(tài)下使用在線,非wifi離線。在線狀態(tài)下, 請求超時1.2s自動轉(zhuǎn)離線// MIX_MODE_HIGH_SPEED_NETWORK , 3G 4G wifi狀態(tài)下使用在線,其它狀態(tài)離線。在線狀態(tài)下,請求超時1.2s自動轉(zhuǎn)離線// MIX_MODE_HIGH_SPEED_SYNTHESIZE, 2G 3G 4G wifi狀態(tài)下使用在線,其它狀態(tài)離線。在線狀態(tài)下,請求超時1.2s自動轉(zhuǎn)離線// 聲學(xué)模型文件路徑 (離線引擎使用), 請確認(rèn)下面兩個文件存在params.put(SpeechSynthesizer.PARAM_TTS_TEXT_MODEL_FILE, textFilename);params.put(SpeechSynthesizer.PARAM_TTS_SPEECH_MODEL_FILE, modelFilename);return params;}private static HashMap<String, Boolean> mapInitied = new HashMap<String, Boolean>();private final String VOICE_FEMALE = "F";//離線女聲private final String VOICE_MALE = "M";//離線男聲private final String VOICE_DUYY = "Y";//離線度逍遙private final String VOICE_DUXY = "X";//離線度丫丫private String textFilename = "";private String modelFilename = "";private void setOfflineVoiceType(String voiceType) {String text = "bd_etts_text.dat";String model;if (VOICE_MALE.equals(voiceType)) {model = "bd_etts_common_speech_m15_mand_eng_high_am-mix_v3.0.0_20170505.dat";} else if (VOICE_FEMALE.equals(voiceType)) {model = "bd_etts_common_speech_f7_mand_eng_high_am-mix_v3.0.0_20170512.dat";} else if (VOICE_DUXY.equals(voiceType)) {model = "bd_etts_common_speech_yyjw_mand_eng_high_am-mix_v3.0.0_20170512.dat";} else if (VOICE_DUYY.equals(voiceType)) {model = "bd_etts_common_speech_as_mand_eng_high_am_v3.0.0_20170516.dat";} else {throw new RuntimeException("voice type is not in list");}textFilename = copyAssetsFile(text);modelFilename = copyAssetsFile(model);}private String copyAssetsFile(String sourceFilename) {String destFilename = FileUtil.createTmpDir(MyApplication.context) + "/" + sourceFilename;try {File file = new File(destFilename);if (file.exists()){return destFilename;}boolean recover = false;Boolean existed = mapInitied.get(sourceFilename); // 啟動時完全覆蓋一次if (existed == null || !existed) {recover = true;}FileUtil.copyFromAssets(MyApplication.context.getApplicationContext().getAssets(),sourceFilename, destFilename, recover);return destFilename;}catch (Exception e){e.printStackTrace();}return destFilename;}總結(jié)
以上是生活随笔為你收集整理的集成百度离在线语音唤醒/语音合成sdk的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 北京大学前言交叉学科研究院大数据中心夏令
- 下一篇: java dbcp连接池 使用_Java