@@ -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) { | |||
@@ -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() { | |||
@@ -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); | |||
@@ -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); | |||
@@ -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; | |||
@@ -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"); | |||
@@ -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(); | |||
} | |||
} |
@@ -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(); | |||
} | |||
} |
@@ -6,4 +6,5 @@ public class Setting implements Serializable { | |||
public int id; | |||
public int isReceptionMode; //接待模式 1.是 0.否 | |||
public long hbUpdateTime; //心跳更新时间戳 | |||
public long ttsTotalTime; //tts总时长 | |||
} |
@@ -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); | |||
} | |||
}); | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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(); | |||
} | |||
} |
@@ -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; | |||
} | |||
} | |||
} | |||
} |
@@ -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()) { | |||
@@ -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); | |||
} | |||
@@ -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,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; | |||
/** | |||
* 心跳 | |||
@@ -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(); | |||
@@ -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); | |||
} | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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; | |||
} | |||
} | |||
} |
@@ -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(); | |||
} | |||
} |
@@ -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(); | |||
} | |||
} |
@@ -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"); | |||