Browse Source

fix: init

sibichiAi
高志龙 8 months ago
parent
commit
93dc295b17
  1. 6
      app/build.gradle
  2. BIN
      app/libs/DUI-lite-SDK-for-Android-3.5.0-466a4c77.jar
  3. BIN
      app/libs/arm64-v8a/libailog2.so
  4. BIN
      app/libs/arm64-v8a/libduidns.so
  5. BIN
      app/libs/arm64-v8a/libduiitn.so
  6. BIN
      app/libs/arm64-v8a/libduiutils.so
  7. BIN
      app/libs/arm64-v8a/libliteca.so
  8. BIN
      app/libs/arm64-v8a/libmp3.so
  9. BIN
      app/libs/arm64-v8a/libopusogg.so
  10. BIN
      app/libs/arm64-v8a/libspeex.so
  11. BIN
      app/libs/arm64-v8a/libvad.so
  12. BIN
      app/libs/armeabi-v7a/libailog2.so
  13. BIN
      app/libs/armeabi-v7a/libduidns.so
  14. BIN
      app/libs/armeabi-v7a/libduiitn.so
  15. BIN
      app/libs/armeabi-v7a/libduiutils.so
  16. BIN
      app/libs/armeabi-v7a/libliteca.so
  17. BIN
      app/libs/armeabi-v7a/libmp3.so
  18. BIN
      app/libs/armeabi-v7a/libopusogg.so
  19. BIN
      app/libs/armeabi-v7a/libspeex.so
  20. BIN
      app/libs/armeabi-v7a/libvad.so
  21. BIN
      app/libs/armeabi/libailog2.so
  22. BIN
      app/libs/armeabi/libduidns.so
  23. BIN
      app/libs/armeabi/libduiitn.so
  24. BIN
      app/libs/armeabi/libduiutils.so
  25. BIN
      app/libs/armeabi/libliteca.so
  26. BIN
      app/libs/armeabi/libmp3.so
  27. BIN
      app/libs/armeabi/libopusogg.so
  28. BIN
      app/libs/armeabi/libspeex.so
  29. BIN
      app/libs/armeabi/libvad.so
  30. BIN
      app/src/main/assets/vad_aihome_v0.11.bin
  31. 20
      app/src/main/java/qianmu/container/activity/H5/UpdateFileActivity.java
  32. 286
      app/src/main/java/qianmu/container/activity/H5/WebViewActivity.java
  33. 4
      app/src/main/java/qianmu/container/app/Constant.java
  34. 29
      app/src/main/java/qianmu/container/app/MyApplication.java
  35. 231
      app/src/main/java/qianmu/container/util/TTSUtil.java

6
app/build.gradle

@ -10,7 +10,7 @@ android {
minSdkVersion 22
targetSdkVersion 30
versionCode 6
versionName "V2.0.7.33"
versionName "V2.0.7.30"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles 'consumer-rules.pro'
@ -90,14 +90,14 @@ dependencies {
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation files('libs\\ymeeting.jar')//亿
implementation project(path: ':playerview')
implementation files('libs/SparkChain.aar')
implementation files('libs\\zckjAPI-2.2.jar')//
implementation files('libs\\jna-min.jar')
implementation files('libs\\toolbox_kit.jar')//
implementation files('libs\\shockman.jar')//
implementation files('libs\\signway.jar') //
implementation files('libs\\sdkapi.jar') //Bv-3588
implementation files('libs\\smdt.jar')//
implementation files('libs\\smdt.jar') //
implementation files('libs\\DUI-lite-SDK-for-Android-3.5.0-466a4c77.jar') //
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'

BIN
app/libs/DUI-lite-SDK-for-Android-3.5.0-466a4c77.jar

Binary file not shown.

BIN
app/libs/arm64-v8a/libailog2.so

Binary file not shown.

BIN
app/libs/arm64-v8a/libduidns.so

Binary file not shown.

BIN
app/libs/arm64-v8a/libduiitn.so

Binary file not shown.

BIN
app/libs/arm64-v8a/libduiutils.so

Binary file not shown.

BIN
app/libs/arm64-v8a/libliteca.so

Binary file not shown.

BIN
app/libs/arm64-v8a/libmp3.so

Binary file not shown.

BIN
app/libs/arm64-v8a/libopusogg.so

Binary file not shown.

BIN
app/libs/arm64-v8a/libspeex.so

Binary file not shown.

BIN
app/libs/arm64-v8a/libvad.so

Binary file not shown.

BIN
app/libs/armeabi-v7a/libailog2.so

Binary file not shown.

BIN
app/libs/armeabi-v7a/libduidns.so

Binary file not shown.

BIN
app/libs/armeabi-v7a/libduiitn.so

Binary file not shown.

BIN
app/libs/armeabi-v7a/libduiutils.so

Binary file not shown.

BIN
app/libs/armeabi-v7a/libliteca.so

Binary file not shown.

BIN
app/libs/armeabi-v7a/libmp3.so

Binary file not shown.

BIN
app/libs/armeabi-v7a/libopusogg.so

Binary file not shown.

BIN
app/libs/armeabi-v7a/libspeex.so

Binary file not shown.

BIN
app/libs/armeabi-v7a/libvad.so

Binary file not shown.

BIN
app/libs/armeabi/libailog2.so

Binary file not shown.

BIN
app/libs/armeabi/libduidns.so

Binary file not shown.

BIN
app/libs/armeabi/libduiitn.so

Binary file not shown.

BIN
app/libs/armeabi/libduiutils.so

Binary file not shown.

BIN
app/libs/armeabi/libliteca.so

Binary file not shown.

BIN
app/libs/armeabi/libmp3.so

Binary file not shown.

BIN
app/libs/armeabi/libopusogg.so

Binary file not shown.

BIN
app/libs/armeabi/libspeex.so

Binary file not shown.

BIN
app/libs/armeabi/libvad.so

Binary file not shown.

BIN
app/src/main/assets/vad_aihome_v0.11.bin

Binary file not shown.

20
app/src/main/java/qianmu/container/activity/H5/UpdateFileActivity.java

@ -16,8 +16,6 @@ import androidx.databinding.DataBindingUtil;
import com.alibaba.android.arouter.facade.annotation.Route;
import com.alibaba.android.arouter.launcher.ARouter;
import com.iflytek.sparkchain.core.SparkChain;
import com.iflytek.sparkchain.core.SparkChainConfig;
import com.sdkapi.api.SdkApi;
import java.io.File;
@ -255,23 +253,6 @@ public class UpdateFileActivity extends BaseActivity {
SdkApi.newInstance(this);
}
if("kdxf".equals(Constant.TTSFac)){
Log.d("MainActivity: ","initKDXFSDK");
// 初始化SDK,Appid等信息在清单中配置
SparkChainConfig sparkChainConfig = SparkChainConfig.builder();
sparkChainConfig.appID(getResources().getString(R.string.appid))
.apiKey(getResources().getString(R.string.apikey))
.apiSecret(getResources().getString(R.string.apiSecret))//应用申请的appid三元组
.logLevel(666);
int ret = SparkChain.getInst().init(getApplicationContext(),sparkChainConfig);
String result;
if(ret == 0){
result = "SDK初始化成功,请选择相应的功能点击体验。";
}else{
result = "SDK初始化失败,错误码:" + ret;
}
Log.e("MainActivity: ",result);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
if(!Environment.isExternalStorageManager()){
Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
@ -280,6 +261,7 @@ public class UpdateFileActivity extends BaseActivity {
return;
}
}
//设置开机自启应用
if(Constant.androidBoardType.equals("smt")){
MyApplication.getInstance().getSmdt().sys_setSystemBootApp(MyApplication.getInstance().getPackageName());

286
app/src/main/java/qianmu/container/activity/H5/WebViewActivity.java

@ -32,31 +32,20 @@ import androidx.annotation.NonNull;
import androidx.databinding.DataBindingUtil;
import androidx.recyclerview.widget.GridLayoutManager;
import com.aispeech.AIError;
import com.aispeech.AIResult;
import com.aispeech.common.AIConstant;
import com.aispeech.common.JSONResultParser;
import com.aispeech.export.config.AICloudASRConfig;
import com.aispeech.export.engines2.AICloudASREngine;
import com.aispeech.export.intent.AICloudASRIntent;
import com.aispeech.export.listeners.AIASRListener;
import com.alibaba.android.arouter.facade.annotation.Route;
import com.alibaba.android.arouter.launcher.ARouter;
import com.google.gson.Gson;
import com.iflytek.sparkchain.core.asr.ASR;
import com.iflytek.sparkchain.core.asr.AsrCallbacks;
import com.iflytek.sparkchain.core.asr.Segment;
import com.iflytek.sparkchain.core.asr.Transcription;
import com.iflytek.sparkchain.core.asr.Vad;
import com.shockman.sm.vendor.IHttp;
import com.shockman.sm.vendor.SmUtils;
import com.shockman.sm.vendor.TargetVo;
import org.greenrobot.eventbus.EventBus;
import org.java_websocket.drafts.Draft_6455;
import org.java_websocket.enums.ReadyState;
import java.io.File;
import java.net.URI;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Scanner;
import java.util.concurrent.Executors;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import qianmu.container.R;
import qianmu.container.activity.BaseActivity;
@ -64,24 +53,12 @@ import qianmu.container.adapter.KeyAdapter;
import qianmu.container.app.Constant;
import qianmu.container.app.MyApplication;
import qianmu.container.data.AppData;
import qianmu.container.data.DeviceData;
import qianmu.container.data.ScreenSaverData;
import qianmu.container.databinding.ActivityWebviewBinding;
import qianmu.container.entity.AppVersion;
import qianmu.container.entity.KdxfBean;
import qianmu.container.entity.MessageEvent;
import qianmu.container.entity.ResourceFileBean;
import qianmu.container.entity.ScreenSaver;
import qianmu.container.entity.TTSMessage;
import qianmu.container.entity.Vocbean;
import qianmu.container.listener.QueryFinishListener;
import qianmu.container.socket.SocketClient;
import qianmu.container.util.AppUtil;
import qianmu.container.util.AudioPlay;
import qianmu.container.util.CalendarUtils;
import qianmu.container.util.DeviceUtil;
import qianmu.container.util.FileUtil;
import qianmu.container.util.GsonUtil;
import qianmu.container.util.KeyboardUtil;
import qianmu.container.util.LoggerUtil;
import qianmu.container.util.StringUtil;
@ -103,13 +80,10 @@ public class WebViewActivity extends BaseActivity {
//static String HtmlUrl = "http://192.168.1.196:5173/";
int time = 0;
private VideoView currentVideo;
SocketClient localSocketClient;
// 语音听写对象
private ASR mAsr;
private boolean isrun = false; // 是否正在听写
private boolean isdws = false; // 是否可以修正
private String language = "zh_cn";
private AICloudASREngine mEngine;
private AICloudASRIntent aiCloudASRIntent;
private TTSUtil ttsUtil;
Handler handler = new Handler() {
@ -176,8 +150,6 @@ public class WebViewActivity extends BaseActivity {
//设置密码
initPass();
if("sbc".equals(Constant.TTSFac)){ // 思必驰
connectLocalSocket();
}else{ //kdxf
initASR();
ttsUtil = new TTSUtil();
ttsUtil.initTts();
@ -422,7 +394,6 @@ public class WebViewActivity extends BaseActivity {
@Override
protected void onDestroy() {
super.onDestroy();
destroyLocalSocketClient();
LoggerUtil.e(TAG, "onDestroy()");
}
@ -447,7 +418,6 @@ public class WebViewActivity extends BaseActivity {
});
binding.web.addJavascriptInterface(new AndroidtoJs(), "android");
}
int count = 0;
// JS 调用 android
public class AndroidtoJs extends Object {
// 回到屏保页面
@ -484,25 +454,12 @@ public class WebViewActivity extends BaseActivity {
public void startRecord() {
LoggerUtil.e(TAG,"JS调用了Android的方法:startRecord()");
if("sbc".equals(Constant.TTSFac)) {
if (localSocketClient == null) initLocalSocketClient(); //-------------------------------
localSocketClient.send(StringUtil.strSplice("{\"method\":\"/tts/stop\"}"));
localSocketClient.send(StringUtil.strSplice("{\"method\":\"/asr/start\"}"));
}else{
if(isrun){
return;
}
ttsUtil.stopTTs();
if(mAsr == null){
if(mEngine == null){
LoggerUtil.d(TAG, "未初始化");
initASR();
}
count++;
int ret = mAsr.startListener(count+"");
if(ret != 0){
LoggerUtil.d(TAG,"识别开启失败,错误码:"+ret+"\n");
}else{
isrun = true;
}
mEngine.start(aiCloudASRIntent);
}
runOnUiThread(new Runnable() {
@Override
@ -516,9 +473,6 @@ public class WebViewActivity extends BaseActivity {
public void stopRecord() {
LoggerUtil.e(TAG,"JS调用了Android的方法:stopRecord()");
if("sbc".equals(Constant.TTSFac)) {
if (localSocketClient == null) initLocalSocketClient(); //-------------------------------
localSocketClient.send(StringUtil.strSplice("{\"method\":\"/asr/stop\"}"));
}else{
stopAsr();
}
}
@ -527,9 +481,6 @@ public class WebViewActivity extends BaseActivity {
public void startTTS(String txt) {
LoggerUtil.e(TAG,"JS调用了Android的方法:startTTS()");
if("sbc".equals(Constant.TTSFac)) {
if (localSocketClient == null) initLocalSocketClient(); //-------------------------------
localSocketClient.send(StringUtil.strSplice("{\"method\": \"/tts/start\",\"params\": {\"text\":\"", txt, "\", \"mode\":\"autoPlay\"}}"));
}else{
ttsUtil.startTTs(txt);
}
}
@ -538,9 +489,6 @@ public class WebViewActivity extends BaseActivity {
public void stopTTS() {
LoggerUtil.e(TAG,"JS调用了Android的方法:stopTTS()");
if("sbc".equals(Constant.TTSFac)){
if (localSocketClient == null) initLocalSocketClient(); //-------------------------------
localSocketClient.send(StringUtil.strSplice("{\"method\":\"/tts/stop\"}"));
}else{
ttsUtil.stopTTs();
}
runOnUiThread(new Runnable() {
@ -611,37 +559,26 @@ public class WebViewActivity extends BaseActivity {
//-------- 科大讯飞
private void initASR(){
if(mAsr == null){
mAsr = new ASR();
mAsr.registerCallbacks(mAsrCallbacks);
mAsr.language(language);//语种,zh_cn:中文,en_us:英文。其他语种参见集成文档
mAsr.domain("iat");//应用领域,iat:日常用语。其他领域参见集成文档
mAsr.accent("mandarin");//方言,mandarin:普通话。方言仅当language为中文时才会生效。其他方言参见集成文档。
mAsr.vinfo(true);//返回子句结果对应的起始和结束的端点帧偏移值。
if("zh_cn".equals(language)){
mAsr.dwa("wpgs");//动态修正
}
if(mEngine == null){
AICloudASRConfig config = new AICloudASRConfig();
config.setLocalVadEnable(true);
config.setVadResource("vad_aihome_v0.11.bin");
mEngine = AICloudASREngine.createInstance();
aiCloudASRIntent = new AICloudASRIntent();
aiCloudASRIntent.setRealback(true);//打开实时反馈功能
aiCloudASRIntent.setResourceType("aihome");
aiCloudASRIntent.setEnableNumberConvert(true);//设置启用识别结果汉字数字转阿拉伯数字功能
aiCloudASRIntent.setWaitingTimeout(5000);//设置等待识别结果超时时长,默认5000ms
aiCloudASRIntent.setNoSpeechTimeOut(2000);
aiCloudASRIntent.setPauseTime(1000);
mEngine.init(config, new AIASRListenerImpl());
}
}
AsrCallbacks mAsrCallbacks = new AsrCallbacks() {
@Override
public void onResult(ASR.ASRResult asrResult, Object o) {
//以下信息需要开发者根据自身需求,如无必要,可不需要解析执行。
int status = asrResult.getStatus(); //结果数据状态,0:识别的第一块结果,1:识别中间结果,2:识别最后一块结果
String result = asrResult.getBestMatchText(); //识别结果
if(status == 0){
voiceContent(result);
}else if(status == 2){
voiceContent(result);
stopAsr();
}else{
voiceContent(result);
}
}
private class AIASRListenerImpl implements AIASRListener {
@Override
public void onError(ASR.ASRError asrError, Object o) {
public void onError(AIError error) {
LoggerUtil.e("ASRInit: ",error.getMessage());
// 在非主线程中需要调用 WebView 方法时
runOnUiThread(new Runnable() {
@Override
@ -652,28 +589,82 @@ public class WebViewActivity extends BaseActivity {
stopAsr();
}
public void onResults(AIResult results) {
if (results.getResultType() == AIConstant.AIENGINE_MESSAGE_TYPE_JSON) {
JSONResultParser parser = new JSONResultParser((String) results.getResultObject());
if("".equals(parser.getAllText())) {
voiceContent(parser.getVar());
}
}
}
@Override
public void onInit(int status) {
if (status == AIConstant.OPT_SUCCESS) {
LoggerUtil.e("ASRInit: ","初始化成功!");
} else {
LoggerUtil.e("ASRInit: ","初始化失败!code:" + status);
}
}
@Override
public void onBeginOfSpeech() {
public void onBeginningOfSpeech() {
//本地vad打开时,才会执行
LoggerUtil.e("ASRInit: ","onBeginningOfSpeech");
}
@Override
public void onNotOneShot() {
//do nothing
LoggerUtil.e("ASRInit: ","onNotOneShot");
}
@Override
public void onEndOfSpeech() {
Log.d(TAG, "结束说话");
//本地vad打开时,才会执行
runOnUiThread(new Runnable() {
@Override
public void run() {
binding.web.evaluateJavascript("javascript: window.youAskOver('');", null);
}
});
LoggerUtil.e("ASRInit: ","onEndOfSpeech");
}
};
@Override
public void onReadyForSpeech() {
LoggerUtil.e("ASRInit: ","onReadyForSpeech");
}
@Override
public void onResultDataReceived(byte[] buffer, int size, int wakeupType) {
LoggerUtil.e("ASRInit: ","onReadyForSpeech "+String.valueOf(size));
}
@Override
public void onRmsChanged(float rmsdB) {
Log.d(TAG, "" + rmsdB);
}
@Override
public void onResultDataReceived(byte[] buffer, int size) {
//do nothing
}
@Override
public void onRawDataReceived(byte[] buffer, int size) {
//do nothing
LoggerUtil.e("ASRInit: ","onRawDataReceived "+String.valueOf(size));
}
}
/**
* android调用js传送识别语音内容
*/
public void voiceContent(String msg) {
if (binding.web != null) {
LoggerUtil.e(TAG, "android调用js方法:voiceContent(),语音内容:" + msg);
LoggerUtil.e(TAG, "android调用js方法:giveAskText(),语音内容:" + msg);
runOnUiThread(new Runnable() {
@Override
public void run() {
@ -683,110 +674,9 @@ public class WebViewActivity extends BaseActivity {
}
}
private void stopAsr(){
if(isrun){
if(mAsr!=null){
mAsr.stopListener(false);
}
isrun = false;
}
}
// 思必驰----------------
private void initLocalSocketClient() {
try {
URI localUri = new URI("ws://127.0.0.1:50002");
LoggerUtil.e("TTSSocketUri", localUri.toString());
localSocketClient = new SocketClient(localUri, new Draft_6455());
setLocalSocketListener();
} catch (Throwable t) {
LoggerUtil.e("initSocketClient", StringUtil.getThrowableStr(t));
}
}
public void connectLocalSocket() {
try {
//客户端不存在时 创建客户端设置监听事件
if (localSocketClient == null) initLocalSocketClient();
//获取客户端当前的连接状态
ReadyState state = localSocketClient.getReadyState();
LoggerUtil.e("connectLocalSocket", "TTS客户端连接状态:"+ GsonUtil.getGson().toJson(state));
boolean open = localSocketClient.isOpen();
LoggerUtil.e("connectLocalSocket", "TTS客户端连接状态:open="+open);
if (open) return;
//获取客户端当前的连接状态
if (localSocketClient.isOpen()) return;
//未连接状态时 连接服务器
if (state.equals(ReadyState.NOT_YET_CONNECTED)) localSocketClient.connect();
else if (state.equals(ReadyState.CLOSING) || state.equals(ReadyState.CLOSED)) {
//正在关闭或者关闭状态时 重新连接服务器
localSocketClient.reconnect();
}
} catch (Throwable t) {
LoggerUtil.e("connectLocalSocket", StringUtil.getThrowableStr(t));
destroyLocalSocketClient();
if(mEngine!=null){
mEngine.cancel();
}
}
//语音交互
private void setLocalSocketListener() {
localSocketClient.setOnOpenListener((handshakeData) -> {
LoggerUtil.e("connectLocalSocket", "TTS客户端连接成功");
localSocketClient.send(StringUtil.strSplice("{\"method\":\"/asr/stop\"}"));
});
localSocketClient.setOnMessageListener((conn, message) -> {
try {
TTSMessage messageBean = new Gson().fromJson(message, TTSMessage.class);
TTSMessage.Params content = messageBean.getParams();
if (content == null) return;
String method = messageBean.getMethod();
if("asr.text".equals(method)){
LoggerUtil.e("ttsSocket:",content.getText());
runOnUiThread(new Runnable() {
@Override
public void run() {
binding.web.loadUrl(StringUtil.strSplice("javascript:window.giveAskText('", content.getText(), "');"));
}
});
}else if("asr.result".equals(method)){
LoggerUtil.e("ttsSocket:",content.getText());
runOnUiThread(new Runnable() {
@Override
public void run() {
localSocketClient.send(StringUtil.strSplice("{\"method\":\"/asr/stop\"}"));
binding.web.loadUrl(StringUtil.strSplice("javascript:window.youAskOver('", content.getText(), "');"));
}
});
}else if("tts.result".equals(method)){
LoggerUtil.e("ttsSocket:", messageBean.getParams().getStatus().trim());
if("end".equals(messageBean.getParams().getStatus().trim())) {
runOnUiThread(new Runnable() {
@Override
public void run() {
changeVideo("bg");
}
});
}
}
} catch (Throwable t) {
LoggerUtil.e("setOnMessageListener", StringUtil.getThrowableStr(t));
}
});
localSocketClient.setOnCloseListener((code, reason, remote) -> {
LoggerUtil.e("LocSocCliManager", "onClose:code="+code);
if (localSocketClient == null){
initLocalSocketClient();
}else {
localSocketClient.reconnect();
}
});
localSocketClient.setOnErrorListener((ex) -> LoggerUtil.e("LocSocCliManager", "onError"));
}
//销毁当前的客户端
public void destroyLocalSocketClient() {
if (localSocketClient == null) return;
localSocketClient.close();
localSocketClient = null;
}
}

4
app/src/main/java/qianmu/container/app/Constant.java

@ -23,7 +23,7 @@ public class Constant {
public static boolean newGuide = false; // 指路机类型,true:新版指路机 false:老板指路机(流花)
public static String mqttState = ""; // 屏幕连接方式
// public static String androidBoardType = ""; //设备板子型号 无固定版
// public static String androidBoardType = "ys"; // 设备板子型号 ys(亿晟) 北京颐堤港定制touch
public static String androidBoardType = "ys"; // 设备板子型号 ys(亿晟) 北京颐堤港定制touch
// public static String androidBoardType = "xwst"; //设备板子型号 xwst(欣威视通3399)
// public static String androidBoardType = "xwst2"; //设备板子型号 xwst2(欣威视通3588、T982、3576)
// public static String androidBoardType = "zc"; //设备板子型号 zc(卓策主板——王府井喜悦、杨浦中心医院)
@ -31,7 +31,7 @@ public class Constant {
// public static String androidBoardType = "nova"; //设备板子型号 诺瓦盒子 华贸LED
// public static String androidBoardType = "huidu"; //设备板子型号 huidu(灰度主板) 罗湖寻车机
// public static String androidBoardType = "bv"; //设备板子型号 Bv-3588M
public static String androidBoardType = "smt"; //设备板子型号 视美泰
// public static String androidBoardType = "smt"; //设备板子型号 视美泰
public static String TTSFac = "sbc"; // 语音识别厂家 kdxf--科大讯飞 sbc-思必驰
public static final String VOID_STOP = "void_stop";//

29
app/src/main/java/qianmu/container/app/MyApplication.java

@ -7,7 +7,10 @@ import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.PowerManager;
import android.util.Log;
import com.aispeech.DUILiteConfig;
import com.aispeech.DUILiteSDK;
import com.alibaba.android.arouter.BuildConfig;
import com.alibaba.android.arouter.launcher.ARouter;
import com.jakewharton.processphoenix.ProcessPhoenix;
@ -81,9 +84,35 @@ public class MyApplication extends Application {
if (Constant.androidBoardType.equals("smt")) {
smdt = SmdtManagerNew.getInstance(this);
}
if(Constant.TTSFac.equals("sbc")){
initSbcSDK();
}
// refWatcher = LeakCanary.install(this);
}
private void initSbcSDK(){
// 产品认证需设置 apiKey, productId, productKey, productSecret
DUILiteConfig config = new DUILiteConfig.Builder()
.setApiKey("d823edab41b8d823edab41b868ecc552")
.setProductId("279632533")
.setProductKey("ab73065d16e11bcfac026eee3db9f6cb")
.setProductSecret("85d9490c438099acc33be7676799399f").create();
DUILiteSDK.init(getApplicationContext());
// SDK 授权
DUILiteSDK.doAuth(getApplicationContext(), config, new DUILiteSDK.InitListener() {
@Override
public void success() {
LoggerUtil.d("DUILiteSDKInit: ", "授权成功! ");
}
@Override
public void error(String errorCode,String errorInfo) {
LoggerUtil.d("DUILiteSDKInit: ", "授权失败, errorcode: "+errorCode+",errorInfo:"+errorInfo);
}
});
}
public Lztek getLztek() {
if (lztek == null) {
lztek = Lztek.create(this.getBaseContext());

231
app/src/main/java/qianmu/container/util/TTSUtil.java

@ -1,20 +1,18 @@
package qianmu.container.util;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import androidx.annotation.NonNull;
import com.iflytek.sparkchain.core.tts.OnlineTTS;
import com.iflytek.sparkchain.core.tts.TTS;
import com.iflytek.sparkchain.core.tts.TTSCallbacks;
import com.aispeech.AIError;
import com.aispeech.common.AIConstant;
import com.aispeech.export.config.AICloudTTSConfig;
import com.aispeech.export.engines2.AICloudTTSEngine;
import com.aispeech.export.intent.AICloudTTSIntent;
import com.aispeech.export.listeners.AITTSListener;
import org.greenrobot.eventbus.EventBus;
import org.json.JSONArray;
import qianmu.container.app.Constant;
import qianmu.container.entity.MessageEvent;
@ -22,158 +20,99 @@ import qianmu.container.entity.MessageEvent;
public class TTSUtil {
private static String TAG = "TTS: ";
// 语音合成对象
private OnlineTTS mOnlineTTS;
private int sampleRate = 16000;
TTSCallbacks mTTSCallback = new TTSCallbacks() {
@Override
public void onResult(TTS.TTSResult result, Object o) {
//解析获取的交互结果,示例展示所有结果获取,开发者可根据自身需要,选择获取。
byte[] audio = result.getData();//音频数据
int status = result.getStatus();//数据状态
Bundle bundle = new Bundle();
bundle.putByteArray("audio", audio);
Message msg = mAudioPlayHandler.obtainMessage();
msg.what = AUDIOPLAYER_WRITE;
msg.obj = bundle;
mAudioPlayHandler.sendMessage(msg);
if(status == 2){
//音频合成回调结束状态,注意,此状态不是播报完成状态
mAudioPlayHandler.sendEmptyMessage(AUDIOPLAYER_END);
}
}
private AICloudTTSEngine mEngine;
private AICloudTTSIntent intent;
@Override
public void onError(TTS.TTSError ttsError, Object o) {
int errCode = ttsError.getCode();//错误码
String errMsg = ttsError.getErrMsg();//错误信息
LoggerUtil.d(TAG, "onError:errCode:" + errCode+ ",errMsg:" + errMsg);
//如果此时已经播报,则停止播报
EventBus.getDefault().post(new MessageEvent(Constant.VOID_STOP));
stopTTs();
}
};
public void initTts(){
mAudioPlayThread.start();
// 初始化合成对象 发音人
mOnlineTTS = new OnlineTTS("xiaoyan"); //xiaoyan
mEngine = AICloudTTSEngine.createInstance();
AICloudTTSConfig config = new AICloudTTSConfig();
config.setUseCache(false);
mEngine.init(config, new AITTSListener() {
@Override
public void onInit(int status) {
Log.d(TAG, "onInit()");
if (status == AIConstant.OPT_SUCCESS) {
Log.i(TAG, "初始化成功!");
} else {
Log.i(TAG, "初始化失败!");
}
}
@Override
public void onError(String utteranceId, AIError error) {
Log.e(TAG, "onError: " + utteranceId + "," + error.toString());
EventBus.getDefault().post(new MessageEvent(Constant.VOID_STOP));
}
@Override
public void onReady(String utteranceId) {
Log.e(TAG, "onReady: " + utteranceId);
}
@Override
public void onCompletion(String utteranceId) {
LoggerUtil.e(TAG, "onCompletion: " + utteranceId);
EventBus.getDefault().post(new MessageEvent(Constant.VOID_STOP));
}
@Override
public void onProgress(int currentTime, int totalTime, boolean isRefTextTTSFinished) {
}
@Override
public void onSynthesizeStart(String utteranceId) {
}
@Override
public void onSynthesizeDataArrived(String utteranceId, byte[] audioData) {
}
@Override
public void onSynthesizeFinish(String utteranceId) {
}
@Override
public void onTimestampReceived(byte[] bytes, int i) {
}
@Override
public void onPhonemesDataArrived(String s, String s1) {
}
@Override
public void onHighInfoReceived(JSONArray textArray, int curIndex, int curDuration, int curStart) {
Log.d("onHighInfoReceived", "textArray = " + textArray + ", curText="+textArray.optString(curIndex)+",duration = " + curDuration + ", curStart = " + curStart);
}
});
intent = new AICloudTTSIntent();
intent.setSpeaker("qianranfv5");
intent.setVolume("100");
intent.setSpeed("0.8");
intent.setTextType("text");
intent.setSpeakingStyle("happy");
intent.setHighLightInfo(false);
}
//开始听写
public void startTTs(String texts){
if (null == mOnlineTTS) {
if (null == mEngine) {
LoggerUtil.d(TAG, "未初始化");
initTts();
}
if(audioTrack == null){
mAudioPlayHandler.sendEmptyMessage(AUDIOPLAYER_INIT);
}else{
mAudioPlayHandler.sendEmptyMessage(AUDIOPLAYER_START);
}
setParam();
// 合成并播放
int ret = mOnlineTTS.aRun(texts);
if(ret!=0){
LoggerUtil.d(TAG, "语音合成失败" );
}
LoggerUtil.e(TAG, texts);
mEngine.speak(intent, texts, "1024");
}
//停止听写
public void stopTTs(){
LoggerUtil.d(TAG, "手动暂停播放");
if (null == mOnlineTTS) {
LoggerUtil.d(TAG, "未初始化");
return;
}
mAudioPlayHandler.removeCallbacksAndMessages(null);
mAudioPlayHandler.sendEmptyMessage(AUDIOPLAYER_END);
mOnlineTTS.stop();
mEngine.stop();
}
/**
* 参数设置
*
* @return
*/
private void setParam() {
mOnlineTTS.aue("raw");
mOnlineTTS.auf("audio/L16;rate="+sampleRate); // 8K 或 16K
mOnlineTTS.speed(60);//语速:0对应默认语速的1/2,100对应默认语速的2倍。最⼩值:0, 最⼤值:100
mOnlineTTS.pitch(50);//语调:0对应默认语速的1/2,100对应默认语速的2倍。最⼩值:0, 最⼤值:100
mOnlineTTS.volume(80);//音量:0是静音,1对应默认音量1/2,100对应默认音量的2倍。最⼩值:0, 最⼤值:100
mOnlineTTS.bgs(0); //合成音频的背景音 0:无背景音(默认值) 1:有背景音
mOnlineTTS.tte("UTF8");
mOnlineTTS.registerCallbacks(mTTSCallback);
}
/**
* 播放器用于播报合成的音频
* 注意当前Demo中的播放器仅实现了播放PCM格式的音频如果客户合成的是其他格式的音频需自行实现播放功能
*/
private static final int AUDIOPLAYER_INIT = 0x0000;
private static final int AUDIOPLAYER_START = 0x0001;
private static final int AUDIOPLAYER_WRITE = 0x0002;
private static final int AUDIOPLAYER_END = 0x0003;
private static final int CHANNEL_CONFIG = AudioFormat.CHANNEL_OUT_MONO; // 单声道输出
private static final int AUDIO_FORMAT = AudioFormat.ENCODING_PCM_16BIT; // PCM 16位编码
private AudioTrack audioTrack;
private Handler mAudioPlayHandler;
private boolean isPlaying = false;
int count = 0;
private Thread mAudioPlayThread = new Thread(new Runnable() {
@Override
public void run() {
Looper.prepare();
mAudioPlayHandler = new Handler(Looper.myLooper()){
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
switch(msg.what){
case AUDIOPLAYER_INIT:
Log.d(TAG,"audioInit");
int minBufferSize = AudioTrack.getMinBufferSize(sampleRate, CHANNEL_CONFIG, AUDIO_FORMAT);
audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate, CHANNEL_CONFIG, AUDIO_FORMAT, minBufferSize, AudioTrack.MODE_STREAM);
mAudioPlayHandler.sendEmptyMessage(AUDIOPLAYER_START);
break;
case AUDIOPLAYER_START:
Log.d(TAG,"audioStart");
if(audioTrack!=null) {
isPlaying = true;
audioTrack.play();
}
break;
case AUDIOPLAYER_WRITE:
count ++;
if(count%5 == 0){
Log.d(TAG,"audioWrite");
count = 0;
}
Bundle bundle = (Bundle) msg.obj;
byte[] audioData = bundle.getByteArray("audio");
if(audioTrack!=null&&audioData.length>0){
audioTrack.write(audioData,0,audioData.length);
}
break;
case AUDIOPLAYER_END:
Log.d(TAG,"audioEnd");
EventBus.getDefault().post(new MessageEvent(Constant.VOID_STOP));
if(audioTrack!=null) {
audioTrack.stop();
audioTrack.release();
audioTrack = null;
isPlaying = false;
}
break;
}
}
};
Looper.loop();
}
});
}

Loading…
Cancel
Save