瀏覽代碼

增加熟人介绍生人,讯飞语音转写

tags/A.1.0.4.0_20230804_release^2^2
tangmingjie 2 年之前
父節點
當前提交
f272439b6e
共有 29 個檔案被更改,包括 1300 行新增663 行删除
  1. 二進制
      app/libs/Msc.jar
  2. 二進制
      app/libs/arm64-v8a/libmsc.so
  3. 二進制
      app/libs/armeabi-v7a/libmsc.so
  4. 二進制
      app/libs/commons-codec-1.9.jar
  5. +52
    -31
      app/src/main/java/com/aispeech/nativedemo/DDSService.java
  6. +4
    -1
      app/src/main/java/com/aispeech/nativedemo/DuiApplication.java
  7. +10
    -32
      app/src/main/java/com/aispeech/nativedemo/MainActivity.java
  8. +7
    -3
      app/src/main/java/com/aispeech/nativedemo/asr/observer/DuiMessageObserver.java
  9. +1
    -1
      app/src/main/java/com/aispeech/nativedemo/config/Config.java
  10. +5
    -0
      app/src/main/java/com/aispeech/nativedemo/config/ConfigManager.java
  11. +68
    -0
      app/src/main/java/com/aispeech/nativedemo/entity/Broadcast.java
  12. +28
    -0
      app/src/main/java/com/aispeech/nativedemo/entity/Resource.java
  13. +1
    -0
      app/src/main/java/com/aispeech/nativedemo/entity/Setting.java
  14. +107
    -14
      app/src/main/java/com/aispeech/nativedemo/face/FaceChatMode.java
  15. +256
    -0
      app/src/main/java/com/aispeech/nativedemo/iat/IatManager.java
  16. +173
    -0
      app/src/main/java/com/aispeech/nativedemo/iat/JsonParser.java
  17. +486
    -0
      app/src/main/java/com/aispeech/nativedemo/iat/WebIATWS.java
  18. +32
    -23
      app/src/main/java/com/aispeech/nativedemo/log/LogFile.java
  19. +2
    -0
      app/src/main/java/com/aispeech/nativedemo/log/LoggerPrinter.java
  20. +2
    -2
      app/src/main/java/com/aispeech/nativedemo/mqtt/Mqtt.java
  21. +3
    -2
      app/src/main/java/com/aispeech/nativedemo/mqtt/MqttConfig.java
  22. +6
    -3
      app/src/main/java/com/aispeech/nativedemo/network/ws/DigiWebSocketServer.java
  23. +55
    -6
      app/src/main/java/com/aispeech/nativedemo/network/ws/MessageUtils.java
  24. +0
    -31
      app/src/main/java/com/aispeech/nativedemo/rtasr/DraftWithOrigin.java
  25. +0
    -66
      app/src/main/java/com/aispeech/nativedemo/rtasr/EncryptUtil.java
  26. +0
    -228
      app/src/main/java/com/aispeech/nativedemo/rtasr/RTASRManager.java
  27. +0
    -219
      app/src/main/java/com/aispeech/nativedemo/rtasr/RTASRTest.java
  28. +2
    -1
      app/src/main/java/com/aispeech/nativedemo/shape/ShapeManager.java
  29. 二進制
      test/libs/lib-dds-2.9.2.1-release.aar

二進制
app/libs/Msc.jar 查看文件


二進制
app/libs/arm64-v8a/libmsc.so 查看文件


二進制
app/libs/armeabi-v7a/libmsc.so 查看文件


二進制
app/libs/commons-codec-1.9.jar 查看文件


+ 52
- 31
app/src/main/java/com/aispeech/nativedemo/DDSService.java 查看文件

@@ -14,7 +14,6 @@ import android.os.IBinder;
import android.os.Looper;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Base64;
import android.util.Log;
import android.widget.Toast;

@@ -22,22 +21,21 @@ import com.aispeech.dui.dds.DDS;
import com.aispeech.dui.dds.DDSAuthListener;
import com.aispeech.dui.dds.DDSConfig;
import com.aispeech.dui.dds.DDSInitListener;
import com.aispeech.dui.dds.DDSMode;
import com.aispeech.dui.dds.agent.AsrListener;
import com.aispeech.dui.dds.agent.tts.TTSEngine;
import com.aispeech.dui.dds.exceptions.DDSNotInitCompleteException;
import com.aispeech.nativedemo.face.FaceManager;
import com.aispeech.nativedemo.iat.IatManager;
import com.aispeech.nativedemo.log.Logger;
import com.aispeech.nativedemo.mqtt.MqttManager;
import com.aispeech.nativedemo.network.ws.WebSocketManager;
import com.aispeech.nativedemo.ui.LauncherActivity;
import com.aispeech.nativedemo.config.Config;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;

/**
@@ -137,8 +135,6 @@ public class DDSService extends Service {
Logger.e("思必驰++++++++++++++++++++");
}
// DDS.getInstance().setAudioDebug(true);

// startTtsListening();
}

@Override
@@ -338,31 +334,56 @@ public class DDSService extends Service {

private long mTime = 0;
private long mAsrTime = 0;
private String mFileName = "";

public void startAsrListening() {
// DDS.getInstance().getAgent().getASREngine().setAsrListener(new AsrListener() {
// @Override
// public void onAsr(byte[] bytes) {
// if(mTime == 0){
// mTime = System.currentTimeMillis();
// mAsrTime = System.currentTimeMillis();
// }
// if(System.currentTimeMillis() - mAsrTime > 3000){
// mTime = System.currentTimeMillis();
// }
// mAsrTime = System.currentTimeMillis();
// File file = createFile("asr-" + mTime + ".pcm");
// RandomAccessFile raf = null;
// try {
// raf = new RandomAccessFile(file, "rw");
// raf.seek(file.length());
// raf.write(bytes);
// raf.close();
// } catch (IOException e) {
// throw new RuntimeException(e);
// }
// }
// });
DDS.getInstance().getAgent().getASREngine().setAsrListener(new AsrListener() {
@Override
public void onAsr(byte[] bytes) {
startTimer();
if(mTime == 0){
mTime = System.currentTimeMillis();
mAsrTime = System.currentTimeMillis();
}
if(System.currentTimeMillis() - mAsrTime > 1000){
mTime = System.currentTimeMillis();
}
mAsrTime = System.currentTimeMillis();
File file = createFile("asr-" + mTime + ".pcm");
RandomAccessFile raf = null;
try {
raf = new RandomAccessFile(file, "rw");
raf.seek(file.length());
raf.write(bytes);
raf.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
});
}

private Timer mTimer;
public void startTimer(){
if(mTimer != null){
mTimer.cancel();
mTimer = null;
}
mTimer = new Timer();
mTimer.schedule(new TimerTask() {
@Override
public void run() {
String dirPath = Environment.getExternalStorageDirectory().getAbsolutePath()
+"/Android/data/com.aispeech.nativedemo/files/asrCache/" + "asr-" + mTime + ".pcm";
if(!dirPath.equals(mFileName)){
File file = new File(dirPath);
if(file.exists()){
IatManager.getInstance().executeStream(dirPath);
}
mFileName = dirPath;
}
}
}, 1000);
}

public File createFile(String name) {


+ 4
- 1
app/src/main/java/com/aispeech/nativedemo/DuiApplication.java 查看文件

@@ -7,12 +7,13 @@ import android.util.Log;
import com.aispeech.dui.dds.DDS;
import com.aispeech.dui.dds.DDSErrorListener;
import com.aispeech.nativedemo.config.Config;
import com.aispeech.nativedemo.face.FaceManager;
import com.aispeech.nativedemo.iat.IatManager;
import com.aispeech.nativedemo.log.Logger;
import com.aispeech.nativedemo.network.DigiNetworkManager;
import com.aispeech.nativedemo.utils.CrashHandler;
import com.aispeech.nativedemo.utils.ResourceUtils;
import com.facebook.drawee.backends.pipeline.Fresco;
import com.iflytek.cloud.SpeechUtility;

import org.json.JSONObject;

@@ -30,11 +31,13 @@ public class DuiApplication extends Application {
mContext = this;
Logger.init();
CrashHandler.getInstance().init(this);
SpeechUtility.createUtility(this, "appid=e14469ab");
Fresco.initialize(this);
// Thread.setDefaultUncaughtExceptionHandler(uncaughtExceptionHandler);
// FaceManager.getInstance(this).initEngine();
DigiNetworkManager.getManager().init(this);
copyDbAndConfig();
IatManager.getInstance();
}

public static Context getContext() {


+ 10
- 32
app/src/main/java/com/aispeech/nativedemo/MainActivity.java 查看文件

@@ -1,11 +1,8 @@
package com.aispeech.nativedemo;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.core.app.ActivityCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.Manifest;
import android.app.Activity;
@@ -16,7 +13,6 @@ import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.ImageFormat;
import android.graphics.PixelFormat;
import android.graphics.SurfaceTexture;
import android.graphics.drawable.Drawable;
@@ -27,28 +23,21 @@ import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CameraMetadata;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.TotalCaptureResult;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.media.Image;
import android.media.ImageReader;
import android.net.ConnectivityManager;
import android.net.NetworkCapabilities;
import android.net.NetworkRequest;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.RemoteException;
import android.os.SystemClock;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Size;
import android.util.SparseIntArray;
import android.view.LayoutInflater;
import android.view.Surface;
import android.view.TextureView;
import android.view.View;
@@ -57,23 +46,16 @@ import android.view.WindowManager;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.aispeech.dui.dds.DDS;
import com.aispeech.dui.dds.DDSErrorListener;
import com.aispeech.dui.dds.agent.wakeup.word.WakeupWord;
import com.aispeech.dui.dds.exceptions.DDSNotInitCompleteException;
import com.aispeech.nativedemo.asr.observer.DuiMessageObserver;
import com.aispeech.nativedemo.camera.CameraController;
import com.aispeech.nativedemo.config.Config;
import com.aispeech.nativedemo.db.DatabaseImpl;
import com.aispeech.nativedemo.db.DbHelper;
import com.aispeech.nativedemo.db.EmpDbHelper;
import com.aispeech.nativedemo.db.InitializeDbHelper;
import com.aispeech.nativedemo.db.ModelDbHelper;
import com.aispeech.nativedemo.db.SkillDbHelper;
import com.aispeech.nativedemo.db.StrangerDbHelper;
import com.aispeech.nativedemo.dds.DDSManager;
@@ -84,6 +66,7 @@ import com.aispeech.nativedemo.face.FaceChatMode;
import com.aispeech.nativedemo.face.FaceManager;
import com.aispeech.nativedemo.face.FaceReceptionMode;
import com.aispeech.nativedemo.face.IdentityMode;
import com.aispeech.nativedemo.iat.IatManager;
import com.aispeech.nativedemo.log.Logger;
import com.aispeech.nativedemo.mqtt.MqttManager;
import com.aispeech.nativedemo.network.NetworkStatusCallback;
@@ -93,14 +76,9 @@ import com.aispeech.nativedemo.observer.DuiCommandObserver;
import com.aispeech.nativedemo.observer.DuiNativeApiObserver;
import com.aispeech.nativedemo.observer.DuiUpdateObserver;
import com.aispeech.nativedemo.rockchip.HdmiService;
import com.aispeech.nativedemo.rockchip.RockchipCamera2;
import com.aispeech.nativedemo.rockchip.util.DataUtils;
import com.aispeech.nativedemo.update.callback.DownloadListener;
import com.aispeech.nativedemo.update.core.DownloadManager;
import com.aispeech.nativedemo.update.utils.AppUtils;
import com.aispeech.nativedemo.upload.UploadManager;
import com.aispeech.nativedemo.utils.CommandExecution;
import com.aispeech.nativedemo.utils.ConfigClass;
import com.aispeech.nativedemo.utils.PermissionUtil;
import com.aispeech.nativedemo.utils.Utils;
import com.aispeech.nativedemo.utils.suspension.SuspensionHelper;
@@ -115,18 +93,11 @@ import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import rockchip.hardware.hdmi.V1_0.IHdmi;
import rockchip.hardware.hdmi.V1_0.IHdmiCallback;
@@ -254,8 +225,15 @@ public class MainActivity extends Activity implements DuiUpdateObserver.UpdateCa
// startHdmi();
// initSpeech();

File file = new File(getExternalFilesDir(null).getAbsolutePath() + "/update/" + getPackageName() + ".apk");
AppUtils.installApk(MainActivity.this, file);
// File file = new File(getExternalFilesDir(null).getAbsolutePath() + "/update/" + getPackageName() + ".apk");
// AppUtils.installApk(MainActivity.this, file);

String dirPath = Environment.getExternalStorageDirectory().getAbsolutePath()
+"/Android/data/com.aispeech.nativedemo/files/asrCache/" + "16k_10.pcm";
File file = new File(dirPath);
if(file.exists()){
IatManager.getInstance().executeStream(dirPath);
}
}
});
close = findViewById(R.id.close_camera);


+ 7
- 3
app/src/main/java/com/aispeech/nativedemo/asr/observer/DuiMessageObserver.java 查看文件

@@ -6,7 +6,10 @@ import android.util.Log;
import com.aispeech.dui.dds.DDS;
import com.aispeech.dui.dds.agent.DMTaskCallback;
import com.aispeech.dui.dds.agent.MessageObserver;
import com.aispeech.nativedemo.MainActivity;
import com.aispeech.nativedemo.config.Config;
import com.aispeech.nativedemo.log.Logger;
import com.aispeech.nativedemo.mqtt.MqttManager;
import com.aispeech.nativedemo.network.ws.MessageUtils;
import com.aispeech.nativedemo.widget.pageview.utils.JSONUtils;
import com.google.gson.Gson;
@@ -65,12 +68,13 @@ public class DuiMessageObserver implements MessageObserver {
if(type == Type.DM_OUTPUT){
String display = jsonObject.optString("display");
String nlg = jsonObject.optString("nlg");
String dmInput = jsonObject.optString("dmInput");
Log.e(Tag, display);
Log.e(Tag, nlg);
String readText = nlg;
// if(FaceManager.getInstance(DuiApplication.getContext()).hasPerson()) {
if (JSONUtils.isJson(display)) {
readText = MessageUtils.sendSkill(display);
readText = MessageUtils.sendSkill(display, dmInput);
try {
jsonObject.put("nlg", "");
jsonObject.put("display", "");
@@ -188,9 +192,9 @@ public class DuiMessageObserver implements MessageObserver {
String error = dataObj.optString("error");
JSONObject errorObj = new JSONObject(error);
String errId = errorObj.optString("errId");
if(!errId.equals("071304") && !errId.equals("071305") && !errId.equals("071310") && !errId.equals("071317") && !errId.equals("071318")){
if(!errId.equals("071304") && !errId.equals("071305") && !errId.equals("071309") && !errId.equals("071310") && !errId.equals("071317") && !errId.equals("071318")){
Logger.e("对话错误: " + data);
// MqttManager.getInstance(MainActivity.instance).getFileUploadPath(Config.ErrorEvent.ERROR_UPLOAD_WARNING, Config.ErrorEvent.ERROR_LEVEL_2, "speech_sdk_err_code", Tag);
MqttManager.getInstance(MainActivity.instance).getFileUploadPath(Config.ErrorEvent.ERROR_UPLOAD_WARNING, Config.ErrorEvent.ERROR_LEVEL_2, "speech_sdk_err_code", Tag);
}
} catch (JSONException e) {
throw new RuntimeException(e);


+ 1
- 1
app/src/main/java/com/aispeech/nativedemo/config/Config.java 查看文件

@@ -9,7 +9,7 @@ public class Config {
public static final String PROD_BASE_URL= "http://123.57.75.177:8080/";
public static final String TEST_BASE_URL= "http://39.107.77.235:8080/";
public static final String DEV_BASE_URL= "http://192.168.10.244:8080/";
public static final String CURRENT_URL= PROD_BASE_URL;
public static final String CURRENT_URL= DEV_BASE_URL;

public static final long ONE_SECOND = 1000L;
public static final long ONE_MINUTE = 60 * ONE_SECOND;


+ 5
- 0
app/src/main/java/com/aispeech/nativedemo/config/ConfigManager.java 查看文件

@@ -12,6 +12,7 @@ import com.aispeech.nativedemo.db.ModelDbHelper;
import com.aispeech.nativedemo.db.ReceptionDbHelper;
import com.aispeech.nativedemo.db.SkillDbHelper;
import com.aispeech.nativedemo.entity.Background;
import com.aispeech.nativedemo.entity.Broadcast;
import com.aispeech.nativedemo.entity.Emp;
import com.aispeech.nativedemo.entity.Icon;
import com.aispeech.nativedemo.entity.Model;
@@ -340,6 +341,10 @@ public class ConfigManager {
if(jsonObject.has("workdayHour")){
model.workdayHour = new WorkDayHour().create(jsonObject.optJSONObject("workdayHour"));
}
if(jsonObject.has("broadcast")){
Broadcast broadcast = new Broadcast().create(jsonObject.optJSONObject("broadcast"));
MessageUtils.sendBroadcast(broadcast.toString());
}
ModelDbHelper.getInstance().add(model);
if (obj.has("timestamp")) {
mUserTimeStamp = obj.optLong("timestamp");


+ 68
- 0
app/src/main/java/com/aispeech/nativedemo/entity/Broadcast.java 查看文件

@@ -0,0 +1,68 @@
package com.aispeech.nativedemo.entity;

import androidx.annotation.NonNull;

import com.aispeech.nativedemo.db.SkillDbHelper;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

public class Broadcast implements Serializable {
public int recycle;
public int speed;
public List<Resource> resource;

public Broadcast(){
resource = new ArrayList<>();
}

public Broadcast create(JSONObject object){
this.recycle = object.optInt("recycle");
this.speed = object.optInt("speed");
if (object.has("resource")) {
try {
JSONArray array = object.getJSONArray("resource");
for (int i = 0; i < array.length(); i++) {
JSONObject jsonObject = array.getJSONObject(i);
Resource res = new Resource();
res.order = jsonObject.optInt("order");
res.ttsText = jsonObject.optString("ttsText");
res.url = jsonObject.optString("url");
resource.add(res);
}
} catch (JSONException e) {
throw new RuntimeException(e);
}
}
return this;
}

@NonNull
@Override
public String toString() {
JSONObject obj;
try {
obj = new JSONObject();
obj.put("recycle", recycle);
obj.put("speed", speed);
JSONArray array = new JSONArray();
for (int i = 0; i < resource.size(); i++) {
JSONObject jsonObject = new JSONObject();
Resource res = resource.get(i);
jsonObject.put("order", res.order);
jsonObject.put("ttsText", res.ttsText);
jsonObject.put("url", res.url);
array.put(jsonObject);
}
obj.put("resource", array);
} catch (JSONException e) {
throw new RuntimeException(e);
}
return obj.toString();
}
}

+ 28
- 0
app/src/main/java/com/aispeech/nativedemo/entity/Resource.java 查看文件

@@ -0,0 +1,28 @@
package com.aispeech.nativedemo.entity;

import androidx.annotation.NonNull;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.Serializable;

public class Resource implements Serializable {
public int order;
public String ttsText; //名字
public String url; //成为

@NonNull
@Override
public String toString() {
JSONObject object = new JSONObject();
try {
object.put("order", order);
object.put("ttsText", ttsText);
object.put("url", url);
} catch (JSONException e) {
throw new RuntimeException(e);
}
return object.toString();
}
}

+ 1
- 0
app/src/main/java/com/aispeech/nativedemo/entity/Setting.java 查看文件

@@ -6,4 +6,5 @@ public class Setting implements Serializable {
public int id;
public int isReceptionMode; //接待模式 1.是 0.否
public long hbUpdateTime; //心跳更新时间戳
public long ttsTotalTime; //tts总时长
}

+ 107
- 14
app/src/main/java/com/aispeech/nativedemo/face/FaceChatMode.java 查看文件

@@ -400,6 +400,9 @@ public class FaceChatMode {
return persons.get(maxFaceId.get());
}

private static String lastUserID;
private static long nextLogTime;

private static void sendMsgAndLog(Bitmap textureBitmap){
if(mSelectPerson == null){
return;
@@ -410,19 +413,19 @@ public class FaceChatMode {
/**
* 发送日志
*/
// String sendId = mSelectPerson.id;
// boolean isStranger = sendId.equals("-1") || sendId.equals("-2");
// if (!sendId.equals(lastUserID)) {
// lastUserID = sendId;
// nextLogTime = System.currentTimeMillis();
// sendLog(isStranger, sendId, mSelectPerson.tag, (mSelectPerson.score), BmpCompressUtils.getBytesByBitmap(Utils.CompressBmp(textureBitmap, mSelectPerson.result), 50, Bitmap.CompressFormat.JPEG));
// } else {
// if (System.currentTimeMillis() - nextLogTime > 60000) {
// lastUserID = sendId;
// nextLogTime = System.currentTimeMillis();
// sendLog(isStranger, sendId, mSelectPerson.tag, (mSelectPerson.score), BmpCompressUtils.getBytesByBitmap(Utils.CompressBmp(textureBitmap, mSelectPerson.result), 50, Bitmap.CompressFormat.JPEG));
// }
// }
String sendId = mSelectPerson.id;
boolean isStranger = sendId.equals("-1") || sendId.equals("-2");
if (!sendId.equals(lastUserID)) {
lastUserID = sendId;
nextLogTime = System.currentTimeMillis();
sendLog(isStranger, sendId, mSelectPerson.tag, (mSelectPerson.score), BmpCompressUtils.getBytesByBitmap(Utils.CompressBmp(textureBitmap, mSelectPerson.result), 50, Bitmap.CompressFormat.JPEG));
} else {
if (System.currentTimeMillis() - nextLogTime > 60000) {
lastUserID = sendId;
nextLogTime = System.currentTimeMillis();
sendLog(isStranger, sendId, mSelectPerson.tag, (mSelectPerson.score), BmpCompressUtils.getBytesByBitmap(Utils.CompressBmp(textureBitmap, mSelectPerson.result), 50, Bitmap.CompressFormat.JPEG));
}
}
sendStrangerToServer();

}
@@ -620,7 +623,7 @@ public class FaceChatMode {
return false;
}

private void sendLog(boolean isStranger, String userId, String type, float confidence, byte[] bitmapBytes) {
private static void sendLog(boolean isStranger, String userId, String type, float confidence, byte[] bitmapBytes) {
String base64 = Base64.encodeToString(bitmapBytes, Base64.DEFAULT);

HashMap<String, String> postParam = new HashMap<>();
@@ -777,4 +780,94 @@ public class FaceChatMode {
StrangerDbHelper.getInstance().add(stranger);
return stranger;
}

public static void introduceNewPartner(String dmInput){
Stream<PersonInfo> pInfos = mUndeterminedPersons.values().stream().filter(item-> item.result.hd_fa > 0 && item.result.fa_quality > 0.6f);
if(pInfos.findAny().isPresent()){
MessageUtils.sendAsrText("陌生人人脸质量合格");
pInfos = mUndeterminedPersons.values().stream().filter(item-> item.result.hd_fa > 0 && item.result.fa_quality > 0.6f);
PersonInfo info = pInfos.findFirst().get();
// if(mPersons.size() > 1){
if(mSelectPerson != null){
String name = "";
String type = "";
if(dmInput.contains("贵宾")){
name = "贵宾";
type = "9";
} else if(dmInput.contains("同事")){
name = "同事";
type = "5";
} else if(dmInput.contains("访客")){
name = "访客";
type = "6";
} else if(dmInput.contains("高管")){
name = "高管";
type = "4";
} else{
MessageUtils.sendAsrText("介绍" + name);
}
if(!TextUtils.isEmpty(name)){
MessageUtils.sendAsrText("开始创建" + name);
byte[] bitmapBytes = BmpCompressUtils.getBytesByBitmap(Utils.CompressBmp(info.bitmap, info.result), 100, Bitmap.CompressFormat.JPEG);
String base64 = Base64.encodeToString(bitmapBytes, Base64.DEFAULT);
base64 = base64.replace("\n", "").replace("\\", "") + "";
newVisitor(mSelectPerson.name, name, type, info.gender, base64);
}
} else{
MessageUtils.sendAsrText("当前操作人不是熟人");
}
// } else{
// MessageUtils.sendAsrText("没有熟人");
// }
} else{
MessageUtils.sendAsrText("陌生人脸部质量不合格");
}
}

public static void newVisitor(String acquaintance, String name, String type, int gender, String base64){
HashMap<String, Object> postParam = new HashMap<>();
postParam.put("staffName", name);
postParam.put("staffType", type);
postParam.put("gender", gender);
postParam.put("devId", Build.SERIAL);
postParam.put("staffBase64Img", base64);
MessageUtils.sendAsrText("调用接口");
RequestBody requestBody = RequestBody.create(MediaType.parse("application/json"), new JSONObject(postParam).toString());
HttpUtil.post(Config.DEV_BASE_URL + "system/staff/api/new-staff", requestBody, null, new HttpUtil.HttpCallback<String>() {
@Override
public void onSuccess(String success) {
try {
JSONTokener t = new JSONTokener(success);
JSONObject obj = (JSONObject) t.nextValue();
int status = -1001001;
String errMsg = "";
if (obj.has("status")) {
status = obj.getInt("status");
}
if (obj.has("errMsg")) {
errMsg = obj.getString("errMsg");
}
String message = "";
if (status == 0) {
message = acquaintance + "介绍" + name + "成功";
} else {
message = acquaintance + "介绍" + name + "失败:" + errMsg;
onFail(errMsg);
}
Logger.e(message);
MessageUtils.sendAsrText(message);
} catch (Exception e) {
MessageUtils.sendAsrText(e.getMessage());
e.printStackTrace();
onFail(e.getMessage());
}
}

@Override
public void onFail(String error) {
Log.e(TAG, "sendStrangerToServer onFail: " + error);
MessageUtils.sendAsrText(error);
}
});
}
}

+ 256
- 0
app/src/main/java/com/aispeech/nativedemo/iat/IatManager.java 查看文件

@@ -0,0 +1,256 @@
package com.aispeech.nativedemo.iat;

import android.content.Context;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;

import com.aispeech.nativedemo.DuiApplication;
import com.aispeech.nativedemo.log.Logger;
import com.aispeech.nativedemo.network.ws.MessageUtils;
import com.iflytek.cloud.ErrorCode;
import com.iflytek.cloud.InitListener;
import com.iflytek.cloud.RecognizerListener;
import com.iflytek.cloud.RecognizerResult;
import com.iflytek.cloud.SpeechConstant;
import com.iflytek.cloud.SpeechError;
import com.iflytek.cloud.SpeechRecognizer;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.Base64;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Locale;
import java.util.TimeZone;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import okhttp3.Request;

public class IatManager {
private static String TAG = IatManager.class.getSimpleName();
private static IatManager mInstance;
private Context mContext;
private SpeechRecognizer mIat;
private StringBuffer buffer = new StringBuffer();
private HashMap<String, String> mIatResults = new LinkedHashMap<>();
private String resultType = "json";
private String language = "zh_cn";
private String mEngineType = SpeechConstant.TYPE_CLOUD;
private IatManager(Context context) {
mContext = context;
initIat();
}

public static IatManager getInstance() {
if (mInstance == null) {
synchronized (IatManager.class) {
if (mInstance == null) {
mInstance = new IatManager(DuiApplication.getContext());
}
}
}
return mInstance;
}

private void initIat(){
mIat = SpeechRecognizer.createRecognizer(mContext, mInitListener);
}

private InitListener mInitListener = new InitListener() {

@Override
public void onInit(int code) {
Log.d(TAG, "SpeechRecognizer init() code = " + code);
if (code != ErrorCode.SUCCESS) {
Logger.e("djTtsTime-" + "初始化失败,错误码:" + code + ",请点击网址https://www.xfyun.cn/document/error-code查询解决方案");
}
}
};

/**
* 参数设置
*
* @return
*/
public void setParam() {
// 清空参数
mIat.setParameter(SpeechConstant.PARAMS, null);
// 开启动态修正
mIat.setParameter("dwa", "wpgs");
// 设置听写引擎
mIat.setParameter(SpeechConstant.ENGINE_TYPE, mEngineType);
// 设置返回结果格式
mIat.setParameter(SpeechConstant.RESULT_TYPE, resultType);

if (language.equals("zh_cn")) {
// 设置语言
// Logger.e("djTtsTime-" + "language = " + language);
mIat.setParameter(SpeechConstant.LANGUAGE, "zh_cn");
// 设置语言区域
mIat.setParameter(SpeechConstant.ACCENT, "mandarin");
} else {
mIat.setParameter(SpeechConstant.LANGUAGE, language);
}
// Logger.e("djTtsTime-" + "last language:" + mIat.getParameter(SpeechConstant.LANGUAGE));

//此处用于设置dialog中不显示错误码信息
//mIat.setParameter("view_tips_plain","false");

// 设置语音前端点:静音超时时间,即用户多长时间不说话则当做超时处理
mIat.setParameter(SpeechConstant.VAD_BOS, "4000");

// 设置语音后端点:后端点静音检测时间,即用户停止说话多长时间内即认为不再输入, 自动停止录音
mIat.setParameter(SpeechConstant.VAD_EOS, "1000");

// 设置标点符号,设置为"0"返回结果无标点,设置为"1"返回结果有标点
mIat.setParameter(SpeechConstant.ASR_PTT, "1");

// 设置音频保存路径,保存音频格式支持pcm、wav.
// mIat.setParameter(SpeechConstant.AUDIO_FORMAT, "wav");
// mIat.setParameter(SpeechConstant.ASR_AUDIO_PATH, mContext.getExternalFilesDir("msc").getAbsolutePath() + "/iat.wav");
}

int ret = 0; // 函数调用返回值

public void executeStream(String filePath) {
buffer.setLength(0);
mIatResults.clear();
// 设置参数
setParam();
// 设置音频来源为外部文件
mIat.setParameter(SpeechConstant.AUDIO_SOURCE, "-1");
// 也可以像以下这样直接设置音频文件路径识别(要求设置文件在sdcard上的全路径):
// mIat.setParameter(SpeechConstant.AUDIO_SOURCE, "-2");
// mIat.setParameter(SpeechConstant.ASR_SOURCE_PATH, "sdcard/XXX/XXX.pcm");
ret = mIat.startListening(mRecognizerListener);
if (ret != ErrorCode.SUCCESS) {
Logger.e("djTtsTime-" + "识别失败,错误码:" + ret + ",请点击网址https://www.xfyun.cn/document/error-code查询解决方案");
return;
}
try (FileInputStream open = new FileInputStream(filePath)) {
// InputStream open = getAssets().open("iattest.wav");
byte[] buff = new byte[1280];
while (open.available() > 0) {
int read = open.read(buff);
mIat.writeAudio(buff, 0, read);
}
mIat.stopListening();
} catch (IOException e) {
mIat.cancel();
Logger.e("djTtsTime-" + "读取音频流失败");
}
}

private RecognizerListener mRecognizerListener = new RecognizerListener() {

@Override
public void onBeginOfSpeech() {
// 此回调表示:sdk内部录音机已经准备好了,用户可以开始语音输入
Logger.e("djTtsTime-" + "开始说话");
}

@Override
public void onError(SpeechError error) {
// Tips:
// 错误码:10118(您没有说话),可能是录音机权限被禁,需要提示用户打开应用的录音权限。
Logger.e("djTtsTime-" + "onError " + error.getPlainDescription(true));
}

@Override
public void onEndOfSpeech() {
// 此回调表示:检测到了语音的尾端点,已经进入识别过程,不再接受语音输入
Logger.e("djTtsTime-" + "结束说话");
}

@Override
public void onResult(RecognizerResult results, boolean isLast) {
Logger.e(results.getResultString());
if (resultType.equals("json")) {
printResult(results);
if (isLast) {
Logger.e("djTtsTime-" + "onResult 结束");
StringBuffer resultBuffer = new StringBuffer();
for (String key : mIatResults.keySet()) {
resultBuffer.append(mIatResults.get(key));
}
String res = resultBuffer.toString();
MessageUtils.sendAsrText(res);
Logger.e("djTtsTime-" + "ASR转写结果: " + res);
}
return;
}
if (resultType.equals("plain")) {
buffer.append(results.getResultString());
Logger.e("djTtsTime-" + "听写结果: " + buffer.toString());
}
}

@Override
public void onVolumeChanged(int volume, byte[] data) {
// Logger.e("djTtsTime-" + "当前正在说话,音量大小 = " + volume + " 返回音频数据 = " + data.length);
}

@Override
public void onEvent(int eventType, int arg1, int arg2, Bundle obj) {
// 以下代码用于获取与云端的会话id,当业务出错时将会话id提供给技术支持人员,可用于查询会话日志,定位出错原因
// 若使用本地能力,会话id为null
// if (SpeechEvent.EVENT_SESSION_ID == eventType) {
// String sid = obj.getString(SpeechEvent.KEY_EVENT_SESSION_ID);
// Log.d(TAG, "session id =" + sid);
// }
}
};

private void printResult(RecognizerResult results) {
// String text = JsonParser.parseIatResult(results.getResultString());
// String sn = null;
// // 读取json结果中的sn字段
// try {
// JSONObject resultJson = new JSONObject(results.getResultString());
// sn = resultJson.optString("sn");
// } catch (JSONException e) {
// e.printStackTrace();
// }
//
// mIatResults.put(sn, text);

String text = JsonParser.parseIatResult(results.getResultString());

String sn = null;
String pgs = null;
String rg = null;
// 读取json结果中的sn字段
try {
JSONObject resultJson = new JSONObject(results.getResultString());
sn = resultJson.optString("sn");
pgs = resultJson.optString("pgs");
rg = resultJson.optString("rg");
} catch (JSONException e) {
e.printStackTrace();
}
//如果pgs是rpl就在已有的结果中删除掉要覆盖的sn部分
if (pgs.equals("rpl")) {
String[] strings = rg.replace("[", "").replace("]", "").split(",");
int begin = Integer.parseInt(strings[0]);
int end = Integer.parseInt(strings[1]);
for (int i = begin; i <= end; i++) {
mIatResults.remove(i+"");
}
}

mIatResults.put(sn, text);
}
}

+ 173
- 0
app/src/main/java/com/aispeech/nativedemo/iat/JsonParser.java 查看文件

@@ -0,0 +1,173 @@
package com.aispeech.nativedemo.iat;

import org.json.JSONArray;
import org.json.JSONObject;
import org.json.JSONTokener;

/**
* Json结果解析类
*/
public class JsonParser {

public static String parseIatResult(String json) {
StringBuffer ret = new StringBuffer();
try {
JSONTokener tokener = new JSONTokener(json);
JSONObject joResult = new JSONObject(tokener);

JSONArray words = joResult.getJSONArray("ws");
for (int i = 0; i < words.length(); i++) {
// 转写结果词,默认使用第一个结果
JSONArray items = words.getJSONObject(i).getJSONArray("cw");
JSONObject obj = items.getJSONObject(0);
ret.append(obj.getString("w"));
// 如果需要多候选结果,解析数组其他字段
// for(int j = 0; j < items.length(); j++)
// {
// JSONObject obj = items.getJSONObject(j);
// ret.append(obj.getString("w"));
// }
}
} catch (Exception e) {
e.printStackTrace();
}
return ret.toString();
}

public static String parseGrammarResult(String json, String engType) {
StringBuffer ret = new StringBuffer();
try {
JSONTokener tokener = new JSONTokener(json);
JSONObject joResult = new JSONObject(tokener);

JSONArray words = joResult.getJSONArray("ws");
// 云端和本地结果分情况解析
if ("cloud".equals(engType)) {
for (int i = 0; i < words.length(); i++) {
JSONArray items = words.getJSONObject(i).getJSONArray("cw");
for (int j = 0; j < items.length(); j++) {
JSONObject obj = items.getJSONObject(j);
if (obj.getString("w").contains("nomatch")) {
ret.append("没有匹配结果.");
return ret.toString();
}
ret.append("【结果】" + obj.getString("w"));
ret.append("【置信度】" + obj.getInt("sc"));
ret.append("\n");
}
}
} else if ("local".equals(engType)) {
ret.append("【结果】");
for (int i = 0; i < words.length(); i++) {
JSONObject wsItem = words.getJSONObject(i);
JSONArray items = wsItem.getJSONArray("cw");
if ("<contact>".equals(wsItem.getString("slot"))) {
// 可能会有多个联系人供选择,用中括号括起来,这些候选项具有相同的置信度
ret.append("【");
for (int j = 0; j < items.length(); j++) {
JSONObject obj = items.getJSONObject(j);
if (obj.getString("w").contains("nomatch")) {
ret.append("没有匹配结果.");
return ret.toString();
}
ret.append(obj.getString("w")).append("|");
}
ret.setCharAt(ret.length() - 1, '】');
} else {
//本地多候选按照置信度高低排序,一般选取第一个结果即可
JSONObject obj = items.getJSONObject(0);
if (obj.getString("w").contains("nomatch")) {
ret.append("没有匹配结果.");
return ret.toString();
}
ret.append(obj.getString("w"));
}
}
ret.append("【置信度】" + joResult.getInt("sc"));
ret.append("\n");
}

} catch (Exception e) {
e.printStackTrace();
ret.append("没有匹配结果.");
}
return ret.toString();
}

public static String parseGrammarResult(String json) {
StringBuffer ret = new StringBuffer();
try {
JSONTokener tokener = new JSONTokener(json);
JSONObject joResult = new JSONObject(tokener);

JSONArray words = joResult.getJSONArray("ws");
for (int i = 0; i < words.length(); i++) {
JSONArray items = words.getJSONObject(i).getJSONArray("cw");
for (int j = 0; j < items.length(); j++) {
JSONObject obj = items.getJSONObject(j);
if (obj.getString("w").contains("nomatch")) {
ret.append("没有匹配结果.");
return ret.toString();
}
ret.append("【结果】" + obj.getString("w"));
ret.append("【置信度】" + obj.getInt("sc"));
ret.append("\n");
}
}
} catch (Exception e) {
e.printStackTrace();
ret.append("没有匹配结果.");
}
return ret.toString();
}

public static String parseLocalGrammarResult(String json) {
StringBuffer ret = new StringBuffer();
try {
JSONTokener tokener = new JSONTokener(json);
JSONObject joResult = new JSONObject(tokener);

JSONArray words = joResult.getJSONArray("ws");
for (int i = 0; i < words.length(); i++) {
JSONArray items = words.getJSONObject(i).getJSONArray("cw");
for (int j = 0; j < items.length(); j++) {
JSONObject obj = items.getJSONObject(j);
if (obj.getString("w").contains("nomatch")) {
ret.append("没有匹配结果.");
return ret.toString();
}
ret.append("【结果】" + obj.getString("w"));
ret.append("\n");
}
}
ret.append("【置信度】" + joResult.optInt("sc"));

} catch (Exception e) {
e.printStackTrace();
ret.append("没有匹配结果.");
}
return ret.toString();
}

public static String parseTransResult(String json, String key) {
StringBuffer ret = new StringBuffer();
try {
JSONTokener tokener = new JSONTokener(json);
JSONObject joResult = new JSONObject(tokener);
String errorCode = joResult.optString("ret");
if (!errorCode.equals("0")) {
return joResult.optString("errmsg");
}
JSONObject transResult = joResult.optJSONObject("trans_result");
ret.append(transResult.optString(key));
/*JSONArray words = joResult.getJSONArray("results");
for (int i = 0; i < words.length(); i++) {
JSONObject obj = words.getJSONObject(i);
ret.append(obj.getString(key));
}*/
} catch (Exception e) {
e.printStackTrace();
}
return ret.toString();
}
}

+ 486
- 0
app/src/main/java/com/aispeech/nativedemo/iat/WebIATWS.java 查看文件

@@ -0,0 +1,486 @@
package com.aispeech.nativedemo.iat;
import android.os.Handler;
import android.os.HandlerThread;

import com.aispeech.nativedemo.log.Logger;
import com.google.gson.Gson;
import com.google.gson.JsonObject;

import okhttp3.*;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
* 语音听写流式 WebAPI 接口调用示例 接口文档(必看):https://doc.xfyun.cn/rest_api/语音听写(流式版).html
* webapi 听写服务参考帖子(必看):http://bbs.xfyun.cn/forum.php?mod=viewthread&tid=38947&extra=
* 语音听写流式WebAPI 服务,热词使用方式:登陆开放平台https://www.xfyun.cn/后,找到控制台--我的应用---语音听写---个性化热词,上传热词
* 注意:热词只能在识别的时候会增加热词的识别权重,需要注意的是增加相应词条的识别率,但并不是绝对的,具体效果以您测试为准。
* 错误码链接:https://www.xfyun.cn/document/error-code (code返回错误码时必看)
* 语音听写流式WebAPI 服务,方言或小语种试用方法:登陆开放平台https://www.xfyun.cn/后,在控制台--语音听写(流式)--方言/语种处添加
* 添加后会显示该方言/语种的参数值
* @author iflytek
*/

public class WebIATWS extends WebSocketListener {
private static final String hostUrl = "https://iat-api.xfyun.cn/v2/iat"; //中英文,http url 不支持解析 ws/wss schema
// private static final String hostUrl = "https://iat-niche-api.xfyun.cn/v2/iat";//小语种
private static final String appid = "e14469ab"; //在控制台-我的应用获取
public static final int StatusFirstFrame = 0;
public static final int StatusContinueFrame = 1;
public static final int StatusLastFrame = 2;
public static final Gson json = new Gson();
Decoder decoder = new Decoder();
// 开始时间
private static Date dateBegin = new Date();
// 结束时间
private static Date dateEnd = new Date();
private static final SimpleDateFormat sdf = new SimpleDateFormat("yyy-MM-dd HH:mm:ss.SSS");
private byte[] asrData;
private boolean isEnd = false;
private WebSocket mWebSocket;
private String HANDLE_THREAD_NAME = "audioStream";
private HandlerThread backgroundThread;
private Handler backgroundHandler;

private long time;
private Timer mTimer;
private String mFilePath;

public WebIATWS(){
backgroundThread = new HandlerThread(HANDLE_THREAD_NAME);
backgroundThread.start();
backgroundThread.setPriority(10);
backgroundHandler = new Handler(backgroundThread.getLooper());
// startTimer();
}

public void sendData(byte[] data){
asrData = data;
int length = data.length;
Logger.e("pcm data length = " + length);
isEnd = false;
if(time == 0){
backgroundHandler.post(readAndWrite);
} else{
long interval = System.currentTimeMillis() - time;
if(interval < 40){
backgroundHandler.postDelayed(readAndWrite, 40 - interval);
} else{
backgroundHandler.post(readAndWrite);
}
}
time = System.currentTimeMillis();
}

public void startTimer(){
mTimer = new Timer();
mTimer.schedule(new TimerTask() {
@Override
public void run() {
if(System.currentTimeMillis() - time > 1000){
if(asrData != null){
JsonObject frame2 = new JsonObject();
JsonObject data2 = new JsonObject();
data2.addProperty("status", StatusLastFrame);
data2.addProperty("audio", "");
data2.addProperty("format", "audio/L16;rate=16000");
data2.addProperty("encoding", "raw");
frame2.add("data", data2);
mWebSocket.send(frame2.toString());
System.out.println("sendlast");
asrData = null;
}
}
}
}, 0,1000);
}

public void sendEnd(){
this.isEnd = true;
}

public void transfer(String filePath){
mFilePath = filePath;
backgroundHandler.post(readAndWrite);
}

private final Runnable readAndWrite = new Runnable() {
@Override
public void run() {
int frameSize = 1280; //每一帧音频的大小,建议每 40ms 发送 122B
int intervel = 40;
int status = 0; // 音频的状态
try (FileInputStream fs = new FileInputStream(mFilePath)) {
byte[] buffer = new byte[frameSize];
// 发送音频
end:
while (true) {
int len = fs.read(buffer);
if (len == -1) {
status = StatusLastFrame; //文件读完,改变status 为 2
}
switch (status) {
case StatusFirstFrame: // 第一帧音频status = 0
JsonObject frame = new JsonObject();
JsonObject business = new JsonObject(); //第一帧必须发送
JsonObject common = new JsonObject(); //第一帧必须发送
JsonObject data = new JsonObject(); //每一帧都要发送
// 填充common
common.addProperty("app_id", appid);
//填充business
business.addProperty("language", "zh_cn");
//business.addProperty("language", "en_us");//英文
//business.addProperty("language", "ja_jp");//日语,在控制台可添加试用或购买
//business.addProperty("language", "ko_kr");//韩语,在控制台可添加试用或购买
//business.addProperty("language", "ru-ru");//俄语,在控制台可添加试用或购买
business.addProperty("domain", "iat");
business.addProperty("accent", "mandarin");//中文方言请在控制台添加试用,添加后即展示相应参数值
//business.addProperty("nunum", 0);
//business.addProperty("ptt", 0);//标点符号
//business.addProperty("rlang", "zh-hk"); // zh-cn :简体中文(默认值)zh-hk :繁体香港(若未授权不生效,在控制台可免费开通)
//business.addProperty("vinfo", 1);
business.addProperty("dwa", "wpgs");//动态修正(若未授权不生效,在控制台可免费开通)
//business.addProperty("nbest", 5);// 句子多候选(若未授权不生效,在控制台可免费开通)
//business.addProperty("wbest", 3);// 词级多候选(若未授权不生效,在控制台可免费开通)
//填充data
data.addProperty("status", StatusFirstFrame);
data.addProperty("format", "audio/L16;rate=16000");
data.addProperty("encoding", "raw");
data.addProperty("audio", Base64.getEncoder().encodeToString(Arrays.copyOf(buffer, len)));
//填充frame
frame.add("common", common);
frame.add("business", business);
frame.add("data", data);
mWebSocket.send(frame.toString());
status = StatusContinueFrame; // 发送完第一帧改变status 为 1
break;
case StatusContinueFrame: //中间帧status = 1
JsonObject frame1 = new JsonObject();
JsonObject data1 = new JsonObject();
data1.addProperty("status", StatusContinueFrame);
data1.addProperty("format", "audio/L16;rate=16000");
data1.addProperty("encoding", "raw");
data1.addProperty("audio", Base64.getEncoder().encodeToString(Arrays.copyOf(buffer, len)));
frame1.add("data", data1);
mWebSocket.send(frame1.toString());
// System.out.println("send continue");
break;
case StatusLastFrame: // 最后一帧音频status = 2 ,标志音频发送结束
JsonObject frame2 = new JsonObject();
JsonObject data2 = new JsonObject();
data2.addProperty("status", StatusLastFrame);
data2.addProperty("audio", "");
data2.addProperty("format", "audio/L16;rate=16000");
data2.addProperty("encoding", "raw");
frame2.add("data", data2);
mWebSocket.send(frame2.toString());
System.out.println("sendlast");
break end;
}
// Thread.sleep(intervel); //模拟音频采样延时
}
Logger.e("djTtsTime-all data is send");
} catch (FileNotFoundException e) {
Logger.e("djTtsTime- FileNotFoundException:" + e.getMessage());
e.printStackTrace();
} catch (IOException e) {
Logger.e("djTtsTime- IOException:" + e.getMessage());
e.printStackTrace();
}
}
};

@Override
public void onOpen(WebSocket webSocket, Response response) {
mWebSocket = webSocket;
super.onOpen(webSocket, response);
Logger.e("djTtsTime-websocket open");

// new Thread(()->{
// //连接成功,开始发送数据
// int frameSize = 1280; //每一帧音频的大小,建议每 40ms 发送 122B
// int intervel = 40;
// int status = 0; // 音频的状态
// try (FileInputStream fs = new FileInputStream(file)) {
// byte[] buffer = new byte[frameSize];
// // 发送音频
// end:
// while (true) {
// int len = fs.read(buffer);
// if (len == -1) {
// status = StatusLastFrame; //文件读完,改变status 为 2
// }
// switch (status) {
// case StatusFirstFrame: // 第一帧音频status = 0
// JsonObject frame = new JsonObject();
// JsonObject business = new JsonObject(); //第一帧必须发送
// JsonObject common = new JsonObject(); //第一帧必须发送
// JsonObject data = new JsonObject(); //每一帧都要发送
// // 填充common
// common.addProperty("app_id", appid);
// //填充business
// business.addProperty("language", "zh_cn");
// //business.addProperty("language", "en_us");//英文
// //business.addProperty("language", "ja_jp");//日语,在控制台可添加试用或购买
// //business.addProperty("language", "ko_kr");//韩语,在控制台可添加试用或购买
// //business.addProperty("language", "ru-ru");//俄语,在控制台可添加试用或购买
// business.addProperty("domain", "iat");
// business.addProperty("accent", "mandarin");//中文方言请在控制台添加试用,添加后即展示相应参数值
// //business.addProperty("nunum", 0);
// //business.addProperty("ptt", 0);//标点符号
// //business.addProperty("rlang", "zh-hk"); // zh-cn :简体中文(默认值)zh-hk :繁体香港(若未授权不生效,在控制台可免费开通)
// //business.addProperty("vinfo", 1);
// business.addProperty("dwa", "wpgs");//动态修正(若未授权不生效,在控制台可免费开通)
// //business.addProperty("nbest", 5);// 句子多候选(若未授权不生效,在控制台可免费开通)
// //business.addProperty("wbest", 3);// 词级多候选(若未授权不生效,在控制台可免费开通)
// //填充data
// data.addProperty("status", StatusFirstFrame);
// data.addProperty("format", "audio/L16;rate=16000");
// data.addProperty("encoding", "raw");
// data.addProperty("audio", Base64.getEncoder().encodeToString(Arrays.copyOf(buffer, len)));
// //填充frame
// frame.add("common", common);
// frame.add("business", business);
// frame.add("data", data);
// webSocket.send(frame.toString());
// status = StatusContinueFrame; // 发送完第一帧改变status 为 1
// break;
// case StatusContinueFrame: //中间帧status = 1
// JsonObject frame1 = new JsonObject();
// JsonObject data1 = new JsonObject();
// data1.addProperty("status", StatusContinueFrame);
// data1.addProperty("format", "audio/L16;rate=16000");
// data1.addProperty("encoding", "raw");
// data1.addProperty("audio", Base64.getEncoder().encodeToString(Arrays.copyOf(buffer, len)));
// frame1.add("data", data1);
// webSocket.send(frame1.toString());
// // System.out.println("send continue");
// break;
// case StatusLastFrame: // 最后一帧音频status = 2 ,标志音频发送结束
// JsonObject frame2 = new JsonObject();
// JsonObject data2 = new JsonObject();
// data2.addProperty("status", StatusLastFrame);
// data2.addProperty("audio", "");
// data2.addProperty("format", "audio/L16;rate=16000");
// data2.addProperty("encoding", "raw");
// frame2.add("data", data2);
// webSocket.send(frame2.toString());
// System.out.println("sendlast");
// break end;
// }
// Thread.sleep(intervel); //模拟音频采样延时
// }
// System.out.println("all data is send");
// } catch (FileNotFoundException e) {
// e.printStackTrace();
// } catch (IOException e) {
// e.printStackTrace();
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// }).start();
}
@Override
public void onMessage(WebSocket webSocket, String text) {
super.onMessage(webSocket, text);
//System.out.println(text);
ResponseData resp = json.fromJson(text, ResponseData.class);
if (resp != null) {
if (resp.getCode() != 0) {
System.out.println( "code=>" + resp.getCode() + " error=>" + resp.getMessage() + " sid=" + resp.getSid());
System.out.println( "错误码查询链接:https://www.xfyun.cn/document/error-code");
Logger.e("djTtsTime-code=>" + resp.getCode() + " error=>" + resp.getMessage() + " sid=" + resp.getSid());
Logger.e("djTtsTime-错误码查询链接:https://www.xfyun.cn/document/error-code");
return;
}
if (resp.getData() != null) {
if (resp.getData().getResult() != null) {
Text te = resp.getData().getResult().getText();
//System.out.println(te.toString());
try {
decoder.decode(te);
System.out.println("中间识别结果 ==》" + decoder.toString());
Logger.e("djTtsTime-" + "中间识别结果 ==》" + decoder.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
if (resp.getData().getStatus() == 2) {
// todo resp.data.status ==2 说明数据全部返回完毕,可以关闭连接,释放资源
System.out.println("session end ");
dateEnd = new Date();
System.out.println(sdf.format(dateBegin) + "开始");
System.out.println(sdf.format(dateEnd) + "结束");
System.out.println("耗时:" + (dateEnd.getTime() - dateBegin.getTime()) + "ms");
System.out.println("最终识别结果 ==》" + decoder.toString());
System.out.println("本次识别sid ==》" + resp.getSid());
Logger.e("djTtsTime-" + sdf.format(dateBegin) + "开始");
Logger.e("djTtsTime-" + sdf.format(dateEnd) + "结束");
Logger.e("djTtsTime-" + "耗时:" + (dateEnd.getTime() - dateBegin.getTime()) + "ms");
Logger.e("djTtsTime-" + "最终识别结果 ==》" + decoder.toString());
Logger.e("djTtsTime-" + "本次识别sid ==》" + resp.getSid());
decoder.discard();
// webSocket.close(1000, "");
} else {
// todo 根据返回的数据处理
}
}
}
}
@Override
public void onFailure(WebSocket webSocket, Throwable t, Response response) {
super.onFailure(webSocket, t, response);
try {
if (null != response) {
int code = response.code();
System.out.println("onFailure code:" + code);
System.out.println("onFailure body:" + response.body().string());
Logger.e("djTtsTime-onFailure code:" + code);
Logger.e("djTtsTime-onFailure body:" + response.body().string());
if (101 != code) {
System.out.println("connection failed");
System.exit(0);
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

public static class ResponseData {
private int code;
private String message;
private String sid;
private Data data;
public int getCode() {
return code;
}
public String getMessage() {
return this.message;
}
public String getSid() {
return sid;
}
public Data getData() {
return data;
}
}
public static class Data {
private int status;
private Result result;
public int getStatus() {
return status;
}
public Result getResult() {
return result;
}
}
public static class Result {
int bg;
int ed;
String pgs;
int[] rg;
int sn;
Ws[] ws;
boolean ls;
JsonObject vad;
public Text getText() {
Text text = new Text();
StringBuilder sb = new StringBuilder();
for (Ws ws : this.ws) {
sb.append(ws.cw[0].w);
}
text.sn = this.sn;
text.text = sb.toString();
text.sn = this.sn;
text.rg = this.rg;
text.pgs = this.pgs;
text.bg = this.bg;
text.ed = this.ed;
text.ls = this.ls;
text.vad = this.vad==null ? null : this.vad;
return text;
}
}
public static class Ws {
Cw[] cw;
int bg;
int ed;
}
public static class Cw {
int sc;
String w;
}
public static class Text {
int sn;
int bg;
int ed;
String text;
String pgs;
int[] rg;
boolean deleted;
boolean ls;
JsonObject vad;
@Override
public String toString() {
return "Text{" +
"bg=" + bg +
", ed=" + ed +
", ls=" + ls +
", sn=" + sn +
", text='" + text + '\'' +
", pgs=" + pgs +
", rg=" + Arrays.toString(rg) +
", deleted=" + deleted +
", vad=" + (vad==null ? "null" : vad.getAsJsonArray("ws").toString()) +
'}';
}
}
//解析返回数据,仅供参考
public static class Decoder {
private Text[] texts;
private int defc = 10;
public Decoder() {
this.texts = new Text[this.defc];
}
public synchronized void decode(Text text) {
if (text.sn >= this.defc) {
this.resize();
}
if ("rpl".equals(text.pgs)) {
for (int i = text.rg[0]; i <= text.rg[1]; i++) {
this.texts[i].deleted = true;
}
}
this.texts[text.sn] = text;
}
public String toString() {
StringBuilder sb = new StringBuilder();
for (Text t : this.texts) {
if (t != null && !t.deleted) {
sb.append(t.text);
}
}
return sb.toString();
}
public void resize() {
int oc = this.defc;
this.defc <<= 1;
Text[] old = this.texts;
this.texts = new Text[this.defc];
for (int i = 0; i < oc; i++) {
this.texts[i] = old[i];
}
}
public void discard(){
for(int i=0;i<this.texts.length;i++){
this.texts[i]= null;
}
}
}
}

+ 32
- 23
app/src/main/java/com/aispeech/nativedemo/log/LogFile.java 查看文件

@@ -11,40 +11,49 @@ import java.util.Date;

public class LogFile {

/**
* 日常日志
* @param logMessage
* @return
*/
public static String saveLogMessageFile(String logMessage) {
long timestamp = System.currentTimeMillis();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
String time = dateFormat.format(new Date(timestamp));
StringBuffer sb = new StringBuffer();
sb.append(logMessage).append("\n");
try {
String fileName = "log-" + time + ".txt";
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
File dir = new File(Config.FilePath.LOG_PATH);
if (!dir.exists()) {
dir.mkdirs();
}
FileOutputStream fos = new FileOutputStream(Config.FilePath.LOG_PATH + "/" + fileName,true);
String logFile = new String(sb.toString().getBytes(),"UTF-8");
fos.write(logFile.getBytes());
fos.close();
}
return fileName;
} catch (Exception e) {
e.printStackTrace();
}
return null;
return saveFile(logMessage,"log-");
}

/**
* 叠境TTS内容日志
* @param logMessage
* @return
*/
public static String saveDjLogMessageFile(String logMessage) {
logMessage = logMessage.replace("djlog-", "");
return saveFile(logMessage,"djlog-");
}

/**
* 叠境TTS时长日志
* @param logMessage
* @return
*/
public static String saveDjTtsTimeFile(String logMessage) {
logMessage = logMessage.replace("djTtsTime-", "");
return saveFile(logMessage,"tts-total-time-");
}

/**
* 保存日志文件
* @param logMessage 日志消息
* @param filePre 日志文件名前缀
* @return
*/
public static String saveFile(String logMessage, String filePre) {
long timestamp = System.currentTimeMillis();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
String time = dateFormat.format(new Date(timestamp));
StringBuffer sb = new StringBuffer();
sb.append(logMessage).append("\n");
try {
String fileName = "djlog-" + time + ".txt";
String fileName = filePre + time + ".txt";
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
File dir = new File(Config.FilePath.LOG_PATH);
if (!dir.exists()) {


+ 2
- 0
app/src/main/java/com/aispeech/nativedemo/log/LoggerPrinter.java 查看文件

@@ -379,6 +379,8 @@ final class LoggerPrinter implements Printer {
}
if(chunk.contains("djlog")){
LogFile.saveDjLogMessageFile(chunk);
} else if(chunk.contains("djTtsTime")){
LogFile.saveDjTtsTimeFile(chunk);
} else{
LogFile.saveLogMessageFile(chunk);
}


+ 2
- 2
app/src/main/java/com/aispeech/nativedemo/mqtt/Mqtt.java 查看文件

@@ -23,7 +23,7 @@ public class Mqtt implements IMqtt{
public void init(MqttCallback mqttCallback, IMqttActionListener iMqttActionListener){
mIMqttActionListener = iMqttActionListener;
try{
mqttAndroidClient = new MqttAndroidClient(mContext, MqttConfig.HOST, MqttConfig.CLIENT_ID);
mqttAndroidClient = new MqttAndroidClient(mContext, MqttConfig.HOST_CURRENT, MqttConfig.CLIENT_ID);
mqttAndroidClient.setCallback(mqttCallback); //设置订阅消息的回调
mMqttConnectOptions = new MqttConnectOptions();
mMqttConnectOptions.setCleanSession(true); //设置是否清除缓存
@@ -33,7 +33,7 @@ public class Mqtt implements IMqtt{
mMqttConnectOptions.setPassword(MqttConfig.PASSWORD.toCharArray()); //设置密码

Log.d(TAG, "initMqtt: " +
"\n服务器地址(协议+地址+端口号):" + MqttConfig.HOST +
"\n服务器地址(协议+地址+端口号):" + MqttConfig.HOST_CURRENT +
"\nCLIENT_ID:" + MqttConfig.CLIENT_ID +
"\n用户名:" + MqttConfig.USER_NAME +
"\n密码:" + MqttConfig.PASSWORD);


+ 3
- 2
app/src/main/java/com/aispeech/nativedemo/mqtt/MqttConfig.java 查看文件

@@ -3,7 +3,8 @@ package com.aispeech.nativedemo.mqtt;
import android.os.Build;

public class MqttConfig {
public static final String HOST = "tcp://123.57.75.177:1883";
public static final String HOST_PROD = "tcp://123.57.75.177:1883";
public static final String HOST_CURRENT = HOST_PROD;
public static final String CLIENT_ID = Build.SERIAL;
public static final int QUALITY_OF_SERVICE = 1; //0;//服务质量,0最多一次,1最少一次,2只一次
public static final int HAND_MESSAGE = 0;
@@ -13,7 +14,7 @@ public class MqttConfig {
public static final String PASSWORD = "public";
public static final String ENV_PROD = "/prod";
public static final String ENV_DEV = "/dev";
public static final String ENV_CURRENT = ENV_PROD;
public static final String ENV_CURRENT = ENV_DEV;

/**
* 心跳


+ 6
- 3
app/src/main/java/com/aispeech/nativedemo/network/ws/DigiWebSocketServer.java 查看文件

@@ -77,7 +77,7 @@ public class DigiWebSocketServer extends WebSocketServer {
Utils.websocketList.remove(conn.getRemoteSocketAddress().toString());
mConns.add(conn);
removeConnection(conn);
// MqttManager.getInstance(MainActivity.instance).getFileUploadPath(Config.ErrorEvent.ERROR_UPLOAD_WARNING, Config.ErrorEvent.ERROR_LEVEL_2, "socket_status", "onClose");
MqttManager.getInstance(MainActivity.instance).getFileUploadPath(Config.ErrorEvent.ERROR_UPLOAD_WARNING, Config.ErrorEvent.ERROR_LEVEL_2, "socket_status", "onClose");
}

@Override
@@ -89,6 +89,9 @@ public class DigiWebSocketServer extends WebSocketServer {
if(message.contains("djlog-")){
Logger.e(message);
return;
} else if(message.contains("djTtsTime-")){
Logger.e(message);
return;
} else{
Logger.e("onMessage()网页端来的消息->" + conn.getRemoteSocketAddress() + ": " + message);
}
@@ -117,7 +120,7 @@ public class DigiWebSocketServer extends WebSocketServer {
String requestName = obj.optString("requestName");
String errMsg = obj.optString("errMsg");
Logger.e(requestName + ":" + errMsg);
// MqttManager.getInstance(MainActivity.instance).getFileUploadPath(Config.ErrorEvent.ERROR_UPLOAD_WARNING, Config.ErrorEvent.ERROR_LEVEL_2, "web_request_error", "requestErr");
MqttManager.getInstance(MainActivity.instance).getFileUploadPath(Config.ErrorEvent.ERROR_UPLOAD_WARNING, Config.ErrorEvent.ERROR_LEVEL_2, "web_request_error", "requestErr");
} else if(type.equals("asrSwitch")){
boolean status = obj.optBoolean("status");
if(status){
@@ -168,7 +171,7 @@ public class DigiWebSocketServer extends WebSocketServer {
Looper.loop();
}
// removeConnection(conn);
// MqttManager.getInstance(MainActivity.instance).getFileUploadPath(Config.ErrorEvent.ERROR_UPLOAD_WARNING, Config.ErrorEvent.ERROR_LEVEL_2, "socket_status", "onError");
MqttManager.getInstance(MainActivity.instance).getFileUploadPath(Config.ErrorEvent.ERROR_UPLOAD_WARNING, Config.ErrorEvent.ERROR_LEVEL_2, "socket_status", "onError");
ex.printStackTrace();
} catch (Exception e) {
e.printStackTrace();


+ 55
- 6
app/src/main/java/com/aispeech/nativedemo/network/ws/MessageUtils.java 查看文件

@@ -13,7 +13,10 @@ import com.aispeech.nativedemo.db.ModelDbHelper;
import com.aispeech.nativedemo.db.SkillDbHelper;
import com.aispeech.nativedemo.entity.Model;
import com.aispeech.nativedemo.entity.Skill;
import com.aispeech.nativedemo.face.FaceChatMode;
import com.aispeech.nativedemo.face.IdentityMode;
import com.aispeech.nativedemo.log.Logger;
import com.aispeech.nativedemo.shape.ShapeManager;

import org.json.JSONException;
import org.json.JSONObject;
@@ -135,7 +138,7 @@ public class MessageUtils {
}
}

public static String sendSkill(String display){
public static String sendSkill(String display, String dmInput){
String readText = "";
try {
JSONObject jo = new JSONObject();
@@ -170,11 +173,18 @@ public class MessageUtils {
}
if(skillObj.has("skillCode")){
int skillCode = skillObj.optInt("skillCode");
Skill skill = SkillDbHelper.getInstance().getBySkillCode(skillCode);
if(skill != null){
skillObj.put("resp", skill.resp);
skillObj.put("status", skill.status);
skillObj.put("motionName", skill.motionName);
if(skillCode == 24){
if(IdentityMode.MODE_CURRENT.equals(IdentityMode.MODE_CHAT)){
FaceChatMode.introduceNewPartner(dmInput);
}
return "";
} else{
Skill skill = SkillDbHelper.getInstance().getBySkillCode(skillCode);
if(skill != null){
skillObj.put("resp", skill.resp);
skillObj.put("status", skill.status);
skillObj.put("motionName", skill.motionName);
}
}
}
jo.put("data", skillObj.toString());
@@ -204,6 +214,20 @@ public class MessageUtils {
}
}

public static void sendAsrText(String data){
try {
if(!TextUtils.isEmpty(data)){
JSONObject person = new JSONObject();
person.put("type", "asr");
person.put("data", data);
sendMessage(person.toString());
// ShapeManager.getInstance().nlpFromNewDevGpt(txt);
}
} catch (JSONException e) {
e.printStackTrace();
}
}

public static void sendTtsText(String data){
try {
if(!TextUtils.isEmpty(data)){
@@ -230,6 +254,9 @@ public class MessageUtils {
} catch (JSONException e) {
e.printStackTrace();
}
// if(!TextUtils.isEmpty(data)){
// ShapeManager.getInstance().speak(data);
// }
}

public static void sendRest(){
@@ -302,4 +329,26 @@ public class MessageUtils {
throw new RuntimeException(e);
}
}

public static void sendAddPartner(String message){
try {
JSONObject jo = new JSONObject();
jo.put("type", "addPartner");
jo.put("data", message);
sendMessage(jo.toString());
} catch (JSONException e) {
throw new RuntimeException(e);
}
}

public static void sendBroadcast(String message){
try {
JSONObject jo = new JSONObject();
jo.put("type", "broadcast");
jo.put("data", message);
sendMessage(jo.toString());
} catch (JSONException e) {
throw new RuntimeException(e);
}
}
}

+ 0
- 31
app/src/main/java/com/aispeech/nativedemo/rtasr/DraftWithOrigin.java 查看文件

@@ -1,31 +0,0 @@
package com.aispeech.nativedemo.rtasr;

import org.java_websocket.drafts.Draft;
import org.java_websocket.drafts.Draft_6455;
import org.java_websocket.handshake.ClientHandshakeBuilder;

import com.sun.istack.internal.NotNull;

@SuppressWarnings("deprecation")
public class DraftWithOrigin extends Draft_6455 {

private String originUrl;

public DraftWithOrigin(String originUrl) {
this.originUrl = originUrl;
}

@Override
public Draft copyInstance() {
System.out.println(originUrl);
return new DraftWithOrigin(originUrl);
}

@NotNull
@Override
public ClientHandshakeBuilder postProcessHandshakeRequestAsClient(@NotNull ClientHandshakeBuilder request) {
super.postProcessHandshakeRequestAsClient(request);
request.put("Origin", originUrl);
return request;
}
}

+ 0
- 66
app/src/main/java/com/aispeech/nativedemo/rtasr/EncryptUtil.java 查看文件

@@ -1,66 +0,0 @@
package com.aispeech.nativedemo.rtasr;

import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SignatureException;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Base64;

public class EncryptUtil {

/**
* 加密数字签名(基于HMACSHA1算法)
*
* @param encryptText
* @param encryptKey
* @return
* @throws SignatureException
*/
public static String HmacSHA1Encrypt(String encryptText, String encryptKey) throws SignatureException {
byte[] rawHmac = null;
try {
byte[] data = encryptKey.getBytes("UTF-8");
SecretKeySpec secretKey = new SecretKeySpec(data, "HmacSHA1");
Mac mac = Mac.getInstance("HmacSHA1");
mac.init(secretKey);
byte[] text = encryptText.getBytes("UTF-8");
rawHmac = mac.doFinal(text);
} catch (InvalidKeyException e) {
throw new SignatureException("InvalidKeyException:" + e.getMessage());
} catch (NoSuchAlgorithmException e) {
throw new SignatureException("NoSuchAlgorithmException:" + e.getMessage());
} catch (UnsupportedEncodingException e) {
throw new SignatureException("UnsupportedEncodingException:" + e.getMessage());
}
String oauth = new String(Base64.encodeBase64(rawHmac));
return oauth;
}

public final static String MD5(String pstr) {
char md5String[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
try {
byte[] btInput = pstr.getBytes();
MessageDigest mdInst = MessageDigest.getInstance("MD5");
mdInst.update(btInput);
byte[] md = mdInst.digest();
int j = md.length;
char str[] = new char[j * 2];
int k = 0;
for (int i = 0; i < j; i++) { // i = 0
byte byte0 = md[i]; // 95
str[k++] = md5String[byte0 >>> 4 & 0xf]; // 5
str[k++] = md5String[byte0 & 0xf]; // F
}

return new String(str);
} catch (Exception e) {
return null;
}
}
}

+ 0
- 228
app/src/main/java/com/aispeech/nativedemo/rtasr/RTASRManager.java 查看文件

@@ -1,228 +0,0 @@
package com.aispeech.nativedemo.rtasr;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import org.java_websocket.client.WebSocketClient;
import org.java_websocket.drafts.Draft;
import org.java_websocket.enums.ReadyState;
import org.java_websocket.handshake.ServerHandshake;

import java.io.RandomAccessFile;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URLEncoder;
import java.nio.ByteBuffer;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.Objects;
import java.util.concurrent.CountDownLatch;

public class RTASRManager {
private static final String TAG = "RTASRManager";
private static RTASRManager mInstance;

private static final String APPID = "";

// appid对应的secret_key
private static final String SECRET_KEY = "";

// 请求地址
private static final String HOST = "rtasr.xfyun.cn/v1/ws";

private static final String BASE_URL = "ws://" + HOST;

private static final String ORIGIN = "http://" + HOST;

// 音频文件路径
private static final String AUDIO_PATH = "./resource/test_1.pcm";

// 每次发送的数据大小 1280 字节
private static final int CHUNCKED_SIZE = 1280;

private static final SimpleDateFormat sdf = new SimpleDateFormat("yyy-MM-dd HH:mm:ss.SSS");

private RTASRManager() {

}

public static RTASRManager getInstance() {
if (mInstance == null) {
synchronized (RTASRManager.class) {
if (mInstance == null) {
mInstance = new RTASRManager();
}
}
}
return mInstance;
}

public static void sendAsrDataByte(Byte[] data) throws Exception {
while (true) {
URI url = new URI(BASE_URL + getHandShakeParams(APPID, SECRET_KEY));
DraftWithOrigin draft = new DraftWithOrigin(ORIGIN);
CountDownLatch handshakeSuccess = new CountDownLatch(1);
CountDownLatch connectClose = new CountDownLatch(1);
RTASRTest.MyWebSocketClient client = new RTASRTest.MyWebSocketClient(url, draft, handshakeSuccess, connectClose);

client.connect();

while (!client.getReadyState().equals(ReadyState.OPEN)) {
System.out.println(getCurrentTimeStr() + "\t连接中");
Thread.sleep(1000);
}

// 等待握手成功
handshakeSuccess.await();
System.out.println(sdf.format(new Date()) + " 开始发送音频数据");
// 发送音频
byte[] bytes = new byte[CHUNCKED_SIZE];
try (RandomAccessFile raf = new RandomAccessFile(AUDIO_PATH, "r")) {
int len = -1;
long lastTs = 0;
while ((len = raf.read(bytes)) != -1) {
if (len < CHUNCKED_SIZE) {
send(client, bytes = Arrays.copyOfRange(bytes, 0, len));
break;
}

long curTs = System.currentTimeMillis();
if (lastTs == 0) {
lastTs = System.currentTimeMillis();
} else {
long s = curTs - lastTs;
if (s < 40) {
System.out.println("error time interval: " + s + " ms");
}
}
send(client, bytes);
// 每隔40毫秒发送一次数据
Thread.sleep(40);
}

// 发送结束标识
send(client,"{\"end\": true}".getBytes());
System.out.println(getCurrentTimeStr() + "\t发送结束标识完成");
} catch (Exception e) {
e.printStackTrace();
}

// 等待连接关闭
connectClose.await();
break;
}
}

// 生成握手参数
public static String getHandShakeParams(String appId, String secretKey) {
String ts = System.currentTimeMillis()/1000 + "";
String signa = "";
try {
signa = EncryptUtil.HmacSHA1Encrypt(EncryptUtil.MD5(appId + ts), secretKey);
return "?appid=" + appId + "&ts=" + ts + "&signa=" + URLEncoder.encode(signa, "UTF-8");
} catch (Exception e) {
e.printStackTrace();
}

return "";
}

public static void send(WebSocketClient client, byte[] bytes) {
if (client.isClosed()) {
throw new RuntimeException("client connect closed!");
}

client.send(bytes);
}

public static String getCurrentTimeStr() {
return sdf.format(new Date());
}

public static class MyWebSocketClient extends WebSocketClient {

private CountDownLatch handshakeSuccess;
private CountDownLatch connectClose;

public MyWebSocketClient(URI serverUri, Draft protocolDraft, CountDownLatch handshakeSuccess, CountDownLatch connectClose) {
super(serverUri, protocolDraft);
this.handshakeSuccess = handshakeSuccess;
this.connectClose = connectClose;
}

@Override
public void onOpen(ServerHandshake handshake) {
System.out.println(getCurrentTimeStr() + "\t连接建立成功!");
}

@Override
public void onMessage(String msg) {
JSONObject msgObj = JSON.parseObject(msg);
String action = msgObj.getString("action");
if (Objects.equals("started", action)) {
// 握手成功
System.out.println(getCurrentTimeStr() + "\t握手成功!sid: " + msgObj.getString("sid"));
handshakeSuccess.countDown();
} else if (Objects.equals("result", action)) {
// 转写结果
System.out.println(getCurrentTimeStr() + "\tresult: " + getContent(msgObj.getString("data")));
} else if (Objects.equals("error", action)) {
// 连接发生错误
System.out.println("Error: " + msg);
System.exit(0);
}
}

@Override
public void onError(Exception e) {
System.out.println(getCurrentTimeStr() + "\t连接发生错误:" + e.getMessage() + ", " + new Date());
e.printStackTrace();
System.exit(0);
}

@Override
public void onClose(int arg0, String arg1, boolean arg2) {
System.out.println(getCurrentTimeStr() + "\t链接关闭");
connectClose.countDown();
}

@Override
public void onMessage(ByteBuffer bytes) {
try {
System.out.println(getCurrentTimeStr() + "\t服务端返回:" + new String(bytes.array(), "UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}

// 把转写结果解析为句子
public static String getContent(String message) {
StringBuffer resultBuilder = new StringBuffer();
try {
JSONObject messageObj = JSON.parseObject(message);
JSONObject cn = messageObj.getJSONObject("cn");
JSONObject st = cn.getJSONObject("st");
JSONArray rtArr = st.getJSONArray("rt");
for (int i = 0; i < rtArr.size(); i++) {
JSONObject rtArrObj = rtArr.getJSONObject(i);
JSONArray wsArr = rtArrObj.getJSONArray("ws");
for (int j = 0; j < wsArr.size(); j++) {
JSONObject wsArrObj = wsArr.getJSONObject(j);
JSONArray cwArr = wsArrObj.getJSONArray("cw");
for (int k = 0; k < cwArr.size(); k++) {
JSONObject cwArrObj = cwArr.getJSONObject(k);
String wStr = cwArrObj.getString("w");
resultBuilder.append(wStr);
}
}
}
} catch (Exception e) {
return message;
}

return resultBuilder.toString();
}
}

+ 0
- 219
app/src/main/java/com/aispeech/nativedemo/rtasr/RTASRTest.java 查看文件

@@ -1,219 +0,0 @@
package com.aispeech.nativedemo.rtasr;

import java.io.RandomAccessFile;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URLEncoder;
import java.nio.ByteBuffer;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.Objects;
import java.util.concurrent.CountDownLatch;

import org.java_websocket.client.WebSocketClient;
import org.java_websocket.drafts.Draft;
import org.java_websocket.enums.ReadyState;
import org.java_websocket.handshake.ServerHandshake;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

/**
* 实时转写调用demo
* 此demo只是一个简单的调用示例,不适合用到实际生产环境中
*
* @author white
*
*/
public class RTASRTest {

// appid
private static final String APPID = "";

// appid对应的secret_key
private static final String SECRET_KEY = "";

// 请求地址
private static final String HOST = "rtasr.xfyun.cn/v1/ws";

private static final String BASE_URL = "ws://" + HOST;

private static final String ORIGIN = "http://" + HOST;

// 音频文件路径
private static final String AUDIO_PATH = "./resource/test_1.pcm";

// 每次发送的数据大小 1280 字节
private static final int CHUNCKED_SIZE = 1280;

private static final SimpleDateFormat sdf = new SimpleDateFormat("yyy-MM-dd HH:mm:ss.SSS");

public static void sendAsrDataByte(Byte[] data) throws Exception {
while (true) {
URI url = new URI(BASE_URL + getHandShakeParams(APPID, SECRET_KEY));
DraftWithOrigin draft = new DraftWithOrigin(ORIGIN);
CountDownLatch handshakeSuccess = new CountDownLatch(1);
CountDownLatch connectClose = new CountDownLatch(1);
MyWebSocketClient client = new MyWebSocketClient(url, draft, handshakeSuccess, connectClose);
client.connect();
while (!client.getReadyState().equals(ReadyState.OPEN)) {
System.out.println(getCurrentTimeStr() + "\t连接中");
Thread.sleep(1000);
}
// 等待握手成功
handshakeSuccess.await();
System.out.println(sdf.format(new Date()) + " 开始发送音频数据");
// 发送音频
byte[] bytes = new byte[CHUNCKED_SIZE];
try (RandomAccessFile raf = new RandomAccessFile(AUDIO_PATH, "r")) {
int len = -1;
long lastTs = 0;
while ((len = raf.read(bytes)) != -1) {
if (len < CHUNCKED_SIZE) {
send(client, bytes = Arrays.copyOfRange(bytes, 0, len));
break;
}

long curTs = System.currentTimeMillis();
if (lastTs == 0) {
lastTs = System.currentTimeMillis();
} else {
long s = curTs - lastTs;
if (s < 40) {
System.out.println("error time interval: " + s + " ms");
}
}
send(client, bytes);
// 每隔40毫秒发送一次数据
Thread.sleep(40);
}
// 发送结束标识
send(client,"{\"end\": true}".getBytes());
System.out.println(getCurrentTimeStr() + "\t发送结束标识完成");
} catch (Exception e) {
e.printStackTrace();
}
// 等待连接关闭
connectClose.await();
break;
}
}

// 生成握手参数
public static String getHandShakeParams(String appId, String secretKey) {
String ts = System.currentTimeMillis()/1000 + "";
String signa = "";
try {
signa = EncryptUtil.HmacSHA1Encrypt(EncryptUtil.MD5(appId + ts), secretKey);
return "?appid=" + appId + "&ts=" + ts + "&signa=" + URLEncoder.encode(signa, "UTF-8");
} catch (Exception e) {
e.printStackTrace();
}

return "";
}

public static void send(WebSocketClient client, byte[] bytes) {
if (client.isClosed()) {
throw new RuntimeException("client connect closed!");
}

client.send(bytes);
}

public static String getCurrentTimeStr() {
return sdf.format(new Date());
}

public static class MyWebSocketClient extends WebSocketClient {

private CountDownLatch handshakeSuccess;
private CountDownLatch connectClose;

public MyWebSocketClient(URI serverUri, Draft protocolDraft, CountDownLatch handshakeSuccess, CountDownLatch connectClose) {
super(serverUri, protocolDraft);
this.handshakeSuccess = handshakeSuccess;
this.connectClose = connectClose;
}

@Override
public void onOpen(ServerHandshake handshake) {
System.out.println(getCurrentTimeStr() + "\t连接建立成功!");
}

@Override
public void onMessage(String msg) {
JSONObject msgObj = JSON.parseObject(msg);
String action = msgObj.getString("action");
if (Objects.equals("started", action)) {
// 握手成功
System.out.println(getCurrentTimeStr() + "\t握手成功!sid: " + msgObj.getString("sid"));
handshakeSuccess.countDown();
} else if (Objects.equals("result", action)) {
// 转写结果
System.out.println(getCurrentTimeStr() + "\tresult: " + getContent(msgObj.getString("data")));
} else if (Objects.equals("error", action)) {
// 连接发生错误
System.out.println("Error: " + msg);
System.exit(0);
}
}

@Override
public void onError(Exception e) {
System.out.println(getCurrentTimeStr() + "\t连接发生错误:" + e.getMessage() + ", " + new Date());
e.printStackTrace();
System.exit(0);
}

@Override
public void onClose(int arg0, String arg1, boolean arg2) {
System.out.println(getCurrentTimeStr() + "\t链接关闭");
connectClose.countDown();
}

@Override
public void onMessage(ByteBuffer bytes) {
try {
System.out.println(getCurrentTimeStr() + "\t服务端返回:" + new String(bytes.array(), "UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}

// 把转写结果解析为句子
public static String getContent(String message) {
StringBuffer resultBuilder = new StringBuffer();
try {
JSONObject messageObj = JSON.parseObject(message);
JSONObject cn = messageObj.getJSONObject("cn");
JSONObject st = cn.getJSONObject("st");
JSONArray rtArr = st.getJSONArray("rt");
for (int i = 0; i < rtArr.size(); i++) {
JSONObject rtArrObj = rtArr.getJSONObject(i);
JSONArray wsArr = rtArrObj.getJSONArray("ws");
for (int j = 0; j < wsArr.size(); j++) {
JSONObject wsArrObj = wsArr.getJSONObject(j);
JSONArray cwArr = wsArrObj.getJSONArray("cw");
for (int k = 0; k < cwArr.size(); k++) {
JSONObject cwArrObj = cwArr.getJSONObject(k);
String wStr = cwArrObj.getString("w");
resultBuilder.append(wStr);
}
}
}
} catch (Exception e) {
return message;
}

return resultBuilder.toString();
}
}

+ 2
- 1
app/src/main/java/com/aispeech/nativedemo/shape/ShapeManager.java 查看文件

@@ -39,7 +39,7 @@ import okhttp3.RequestBody;
public class ShapeManager {
private static final String TAG = "DDSManager";
private static ShapeManager mInstance;
private String url = "http://192.168.10.139:8999/RPC2";
private String url = "http://192.168.10.124:8999/RPC2";
// private String url = "http://192.168.10.103:8999";

private ShapeManager() {
@@ -82,6 +82,7 @@ public class ShapeManager {
}
});
} catch (XmlRpcException | MalformedURLException e) {
Log.e("ShapeManager", e.getMessage());
throw new RuntimeException(e);
}
Log.e("ShapeManager", "send message over");


二進制
test/libs/lib-dds-2.9.0.1-release.aar → test/libs/lib-dds-2.9.2.1-release.aar 查看文件


Loading…
取消
儲存