@@ -0,0 +1,17 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<project version="4"> | |||
<component name="deploymentTargetDropDown"> | |||
<runningDeviceTargetSelectedWithDropDown> | |||
<Target> | |||
<type value="RUNNING_DEVICE_TARGET" /> | |||
<deviceKey> | |||
<Key> | |||
<type value="SERIAL_NUMBER" /> | |||
<value value="7d656601c9f0070f" /> | |||
</Key> | |||
</deviceKey> | |||
</Target> | |||
</runningDeviceTargetSelectedWithDropDown> | |||
<timeTargetWasSelectedWithDropDown value="2023-07-23T06:07:31.789079600Z" /> | |||
</component> | |||
</project> |
@@ -7,7 +7,6 @@ import android.app.Service; | |||
import android.content.Context; | |||
import android.content.Intent; | |||
import android.media.AudioFormat; | |||
import android.media.AudioManager; | |||
import android.os.Build; | |||
import android.os.Environment; | |||
import android.os.Handler; | |||
@@ -22,15 +21,14 @@ import android.widget.Toast; | |||
import com.aispeech.dui.dds.DDS; | |||
import com.aispeech.dui.dds.DDSAuthListener; | |||
import com.aispeech.dui.dds.DDSConfig; | |||
import com.aispeech.dui.dds.DDSConfigBuilder; | |||
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.log.Logger; | |||
import com.aispeech.nativedemo.mqtt.MqttManager; | |||
import com.aispeech.nativedemo.network.ws.MessageUtils; | |||
import com.aispeech.nativedemo.network.ws.WebSocketManager; | |||
import com.aispeech.nativedemo.ui.LauncherActivity; | |||
import com.aispeech.nativedemo.config.Config; | |||
@@ -40,6 +38,7 @@ import org.json.JSONObject; | |||
import java.io.File; | |||
import java.io.IOException; | |||
import java.io.RandomAccessFile; | |||
import java.util.UUID; | |||
/** | |||
@@ -121,7 +120,7 @@ public class DDSService extends Service { | |||
if (isFull) { | |||
// 发送一个init成功的广播 | |||
Logger.e("init face sdk"); | |||
FaceManager.getInstance(DuiApplication.getContext()).initEngine(); | |||
FaceManager.getInstance().initEngine(); | |||
Logger.e("init face sdk over"); | |||
sendBroadcast(new Intent("ddsdemo.intent.action.init_complete")); | |||
initCompleted = 1; | |||
@@ -130,6 +129,7 @@ public class DDSService extends Service { | |||
// DDS.getInstance().getAgent().getTTSEngine().setMode(DDSMode.TTS_SILENCE); | |||
// DDS.getInstance().getAgent().getTTSEngine().setSpeaker("zhilingfp"); | |||
DDS.getInstance().getAgent().getTTSEngine().setSpeaker("hqqiaf","hqqiaf_lstm_210909.bin"); | |||
startAsrListening(); | |||
} catch (DDSNotInitCompleteException e) { | |||
throw new RuntimeException(e); | |||
} | |||
@@ -280,15 +280,15 @@ public class DDSService extends Service { | |||
// config.addConfig(DDSConfig.K_RECORDER_MODE, "internal"); //(适配了hal之后选内部,或者不写这一条,SDK默认是内部---录音机模式:external(使用外置录音机,需主动调用拾音接口)、internal(使用内置录音机,DDS自动录音) | |||
// config.addConfig(DDSConfig.K_MIC_TYPE, 2); // (根据麦克风实际类型进行配置)设置硬件采集模组的类型 0:无。默认值。 1:单麦回消 2:线性四麦 3:环形六麦 4:车载双麦 5:家具双麦 6: 环形四麦 7: 新车载双麦 8: 线性6麦 | |||
// | |||
// config.addConfig(DDSConfig.K_USE_SSPE,"true");//如果资源是SSPE资源,则需要将此配置置为true | |||
config.addConfig(DDSConfig.K_USE_SSPE,"true");//如果资源是SSPE资源,则需要将此配置置为true | |||
// config.addConfig(DDSConfig.K_MIC_ARRAY_SSPE_BIN,"sspe_aec_ula_wkp_35mm_ch6_mic4_ref2_v2.0.0.130.bin");//SSPE资源(放在test/src/main/assert文件夹下,或放到机器上指定绝对路径)(已包含aec算法)绝对路径,请务必保证绝对路径有可读写权限 | |||
// //config.addConfig(DDSConfig.K_WAKEUP_BIN, "wakeup_s20_zhihuijingling_20230103.bin"); //商务定制版唤醒资源的路径。如果开发者对唤醒率有更高的要求,请联系商务申请定制唤醒资源。 | |||
// config.addConfig(DDSConfig.K_AEC_MODE, "internal");//AEC模式,HAL层未集成AEC算法时,选择"internal"。HAL已经集成AEC算法时,选择"external" | |||
config.addConfig(DDSConfig.K_AEC_MODE, "internal");//AEC模式,HAL层未集成AEC算法时,选择"internal"。HAL已经集成AEC算法时,选择"external" | |||
config.addConfig(DDSConfig.K_MIC_TYPE, 2); | |||
config.addConfig(DDSConfig.K_MIC_ARRAY_SSPE_BIN, "sspe_aec_ula_wkp_35mm_ch6_mic4_ref2_v2.0.0.130.bin"); | |||
// config.addConfig(DDSConfig.K_MIC_ARRAY_SSPE_BIN, "sspe_aec_ula_wkp_35mm_ch6_mic4_ref2_v2.0.0.130.bin"); | |||
// config.addConfig(DDSConfig.K_MIC_ARRAY_SSPE_BIN, "sspe_aec_ula_wkp_35mm_ch6_mic4_ref2_v2.0.0.130_post_20230530.bin"); | |||
// config.addConfig(DDSConfig.K_MIC_ARRAY_SSPE_BIN, "sspe-aec-mann-70mm-6chan-2mic-2ref-v2.0.0.127-0926-nocross-dcrn-decoderadd_20221220_aecGain4_v1.bin"); | |||
config.addConfig(DDSConfig.K_MIC_ARRAY_SSPE_BIN, "sspe-aec-mann-70mm-6chan-2mic-2ref-v2.0.0.127-0926-nocross-dcrn-decoderadd_20230714_aecGain4_v1.bin"); | |||
config.addConfig(DDSConfig.K_MIC_ECHO_CHANNEL_NUM, 2); | |||
config.addConfig(DDSConfig.K_AUDIO_SOURCE, 6); | |||
config.addConfig(DDSConfig.K_AUDIO_CHANNEL_COUNT, 6); | |||
@@ -338,64 +338,37 @@ public class DDSService extends Service { | |||
} | |||
private long mTime = 0; | |||
public void startTtsListening() { | |||
try { | |||
DDS.getInstance().getAgent().getTTSEngine().setMode(DDSMode.TTS_SILENCE); | |||
DDS.getInstance().getAgent().getTTSEngine().setListener(new TTSEngine.Callback() { | |||
@Override | |||
public void beginning(String ttsId) { | |||
Log.d(TAG, "TTS开始播报 ttsId = " + ttsId); | |||
} | |||
@Override | |||
public void received(byte[] data) { | |||
Log.d(TAG, "收到音频,此方法会回调多次,直至data为0,音频结束 data = " + data.length); | |||
String pcmData = Base64.encodeToString(data, Base64.DEFAULT); | |||
JSONObject jo = new JSONObject(); | |||
try { | |||
jo.put("type", "djTts"); | |||
jo.put("data", pcmData); | |||
WebSocketManager.getInstance(MainActivity.instance).sendMsg(jo.toString()); | |||
} catch (JSONException e) { | |||
throw new RuntimeException(e); | |||
} | |||
// File file = createFile(mTime + ".pcm"); | |||
// RandomAccessFile raf = null; | |||
// try { | |||
// raf = new RandomAccessFile(file, "rw"); | |||
// raf.seek(file.length()); | |||
// raf.write(data); | |||
// raf.close(); | |||
// } catch (IOException e) { | |||
// throw new RuntimeException(e); | |||
// } | |||
private long mAsrTime = 0; | |||
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(); | |||
} | |||
@Override | |||
public void end(String ttsId, int status) { | |||
} | |||
@Override | |||
public void error(String error) { | |||
Log.d(TAG, "出现错误," + error); | |||
if(System.currentTimeMillis() - mAsrTime > 3000){ | |||
mTime = System.currentTimeMillis(); | |||
} | |||
@Override | |||
public void phoneReturnReceived(String s) { | |||
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); | |||
} | |||
}); | |||
} catch (DDSNotInitCompleteException e) { | |||
e.printStackTrace(); | |||
} | |||
} | |||
}); | |||
} | |||
public File createFile(String name) { | |||
String dirPath = Environment.getExternalStorageDirectory().getAbsolutePath() | |||
+"/Android/data/com.aispeech.nativedemo/cache/asrCache/"; | |||
+"/Android/data/com.aispeech.nativedemo/files/asrCache/"; | |||
File file = new File(dirPath); | |||
if(!file.exists()) { | |||
file.mkdirs(); | |||
@@ -16,7 +16,7 @@ public class DigiApplication extends Application { | |||
super.onCreate(); | |||
mInstance = this; | |||
CameraController.getInstance(this); | |||
FaceManager.getInstance(this).initEngine(); | |||
FaceManager.getInstance().initEngine(); | |||
WebSocketManager.getInstance(this); | |||
DigiNetworkManager.getManager().init(this); | |||
} | |||
@@ -75,10 +75,15 @@ 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; | |||
import com.aispeech.nativedemo.entity.Emp; | |||
import com.aispeech.nativedemo.entity.Skill; | |||
import com.aispeech.nativedemo.entity.Stranger; | |||
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.log.Logger; | |||
import com.aispeech.nativedemo.mqtt.MqttManager; | |||
import com.aispeech.nativedemo.network.NetworkStatusCallback; | |||
@@ -348,14 +353,6 @@ public class MainActivity extends Activity implements DuiUpdateObserver.UpdateCa | |||
// Utils.userFaces.clear(); | |||
// SkillDbHelper.getInstance().deleteAll(); | |||
// ModelDbHelper.getInstance().deleteAll(); | |||
JSONObject jo = new JSONObject(); | |||
try { | |||
jo.put("type", "djTtsText"); | |||
jo.put("data", "缔智元是一家缔造数字人员工的科技企业,致力于综合图像识别、自然语言交互、知识图谱、超写实3D渲染、物联网等前沿技术,助力企业的数字化与智能化变革"); | |||
WebSocketManager.getInstance(MainActivity.this).sendMsg(jo.toString()); | |||
} catch (JSONException e) { | |||
throw new RuntimeException(e); | |||
} | |||
} | |||
}); | |||
startClient = findViewById(R.id.start_client); | |||
@@ -404,7 +401,7 @@ public class MainActivity extends Activity implements DuiUpdateObserver.UpdateCa | |||
private void initManager() { | |||
mWSManager = WebSocketManager.getInstance(getApplicationContext()); | |||
mFaceManager = FaceManager.getInstance(getApplicationContext()); | |||
mFaceManager = FaceManager.getInstance(); | |||
mFaceManager.setCallback(this); | |||
mCameraController = CameraController.getInstance(getApplicationContext()); | |||
mCameraController.initTexture(mTextureView); | |||
@@ -490,24 +487,24 @@ public class MainActivity extends Activity implements DuiUpdateObserver.UpdateCa | |||
mRectFaceView.setBackground(xml2); | |||
mRectFaceView.setRotationY(180); | |||
if(System.currentTimeMillis() - mDoaTime > 1000){ | |||
mDoaTime = System.currentTimeMillis(); | |||
int doa = 0; | |||
if(bd_x != 0 && bd_x > 100){ | |||
doa = 90 - (1080 - bd_x) / 25; | |||
} | |||
if(Math.abs(mDoa - doa) >= 5){ | |||
if(doa > 50 && doa < 130){ | |||
mDoa = doa; | |||
try { | |||
DDS.getInstance().getAgent().getWakeupEngine().setWakeupDoa(doa); | |||
MessageUtils.sendDoa("define", doa); | |||
} catch (DDSNotInitCompleteException e) { | |||
throw new RuntimeException(e); | |||
} | |||
} | |||
} | |||
} | |||
// if(System.currentTimeMillis() - mDoaTime > 1000){ | |||
// mDoaTime = System.currentTimeMillis(); | |||
// int doa = 0; | |||
// if(bd_x != 0 && bd_x > 100){ | |||
// doa = 90 - (1080 - bd_x) / 25; | |||
// } | |||
// if(Math.abs(mDoa - doa) >= 5){ | |||
// if(doa > 50 && doa < 130){ | |||
// mDoa = doa; | |||
// try { | |||
// DDS.getInstance().getAgent().getWakeupEngine().setWakeupDoa(doa); | |||
// MessageUtils.sendDoa("define", doa); | |||
// } catch (DDSNotInitCompleteException e) { | |||
// throw new RuntimeException(e); | |||
// } | |||
// } | |||
// } | |||
// } | |||
} | |||
}); | |||
} | |||
@@ -542,49 +539,95 @@ public class MainActivity extends Activity implements DuiUpdateObserver.UpdateCa | |||
backgroundHandler = new Handler(backgroundThread.getLooper()); | |||
updateLeFaceModel(); | |||
if (Utils.userFaces == null || Utils.userFaces.isEmpty()) { | |||
List<Emp> empList = EmpDbHelper.getInstance().getAll(); | |||
for (Emp emp : empList) { | |||
List<Emp> emps = EmpDbHelper.getInstance().getAll(); | |||
for (Emp emp : emps) { | |||
Utils.userFaces.put(emp.id + "_1", emp.dfeatures); | |||
} | |||
} | |||
if (Utils.userNewFaces == null || Utils.userNewFaces.isEmpty()) { | |||
List<Stranger> strangers = StrangerDbHelper.getInstance().getAll(); | |||
for (Stranger stranger : strangers) { | |||
Utils.userNewFaces.put(stranger.userId + "_1", stranger.faceFeatures); | |||
} | |||
} | |||
// if (Utils.userLogs == null || Utils.userLogs.isEmpty()) { | |||
// Utils.userLogs = DbHelper.Instance().loadAllLogs(); | |||
// } | |||
backgroundHandler.post(periodicDetect); | |||
} | |||
/** | |||
* 闲聊模式 | |||
*/ | |||
private final Runnable periodicDetect = new Runnable() { | |||
@Override | |||
public void run() { | |||
try { | |||
Log.e(TAG, "-----------------detect face----------------"); | |||
textureBitmap = mTextureView.getBitmap(); | |||
List<MultiAtt> results = mFaceManager.detectMultiAtt(textureBitmap); | |||
List<MultiAtt> results = FaceChatMode.detectMultiAtt(textureBitmap); | |||
if (results != null && results.size() > 0) { | |||
mFaceManager.filterPersonForFeatExtract(results); | |||
//过滤相同人物 | |||
FaceChatMode.filterPersonForFeatExtract(results, textureBitmap); | |||
//删除过期人员 | |||
mFaceManager.deleteExpirePerson(); | |||
boolean isContinue = mFaceManager.featExtract(results, textureBitmap); | |||
FaceChatMode.deleteExpirePerson(); | |||
boolean isContinue = FaceChatMode.featExtract(results, textureBitmap); | |||
if(isContinue){ | |||
// if(isInitComplete){ | |||
// DDSManager.getInstance().wakeUpDDSDialog(); | |||
// } | |||
mFaceManager.confirmCurrentPerson(textureBitmap); | |||
FaceChatMode.confirmCurrentPerson(textureBitmap); | |||
} | |||
// if(!mFaceManager.hasPerson()){ | |||
// DDSManager.getInstance().stopDDSDialog(); | |||
// } | |||
} | |||
Log.e(TAG, "---------------thread execute over-------------"); | |||
backgroundHandler.post(periodicDetect); | |||
loopDetect(); | |||
} catch (Exception e) { | |||
e.printStackTrace(); | |||
} | |||
} | |||
}; | |||
/** | |||
* 接待模式 | |||
*/ | |||
private final Runnable receptionDetect = new Runnable() { | |||
@Override | |||
public void run() { | |||
try { | |||
Log.e(TAG, "-----------------detect face----------------"); | |||
textureBitmap = mTextureView.getBitmap(); | |||
List<MultiAtt> results = FaceReceptionMode.detectMultiAtt(textureBitmap); | |||
if (results != null && results.size() > 0) { | |||
//过滤相同人物 | |||
FaceReceptionMode.filterPersonForFeatExtract(results, textureBitmap); | |||
//删除过期人员 | |||
FaceReceptionMode.deleteExpirePerson(); | |||
boolean isContinue = FaceReceptionMode.featExtract(results, textureBitmap); | |||
if(isContinue){ | |||
FaceReceptionMode.confirmCurrentWord(); | |||
} | |||
} else{ | |||
FaceReceptionMode.checkSessionExpire(false); | |||
} | |||
Log.e(TAG, "---------------thread execute over-------------"); | |||
loopDetect(); | |||
} catch (Exception e) { | |||
e.printStackTrace(); | |||
} | |||
} | |||
}; | |||
private void loopDetect(){ | |||
if(IdentityMode.MODE_CURRENT.equals(IdentityMode.MODE_CHAT)){ | |||
backgroundHandler.post(periodicDetect); | |||
} else{ | |||
backgroundHandler.post(receptionDetect); | |||
} | |||
} | |||
@Override | |||
protected void onCreate(Bundle savedInstanceState) { | |||
super.onCreate(savedInstanceState); | |||
@@ -1,21 +1,13 @@ | |||
package com.aispeech.nativedemo.asr.observer; | |||
import android.os.Environment; | |||
import android.text.TextUtils; | |||
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.DuiApplication; | |||
import com.aispeech.nativedemo.MainActivity; | |||
import com.aispeech.nativedemo.face.FaceManager; | |||
import com.aispeech.nativedemo.log.Logger; | |||
import com.aispeech.nativedemo.mqtt.MqttManager; | |||
import com.aispeech.nativedemo.network.ws.MessageUtils; | |||
import com.aispeech.nativedemo.config.Config; | |||
import com.aispeech.nativedemo.network.ws.WebSocketManager; | |||
import com.aispeech.nativedemo.shape.ShapeManager; | |||
import com.aispeech.nativedemo.widget.pageview.utils.JSONUtils; | |||
import com.google.gson.Gson; | |||
@@ -82,14 +74,7 @@ public class DuiMessageObserver implements MessageObserver { | |||
try { | |||
jsonObject.put("nlg", ""); | |||
jsonObject.put("display", ""); | |||
if (!TextUtils.isEmpty(readText)) { | |||
JSONObject jo = new JSONObject(); | |||
jo.put("type", "djTtsNlpText"); | |||
jo.put("data", readText); | |||
Logger.e("思必驰NLP结果发给叠境tts:" + readText); | |||
WebSocketManager.getInstance(MainActivity.instance).sendMsg(jo.toString()); | |||
} | |||
MessageUtils.sendTtsNlpText(readText); | |||
} catch (JSONException e) { | |||
e.printStackTrace(); | |||
} | |||
@@ -97,13 +82,7 @@ public class DuiMessageObserver implements MessageObserver { | |||
try { | |||
jsonObject.put("nlg", ""); | |||
jsonObject.put("display", ""); | |||
JSONObject jo = new JSONObject(); | |||
jo.put("type", "djTtsNlpText"); | |||
jo.put("data", readText); | |||
Logger.e("思必驰NLP结果发给叠境tts:" + readText); | |||
WebSocketManager.getInstance(MainActivity.instance).sendMsg(jo.toString()); | |||
MessageUtils.sendTtsNlpText(readText); | |||
} catch (JSONException e) { | |||
e.printStackTrace(); | |||
} | |||
@@ -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; | |||
@@ -9,15 +9,19 @@ import com.aispeech.nativedemo.DuiApplication; | |||
import com.aispeech.nativedemo.MainActivity; | |||
import com.aispeech.nativedemo.db.EmpDbHelper; | |||
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.Emp; | |||
import com.aispeech.nativedemo.entity.Icon; | |||
import com.aispeech.nativedemo.entity.Model; | |||
import com.aispeech.nativedemo.entity.Reception; | |||
import com.aispeech.nativedemo.entity.ScreenOff; | |||
import com.aispeech.nativedemo.entity.Skill; | |||
import com.aispeech.nativedemo.entity.WorkDayHour; | |||
import com.aispeech.nativedemo.entity.WorkTime; | |||
import com.aispeech.nativedemo.face.FaceReceptionMode; | |||
import com.aispeech.nativedemo.face.IdentityMode; | |||
import com.aispeech.nativedemo.log.Logger; | |||
import com.aispeech.nativedemo.network.ws.MessageUtils; | |||
import com.aispeech.nativedemo.network.ws.WebSocketManager; | |||
@@ -67,6 +71,7 @@ public class ConfigManager { | |||
heartbeat(); | |||
MessageUtils.sendRest(); | |||
checkServiceStatus(); | |||
getReception(); | |||
} | |||
}, 0, 60000); | |||
} | |||
@@ -131,7 +136,7 @@ public class ConfigManager { | |||
getModel(); | |||
} | |||
if((data & 0x1000) > 0){ | |||
getReception(); | |||
} | |||
if((data & 0x10000) > 0){ | |||
@@ -351,7 +356,58 @@ public class ConfigManager { | |||
@Override | |||
public void onFail(String error) { | |||
Log.e(TAG, "new Heartbeat = " + error); | |||
Log.e(TAG, "getModel = " + error); | |||
} | |||
}); | |||
} | |||
private void getReception() { | |||
HashMap<String, String> map = new HashMap<>(); | |||
map.put("id", "123456"); | |||
map.put("devId", Build.SERIAL); | |||
map.put("type", "3"); | |||
map.put("sign", "123456"); | |||
map.put("enterpriseName", "administrator"); | |||
map.put("timestamp", "1"); | |||
RequestBody requestBody = RequestBody.create(MediaType.parse("application/json"), new JSONObject(map).toString()); | |||
HttpUtil.post(Config.CURRENT_URL + "message/api/update", requestBody, null, new HttpUtil.HttpCallback<String>() { | |||
@Override | |||
public void onSuccess(String success) { | |||
Log.e(TAG, "getReception = " + success); | |||
try { | |||
JSONTokener t = new JSONTokener(success); | |||
JSONObject obj = (JSONObject) t.nextValue(); | |||
int code = 0; | |||
if (obj.has("code")) { | |||
code = obj.getInt("code"); | |||
} | |||
if (code == 200) { | |||
// MessageUtils.sendMessage("接待任务:" + success); | |||
if (obj.has("data")) { | |||
JSONObject object = obj.getJSONObject("data"); | |||
Reception reception = new Reception(); | |||
reception.create(object); | |||
ReceptionDbHelper.getInstance().add(reception); | |||
if(IdentityMode.MODE_CURRENT.equals(IdentityMode.MODE_RECEPTION)){ | |||
FaceReceptionMode.mReception = reception; | |||
} | |||
// if (obj.has("timestamp")) { | |||
// mUserTimeStamp = obj.optLong("timestamp"); | |||
// } | |||
} | |||
} else { | |||
onFail(obj.getString("msg")); | |||
} | |||
} catch (Exception e) { | |||
e.printStackTrace(); | |||
onFail(e.getMessage()); | |||
} | |||
} | |||
@Override | |||
public void onFail(String error) { | |||
Log.e(TAG, "getReception = " + error); | |||
} | |||
}); | |||
} | |||
@@ -17,9 +17,12 @@ public class DatabaseImpl extends SQLiteOpenHelper { | |||
private static final String DB_NAME = "digital_man"; | |||
public static final String TABLE_INITIALIZE = "initialize"; //初始化表 | |||
public static final String TABLE_EMP = "user_faces"; //员工表 | |||
public static final String TABLE_STRANGER = "new_user_faces"; //陌生人表 | |||
public static final String TABLE_SKILL = "skill"; //员工表 | |||
public static final String TABLE_MODEL = "model"; //员工表 | |||
public static final String TABLE_UPGRADE = "upgrade"; //软件升级表 | |||
public static final String TABLE_RECEPTION = "reception"; //接待任务表 | |||
public static final String TABLE_SETTING = "setting"; //设置表 | |||
public DatabaseImpl(Context context, String name, CursorFactory factory, int version) { | |||
super(context, name, factory, version); | |||
@@ -0,0 +1,57 @@ | |||
package com.aispeech.nativedemo.db; | |||
import android.content.ContentValues; | |||
import android.database.Cursor; | |||
import com.aispeech.nativedemo.entity.Reception; | |||
import java.util.Collections; | |||
public class ReceptionBuilder implements DatabaseBuilder<Reception>{ | |||
@Override | |||
public Reception build(Cursor query) { | |||
Reception reception = new Reception(); | |||
reception.name = (query.getString(query.getColumnIndex("name"))); | |||
reception.date = (query.getString(query.getColumnIndex("date"))); | |||
String guideStr = (query.getString(query.getColumnIndex("guide"))); | |||
Collections.addAll(reception.guide,guideStr.split(",")); | |||
String firstStr = (query.getString(query.getColumnIndex("first"))); | |||
Collections.addAll(reception.first,firstStr.split(",")); | |||
String secondStr = (query.getString(query.getColumnIndex("second"))); | |||
Collections.addAll(reception.second,secondStr.split(",")); | |||
String thirdStr = (query.getString(query.getColumnIndex("third"))); | |||
Collections.addAll(reception.third,thirdStr.split(",")); | |||
reception.underpinWord = (query.getString(query.getColumnIndex("underpin_word"))); | |||
return reception; | |||
} | |||
@Override | |||
public ContentValues deconstruct(Reception reception) { | |||
ContentValues contentValues = new ContentValues(); | |||
contentValues.put("name",reception.name); | |||
contentValues.put("date",reception.date); | |||
StringBuilder builder = new StringBuilder(); | |||
for(String str : reception.guide){ | |||
builder.append(str).append(","); | |||
} | |||
contentValues.put("guide",builder.toString()); | |||
builder = new StringBuilder(); | |||
for(String str : reception.first){ | |||
builder.append(str).append(","); | |||
} | |||
contentValues.put("first",builder.toString()); | |||
builder = new StringBuilder(); | |||
for(String str : reception.second){ | |||
builder.append(str).append(","); | |||
} | |||
contentValues.put("second",builder.toString()); | |||
builder = new StringBuilder(); | |||
for(String str : reception.third){ | |||
builder.append(str).append(","); | |||
} | |||
contentValues.put("third",builder.toString()); | |||
contentValues.put("underpin_word",reception.underpinWord); | |||
return contentValues; | |||
} | |||
} |
@@ -0,0 +1,112 @@ | |||
package com.aispeech.nativedemo.db; | |||
import android.content.ContentValues; | |||
import android.database.Cursor; | |||
import android.database.sqlite.SQLiteDatabase; | |||
import com.aispeech.nativedemo.entity.Reception; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
public class ReceptionDbHelper extends IDbHelper<Reception> { | |||
private static ReceptionDbHelper mHelper; | |||
private ReceptionDbHelper() { | |||
} | |||
public static ReceptionDbHelper getInstance() { | |||
if (mHelper == null) | |||
mHelper = new ReceptionDbHelper(); | |||
return mHelper; | |||
} | |||
@Override | |||
public void add(Reception reception) { | |||
if(has(reception)){ | |||
update(reception); | |||
} else{ | |||
SQLiteDatabase db = DatabaseImpl.getDatabase().getDb(); | |||
ContentValues values = new ReceptionBuilder().deconstruct(reception); | |||
db.insert(DatabaseImpl.TABLE_RECEPTION, null, values); | |||
} | |||
} | |||
@Override | |||
public void delete(Reception reception) { | |||
SQLiteDatabase db = DatabaseImpl.getDatabase().getDb(); | |||
db.delete(DatabaseImpl.TABLE_RECEPTION, "name =?", new String[]{reception.name}); | |||
} | |||
public void deleteAll() { | |||
SQLiteDatabase db = DatabaseImpl.getDatabase().getDb(); | |||
db.execSQL("delete from reception"); | |||
} | |||
@Override | |||
public void update(Reception reception) { | |||
SQLiteDatabase db = DatabaseImpl.getDatabase().getDb(); | |||
ContentValues values = new ReceptionBuilder().deconstruct(reception); | |||
db.update(DatabaseImpl.TABLE_RECEPTION, values, "name = ?", new String[]{reception.name}); | |||
} | |||
@Override | |||
public Reception get(Object name) { | |||
SQLiteDatabase database = null; | |||
Cursor cursor = null; | |||
try { | |||
database = DatabaseImpl.getDatabase().getDb(); | |||
cursor = database.rawQuery("select * from reception where name = ?", new String[]{(String)name}); | |||
while (cursor.moveToNext()) { | |||
Reception reception = new ReceptionBuilder().build(cursor); | |||
return reception; | |||
} | |||
} catch (Exception e) { | |||
e.printStackTrace(); | |||
} finally { | |||
if (cursor != null) | |||
cursor.close(); | |||
} | |||
return null; | |||
} | |||
@Override | |||
public List<Reception> getAll() { | |||
SQLiteDatabase database = null; | |||
List<Reception> receptionList = new ArrayList<>(); | |||
Cursor cursor = null; | |||
try { | |||
database = DatabaseImpl.getDatabase().getDb(); | |||
cursor = database.rawQuery("select * from reception", new String[]{}); | |||
while (cursor.moveToNext()) { | |||
Reception reception = new ReceptionBuilder().build(cursor); | |||
receptionList.add(reception); | |||
} | |||
} catch (Exception e) { | |||
e.printStackTrace(); | |||
} finally { | |||
if (cursor != null) | |||
cursor.close(); | |||
} | |||
return receptionList; | |||
} | |||
@Override | |||
public boolean has(Reception reception) { | |||
SQLiteDatabase database = null; | |||
Cursor cursor = null; | |||
try { | |||
database = DatabaseImpl.getDatabase().getDb(); | |||
cursor = database.rawQuery("select * from reception where name = ?", | |||
new String[]{String.valueOf(reception.name)}); | |||
return cursor.getCount() > 0; | |||
} catch (Exception e) { | |||
e.printStackTrace(); | |||
} finally { | |||
if (cursor != null) | |||
cursor.close(); | |||
} | |||
return false; | |||
} | |||
} |
@@ -0,0 +1,28 @@ | |||
package com.aispeech.nativedemo.db; | |||
import android.content.ContentValues; | |||
import android.database.Cursor; | |||
import com.aispeech.nativedemo.entity.Reception; | |||
import com.aispeech.nativedemo.entity.Setting; | |||
import java.util.Collections; | |||
public class SettingBuilder implements DatabaseBuilder<Setting>{ | |||
@Override | |||
public Setting build(Cursor query) { | |||
Setting setting = new Setting(); | |||
setting.isReceptionMode = (query.getInt(query.getColumnIndex("is_reception_mode"))); | |||
setting.hbUpdateTime = (query.getLong(query.getColumnIndex("hb_update_time"))); | |||
return setting; | |||
} | |||
@Override | |||
public ContentValues deconstruct(Setting setting) { | |||
ContentValues contentValues = new ContentValues(); | |||
contentValues.put("is_reception_mode",setting.isReceptionMode); | |||
contentValues.put("hb_update_time",setting.hbUpdateTime); | |||
return contentValues; | |||
} | |||
} |
@@ -0,0 +1,107 @@ | |||
package com.aispeech.nativedemo.db; | |||
import android.content.ContentValues; | |||
import android.database.Cursor; | |||
import android.database.sqlite.SQLiteDatabase; | |||
import com.aispeech.nativedemo.entity.Setting; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
public class SettingDbHelper extends IDbHelper<Setting> { | |||
private static SettingDbHelper mHelper; | |||
private SettingDbHelper() { | |||
} | |||
public static SettingDbHelper getInstance() { | |||
if (mHelper == null) | |||
mHelper = new SettingDbHelper(); | |||
return mHelper; | |||
} | |||
@Override | |||
public void add(Setting setting) { | |||
if(has(setting)){ | |||
update(setting); | |||
} else{ | |||
SQLiteDatabase db = DatabaseImpl.getDatabase().getDb(); | |||
ContentValues values = new SettingBuilder().deconstruct(setting); | |||
db.insert(DatabaseImpl.TABLE_SETTING, null, values); | |||
} | |||
} | |||
@Override | |||
public void delete(Setting setting) { | |||
SQLiteDatabase db = DatabaseImpl.getDatabase().getDb(); | |||
db.delete(DatabaseImpl.TABLE_SETTING, "id =?", new String[]{String.valueOf(setting.id)}); | |||
} | |||
@Override | |||
public void update(Setting setting) { | |||
SQLiteDatabase db = DatabaseImpl.getDatabase().getDb(); | |||
ContentValues values = new SettingBuilder().deconstruct(setting); | |||
db.update(DatabaseImpl.TABLE_SETTING, values, "id = ?", new String[]{String.valueOf(setting.id)}); | |||
} | |||
@Override | |||
public Setting get(Object id) { | |||
SQLiteDatabase database = null; | |||
Cursor cursor = null; | |||
try { | |||
database = DatabaseImpl.getDatabase().getDb(); | |||
cursor = database.rawQuery("select * from setting where id = ?", new String[]{(String) id}); | |||
while (cursor.moveToNext()) { | |||
Setting setting = new SettingBuilder().build(cursor); | |||
return setting; | |||
} | |||
} catch (Exception e) { | |||
e.printStackTrace(); | |||
} finally { | |||
if (cursor != null) | |||
cursor.close(); | |||
} | |||
return null; | |||
} | |||
@Override | |||
public List<Setting> getAll() { | |||
SQLiteDatabase database = null; | |||
List<Setting> settingList = new ArrayList<>(); | |||
Cursor cursor = null; | |||
try { | |||
database = DatabaseImpl.getDatabase().getDb(); | |||
cursor = database.rawQuery("select * from setting", new String[]{}); | |||
while (cursor.moveToNext()) { | |||
Setting setting = new SettingBuilder().build(cursor); | |||
settingList.add(setting); | |||
} | |||
} catch (Exception e) { | |||
e.printStackTrace(); | |||
} finally { | |||
if (cursor != null) | |||
cursor.close(); | |||
} | |||
return settingList; | |||
} | |||
@Override | |||
public boolean has(Setting setting) { | |||
SQLiteDatabase database = null; | |||
Cursor cursor = null; | |||
try { | |||
database = DatabaseImpl.getDatabase().getDb(); | |||
cursor = database.rawQuery("select * from setting where id = ?", | |||
new String[]{String.valueOf(setting.id)}); | |||
return cursor.getCount() > 0; | |||
} catch (Exception e) { | |||
e.printStackTrace(); | |||
} finally { | |||
if (cursor != null) | |||
cursor.close(); | |||
} | |||
return false; | |||
} | |||
} |
@@ -0,0 +1,37 @@ | |||
package com.aispeech.nativedemo.db; | |||
import android.content.ContentValues; | |||
import android.database.Cursor; | |||
import com.aispeech.nativedemo.entity.Emp; | |||
import com.aispeech.nativedemo.entity.Stranger; | |||
import com.aispeech.nativedemo.utils.Utils; | |||
public class StrangerBuilder implements DatabaseBuilder<Stranger>{ | |||
@Override | |||
public Stranger build(Cursor query) { | |||
Stranger stranger = new Stranger(); | |||
stranger.id = (query.getString(query.getColumnIndex("id"))); | |||
stranger.userId = (query.getString(query.getColumnIndex("user_id"))); | |||
stranger.nickName = (query.getString(query.getColumnIndex("user_name"))); | |||
stranger.tag = (query.getString(query.getColumnIndex("tag"))); | |||
stranger.gender = (query.getInt(query.getColumnIndex("gender"))); | |||
stranger.timestamp = (query.getLong(query.getColumnIndex("timestamp"))); | |||
stranger.faceFeatures = Utils.ByteArrayToFloatArray(query.getBlob(query.getColumnIndex("face_feature"))); | |||
return stranger; | |||
} | |||
@Override | |||
public ContentValues deconstruct(Stranger stranger) { | |||
ContentValues contentValues = new ContentValues(); | |||
contentValues.put("id",stranger.id); | |||
contentValues.put("user_id",stranger.userId); | |||
contentValues.put("user_name",stranger.nickName); | |||
contentValues.put("tag",stranger.tag); | |||
contentValues.put("gender",stranger.gender); | |||
contentValues.put("timestamp",stranger.timestamp); | |||
contentValues.put("face_feature",Utils.FloatArrayToByteArray(stranger.faceFeatures)); | |||
return contentValues; | |||
} | |||
} |
@@ -0,0 +1,112 @@ | |||
package com.aispeech.nativedemo.db; | |||
import android.content.ContentValues; | |||
import android.database.Cursor; | |||
import android.database.sqlite.SQLiteDatabase; | |||
import com.aispeech.nativedemo.entity.Stranger; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
public class StrangerDbHelper extends IDbHelper<Stranger> { | |||
private static StrangerDbHelper mHelper; | |||
private StrangerDbHelper() { | |||
} | |||
public static StrangerDbHelper getInstance() { | |||
if (mHelper == null) | |||
mHelper = new StrangerDbHelper(); | |||
return mHelper; | |||
} | |||
@Override | |||
public void add(Stranger stranger) { | |||
if(has(stranger)){ | |||
update(stranger); | |||
} else{ | |||
SQLiteDatabase db = DatabaseImpl.getDatabase().getDb(); | |||
ContentValues values = new StrangerBuilder().deconstruct(stranger); | |||
db.insert(DatabaseImpl.TABLE_STRANGER, null, values); | |||
} | |||
} | |||
@Override | |||
public void delete(Stranger stranger) { | |||
SQLiteDatabase db = DatabaseImpl.getDatabase().getDb(); | |||
db.delete(DatabaseImpl.TABLE_STRANGER, "user_id =?", new String[]{stranger.userId}); | |||
} | |||
public void deleteAll() { | |||
SQLiteDatabase db = DatabaseImpl.getDatabase().getDb(); | |||
db.execSQL("delete from new_user_faces"); | |||
} | |||
@Override | |||
public void update(Stranger stranger) { | |||
SQLiteDatabase db = DatabaseImpl.getDatabase().getDb(); | |||
ContentValues values = new StrangerBuilder().deconstruct(stranger); | |||
db.update(DatabaseImpl.TABLE_STRANGER, values, "user_id = ?", new String[]{stranger.id}); | |||
} | |||
@Override | |||
public Stranger get(Object userId) { | |||
SQLiteDatabase database = null; | |||
Cursor cursor = null; | |||
try { | |||
database = DatabaseImpl.getDatabase().getDb(); | |||
cursor = database.rawQuery("select * from new_user_faces where user_id = ?", new String[]{(String)userId}); | |||
while (cursor.moveToNext()) { | |||
Stranger stranger = new StrangerBuilder().build(cursor); | |||
return stranger; | |||
} | |||
} catch (Exception e) { | |||
e.printStackTrace(); | |||
} finally { | |||
if (cursor != null) | |||
cursor.close(); | |||
} | |||
return null; | |||
} | |||
@Override | |||
public List<Stranger> getAll() { | |||
SQLiteDatabase database = null; | |||
List<Stranger> strangerList = new ArrayList<>(); | |||
Cursor cursor = null; | |||
try { | |||
database = DatabaseImpl.getDatabase().getDb(); | |||
cursor = database.rawQuery("select * from new_user_faces", new String[]{}); | |||
while (cursor.moveToNext()) { | |||
Stranger stranger = new StrangerBuilder().build(cursor); | |||
strangerList.add(stranger); | |||
} | |||
} catch (Exception e) { | |||
e.printStackTrace(); | |||
} finally { | |||
if (cursor != null) | |||
cursor.close(); | |||
} | |||
return strangerList; | |||
} | |||
@Override | |||
public boolean has(Stranger stranger) { | |||
SQLiteDatabase database = null; | |||
Cursor cursor = null; | |||
try { | |||
database = DatabaseImpl.getDatabase().getDb(); | |||
cursor = database.rawQuery("select * from new_user_faces where eid = ?", | |||
new String[]{String.valueOf(stranger.id)}); | |||
return cursor.getCount() > 0; | |||
} catch (Exception e) { | |||
e.printStackTrace(); | |||
} finally { | |||
if (cursor != null) | |||
cursor.close(); | |||
} | |||
return false; | |||
} | |||
} |
@@ -1,7 +1,6 @@ | |||
package com.aispeech.nativedemo.dds; | |||
import android.app.Activity; | |||
import android.content.Context; | |||
import android.text.TextUtils; | |||
import android.util.Log; | |||
@@ -12,8 +11,8 @@ import com.aispeech.dui.dds.exceptions.DDSNotInitCompleteException; | |||
import com.aispeech.nativedemo.MainActivity; | |||
import com.aispeech.nativedemo.R; | |||
import com.aispeech.nativedemo.asr.observer.DuiMessageObserver; | |||
import com.aispeech.nativedemo.config.Config; | |||
import com.aispeech.nativedemo.log.Logger; | |||
import com.aispeech.nativedemo.network.ws.MessageUtils; | |||
import com.aispeech.nativedemo.network.ws.WebSocketManager; | |||
import org.json.JSONException; | |||
@@ -102,21 +101,16 @@ public class DDSManager { | |||
public void speakText(String text){ | |||
synchronized (lock){ | |||
try { | |||
// try { | |||
// if (!DuiMessageObserver.mIsSleep) { | |||
// DDS.getInstance().getAgent().stopDialog(); | |||
// } | |||
// DDS.getInstance().getAgent().avatarClick(text); | |||
// DDS.getInstance().getAgent().sendText(""); | |||
if(!TextUtils.isEmpty(text)){ | |||
JSONObject jo = new JSONObject(); | |||
jo.put("type", "djTtsText"); | |||
jo.put("data", text); | |||
WebSocketManager.getInstance(MainActivity.instance).sendMsg(jo.toString()); | |||
} | |||
} catch (JSONException e) { | |||
throw new RuntimeException(e); | |||
} | |||
// } catch (DDSNotInitCompleteException e) { | |||
// throw new RuntimeException(e); | |||
// } | |||
MessageUtils.sendTtsText(text); | |||
} | |||
} | |||
@@ -1,5 +1,6 @@ | |||
package com.aispeech.nativedemo.entity; | |||
import android.graphics.Bitmap; | |||
import android.os.SystemClock; | |||
import com.lenovo.lefacesdk.MultiAtt; | |||
@@ -20,6 +21,8 @@ public class PersonInfo { | |||
public MultiAtt result; | |||
public int faceWidth; //x值 | |||
public int times; | |||
public Bitmap bitmap; | |||
public float[] dfeatures; | |||
public PersonInfo(){ | |||
@@ -0,0 +1,60 @@ | |||
package com.aispeech.nativedemo.entity; | |||
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 Reception implements Serializable { | |||
public String name; //接待任务名称 | |||
public String date; //接待日期 | |||
public List<String> guide; //负责人 | |||
public List<String> first; //第一优先级 | |||
public List<String> second; //第二优先级 | |||
public List<String> third; //第三优先级 | |||
public String underpinWord; //托底话术 | |||
public Reception(){ | |||
guide = new ArrayList<>(); | |||
first = new ArrayList<>(); | |||
second = new ArrayList<>(); | |||
third = new ArrayList<>(); | |||
} | |||
public Reception create(JSONObject object){ | |||
try { | |||
this.name = object.optString("name"); | |||
this.date = object.optString("date"); | |||
if(object.has("guide")){ | |||
JSONArray guideArray = object.getJSONArray("guide"); | |||
for (int i = 0; i < guideArray.length(); i++) { | |||
guide.add(guideArray.getString(i)); | |||
} | |||
} | |||
if(object.has("first")){ | |||
JSONArray firstArray = object.getJSONArray("first"); | |||
for (int i = 0; i < firstArray.length(); i++) { | |||
first.add(firstArray.getString(i)); | |||
} | |||
} | |||
if(object.has("second")){ | |||
JSONArray secondArray = object.getJSONArray("second"); | |||
for (int i = 0; i < secondArray.length(); i++) { | |||
second.add(secondArray.getString(i)); | |||
} | |||
} | |||
if(object.has("third")){ | |||
JSONArray thirdArray = object.getJSONArray("third"); | |||
for (int i = 0; i < thirdArray.length(); i++) { | |||
second.add(thirdArray.getString(i)); | |||
} | |||
} | |||
} catch (JSONException e) { | |||
throw new RuntimeException(e); | |||
} | |||
return this; | |||
} | |||
} |
@@ -0,0 +1,9 @@ | |||
package com.aispeech.nativedemo.entity; | |||
import java.io.Serializable; | |||
public class Setting implements Serializable { | |||
public int id; | |||
public int isReceptionMode; //接待模式 1.是 0.否 | |||
public long hbUpdateTime; //心跳更新时间戳 | |||
} |
@@ -0,0 +1,35 @@ | |||
package com.aispeech.nativedemo.entity; | |||
import androidx.annotation.NonNull; | |||
import org.json.JSONException; | |||
import org.json.JSONObject; | |||
import java.io.Serializable; | |||
public class Stranger implements Serializable { | |||
public String id; | |||
public String userId; | |||
public String nickName; | |||
public String tag; | |||
public int gender; | |||
public long timestamp; | |||
public float[] faceFeatures; | |||
@NonNull | |||
@Override | |||
public String toString() { | |||
JSONObject object = new JSONObject(); | |||
try { | |||
object.put("id", id); | |||
object.put("userId", userId); | |||
object.put("nickName", nickName); | |||
object.put("tag", tag); | |||
object.put("gender", gender); | |||
object.put("timestamp", gender); | |||
} catch (JSONException e) { | |||
throw new RuntimeException(e); | |||
} | |||
return object.toString(); | |||
} | |||
} |
@@ -0,0 +1,67 @@ | |||
package com.aispeech.nativedemo.entity; | |||
import android.graphics.Bitmap; | |||
import com.lenovo.lefacesdk.MultiAtt; | |||
import org.json.JSONException; | |||
import org.json.JSONObject; | |||
public class Vip { | |||
public String id; | |||
public String name; //昵称 | |||
public String tag; //人物类别 | |||
public int gender; | |||
public int trackId; | |||
public float score; //人像对比得分 | |||
public long startTime; //识别结果时间 | |||
public long updateTime; //识别更新时间 | |||
public long candidateTime; //候选时间 | |||
public MultiAtt result; | |||
public int faceWidth; //x值 | |||
public int times; | |||
public Bitmap bitmap; | |||
public float[] dfeatures; | |||
public boolean isGreet; | |||
public Vip(){ | |||
} | |||
public Vip(String id, String name, String tag, int times, int gender, int trackId, float score, MultiAtt att){ | |||
this.id = id; | |||
this.name = name; | |||
this.tag = tag; | |||
this.times = times; | |||
this.gender = gender; | |||
this.trackId = trackId; | |||
this.score = score; | |||
this.result = att; | |||
this.startTime = this.updateTime = System.currentTimeMillis(); | |||
this.faceWidth = result.fa_w; | |||
} | |||
public boolean isStranger(){ | |||
return id.equals("-2"); | |||
} | |||
public String toString(){ | |||
try { | |||
JSONObject obj = new JSONObject(); | |||
obj.put("id", id); | |||
obj.put("name", name); | |||
obj.put("tag", tag); | |||
obj.put("gender", gender); | |||
obj.put("trackId", trackId); | |||
obj.put("score", score); | |||
obj.put("fa_x", (result.fa_x1 + result.fa_x2) / 2); | |||
obj.put("bd_x", (result.bd_x1 + result.bd_x2) / 2); | |||
long time = System.currentTimeMillis(); | |||
obj.put("ts", time / 1000 + "." + time % 1000); | |||
return obj.toString(); | |||
} catch (JSONException e) { | |||
e.printStackTrace(); | |||
} | |||
return super.toString(); | |||
} | |||
} |
@@ -0,0 +1,780 @@ | |||
package com.aispeech.nativedemo.face; | |||
import android.graphics.Bitmap; | |||
import android.os.Build; | |||
import android.text.TextUtils; | |||
import android.util.Log; | |||
import com.aispeech.nativedemo.DuiApplication; | |||
import com.aispeech.nativedemo.asr.observer.DuiMessageObserver; | |||
import com.aispeech.nativedemo.config.Config; | |||
import com.aispeech.nativedemo.db.EmpDbHelper; | |||
import com.aispeech.nativedemo.db.ModelDbHelper; | |||
import com.aispeech.nativedemo.db.SkillDbHelper; | |||
import com.aispeech.nativedemo.db.StrangerDbHelper; | |||
import com.aispeech.nativedemo.entity.Emp; | |||
import com.aispeech.nativedemo.entity.Model; | |||
import com.aispeech.nativedemo.entity.PersonInfo; | |||
import com.aispeech.nativedemo.entity.Skill; | |||
import com.aispeech.nativedemo.entity.Stranger; | |||
import com.aispeech.nativedemo.log.Logger; | |||
import com.aispeech.nativedemo.network.ws.MessageUtils; | |||
import com.aispeech.nativedemo.utils.BmpCompressUtils; | |||
import com.aispeech.nativedemo.utils.HttpUtil; | |||
import com.aispeech.nativedemo.utils.Utils; | |||
import com.lenovo.lefacesdk.IdentificationResult; | |||
import com.lenovo.lefacesdk.MultiAtt; | |||
import org.json.JSONArray; | |||
import org.json.JSONException; | |||
import org.json.JSONObject; | |||
import org.json.JSONTokener; | |||
import java.text.SimpleDateFormat; | |||
import java.util.ArrayList; | |||
import java.util.Date; | |||
import java.util.HashMap; | |||
import java.util.Iterator; | |||
import java.util.List; | |||
import java.util.Map; | |||
import java.util.Optional; | |||
import java.util.Set; | |||
import java.util.concurrent.atomic.AtomicReference; | |||
import java.util.function.Consumer; | |||
import java.util.stream.Stream; | |||
import cz.msebera.android.httpclient.extras.Base64; | |||
import okhttp3.MediaType; | |||
import okhttp3.RequestBody; | |||
public class FaceChatMode { | |||
private static final String TAG = "FaceChatMode"; | |||
private static Map<String, PersonInfo> mPersons = new HashMap<>(); | |||
private static Map<Integer, PersonInfo> mUndeterminedPersons = new HashMap<>(); | |||
private static PersonInfo mSelectPerson = null; | |||
private static boolean isContainSelectPerson = false; | |||
public static long mInterval = 0; | |||
public static List<MultiAtt> detectMultiAtt(Bitmap textureBitmap) { | |||
if(mInterval == 0){ | |||
mInterval = System.currentTimeMillis(); | |||
} | |||
return FaceManager.getInstance().detectMultiAtt(textureBitmap); | |||
} | |||
public static boolean featExtract(List<MultiAtt> results, Bitmap textureBitmap) { | |||
List<float[]> employeeList = FaceManager.getInstance().featExtract(results, textureBitmap); | |||
isContainSelectPerson = false; | |||
for (int j = 0; j < employeeList.size(); j++) { | |||
float[] feat = employeeList.get(j); | |||
if(feat.length != 256){ | |||
continue; | |||
} | |||
PersonInfo person = identifyFace(feat, results.get(j)); | |||
if(person != null){ | |||
person.dfeatures = feat; | |||
person.bitmap = textureBitmap; | |||
Logger.e("识别对象为:" + person.name); | |||
if(mSelectPerson != null && person.id.equals(mSelectPerson.id)){ | |||
isContainSelectPerson = true; | |||
} | |||
if(person.id.equals("-2")){ //添加识别条件 人脸质量高和识别置信度底 | |||
if(mUndeterminedPersons.containsKey(person.trackId)){ | |||
PersonInfo origin = mUndeterminedPersons.get(person.trackId); | |||
origin.updateTime = System.currentTimeMillis(); | |||
origin.result = person.result; | |||
origin.faceWidth = person.faceWidth; | |||
origin.bitmap = person.bitmap; | |||
mUndeterminedPersons.put(person.trackId, origin); | |||
} else{ | |||
mUndeterminedPersons.put(person.trackId, person); | |||
} | |||
} else{ | |||
//已经认出人的处理 | |||
if(mPersons.containsKey(person.id)){ | |||
PersonInfo origin = mPersons.get(person.id); | |||
origin.updateTime = System.currentTimeMillis(); | |||
origin.result = person.result; | |||
origin.faceWidth = person.faceWidth; | |||
origin.bitmap = person.bitmap; | |||
mPersons.put(person.id, origin); | |||
} else{ | |||
mPersons.put(person.id, person); | |||
} | |||
// | |||
if(mUndeterminedPersons.containsKey(person.trackId)){ | |||
mUndeterminedPersons.remove(person.trackId); | |||
} | |||
} | |||
} | |||
} | |||
if(System.currentTimeMillis() - mInterval < 1000){ | |||
return false; | |||
} | |||
// sendStrangerToServer(); | |||
mInterval = System.currentTimeMillis(); | |||
return true; | |||
} | |||
//过滤人物 | |||
public static void filterPersonForFeatExtract(List<MultiAtt> results, Bitmap textureBitmap){ | |||
filterExactLyFace(results, textureBitmap); | |||
filterUndeterminedFace(results, textureBitmap); | |||
} | |||
public static void confirmCurrentPerson(Bitmap textureBitmap){ | |||
if(mPersons.size() == 0 && mUndeterminedPersons.size() == 0){ | |||
return; | |||
} | |||
//第二阶段 判断当前人 | |||
if(mSelectPerson == null){ | |||
if(mPersons.size() == 0){ | |||
if(mUndeterminedPersons.size() > 0){ | |||
//选择未确定脸大的人 | |||
mSelectPerson = selectUnknownMaxFacePerson(mUndeterminedPersons); | |||
sendMsgAndLog(textureBitmap); | |||
} | |||
return; | |||
} else{ | |||
mSelectPerson = selectKnownMaxTagAndFacePerson(); | |||
} | |||
return; | |||
} | |||
//当前选择人不为空 | |||
// filterHighLevelAndMaxFaceId(); //选出预选人 未确定face大 已确定身份高face大 | |||
selectCandidate(mSelectPerson.faceWidth); | |||
Stream<PersonInfo> pInfos = mCandidates.stream().filter(item->System.currentTimeMillis() - item.candidateTime >= CANDIDATE_STAY_TIME); | |||
Map<String,PersonInfo> candidatesKnown = new HashMap<>(); | |||
Map<Integer,PersonInfo> candidatesUnknown = new HashMap<>(); | |||
pInfos.forEach(new Consumer<PersonInfo>() { | |||
@Override | |||
public void accept(PersonInfo personInfo) { | |||
if(personInfo.isStranger()){ | |||
candidatesUnknown.put(personInfo.trackId, personInfo); | |||
} else{ | |||
candidatesKnown.put(personInfo.id, personInfo); | |||
} | |||
} | |||
}); | |||
if(candidatesKnown.size() == 0){ | |||
if(candidatesUnknown.size() > 0){ | |||
mSelectPerson = selectUnknownMaxFacePerson(candidatesUnknown); | |||
} | |||
} else{ | |||
int maxTag = selectPersonMaxTag(candidatesKnown); | |||
mSelectPerson = filterHighLevelAndMaxFacePerson(candidatesKnown, maxTag); | |||
} | |||
sendMsgAndLog(textureBitmap); | |||
} | |||
private static PersonInfo selectKnownMaxTagAndFacePerson(){ | |||
int maxTag = selectPersonMaxTag(mPersons); | |||
return filterHighLevelAndMaxFacePerson(mPersons, maxTag); | |||
// sendMsgAndLog(textureBitmap); | |||
} | |||
private static List<PersonInfo> mCandidates = new ArrayList<>(); | |||
/** | |||
* 选择候选人 | |||
* @param faceSize | |||
*/ | |||
private static void selectCandidate(int faceSize){ | |||
//TODO 过期处理 | |||
List<PersonInfo> candidates = new ArrayList<>(); | |||
long time = System.currentTimeMillis(); | |||
mPersons.forEach((key, value) -> { | |||
if(value.faceWidth - faceSize > FACE_DIFF){ | |||
Optional<PersonInfo> pInfo = mCandidates.stream().filter(item->item.id.equals(key)).findFirst(); | |||
if(pInfo.isPresent()){ | |||
value.candidateTime = pInfo.get().candidateTime; | |||
} else{ | |||
value.candidateTime = time; | |||
} | |||
candidates.add(value); | |||
} | |||
}); | |||
mUndeterminedPersons.forEach((key, value) -> { | |||
if(value.isStranger() && value.faceWidth - faceSize > FACE_DIFF){ | |||
Optional<PersonInfo> pInfo = mCandidates.stream().filter(item->item.trackId == key).findFirst(); | |||
if(pInfo.isPresent()){ | |||
value.candidateTime = pInfo.get().candidateTime; | |||
} else{ | |||
value.candidateTime = time; | |||
} | |||
candidates.add(value); | |||
} | |||
}); | |||
mCandidates.clear(); | |||
mCandidates = candidates; | |||
} | |||
private static int selectPersonMaxTag(Map<String, PersonInfo> persons){ | |||
AtomicReference<Integer> maxTag = new AtomicReference<>(100); | |||
persons.forEach((key, value) -> { | |||
int mTag = Integer.parseInt(value.tag); | |||
if (mTag == 9) { //重要贵宾 | |||
maxTag.set(mTag); | |||
} else { | |||
if (maxTag.get() != 9) { | |||
if (mTag < maxTag.get()) { | |||
maxTag.set(mTag); | |||
} | |||
} | |||
} | |||
}); | |||
return maxTag.get(); | |||
} | |||
/** | |||
* 获取脸大的人 | |||
* @return | |||
*/ | |||
private static PersonInfo selectUnknownMaxFacePerson(Map<Integer, PersonInfo> persons){ | |||
// 筛选脸大的人 | |||
if(persons == null || persons.size() == 0){ | |||
return null; | |||
} | |||
AtomicReference<Integer> trackId = new AtomicReference<>(-1); | |||
AtomicReference<Integer> maxFace = new AtomicReference<>(0); | |||
persons.forEach((key, value) -> { | |||
if(value.faceWidth > maxFace.get()){ | |||
maxFace.set(value.faceWidth); | |||
trackId.set(key); | |||
} | |||
}); | |||
return persons.get(trackId.get()); | |||
} | |||
private static void filterExactLyFace(List<MultiAtt> results,Bitmap textureBitmap){ //判断在认识人列表中是否存在 | |||
Iterator<MultiAtt> it = results.iterator(); | |||
while(it.hasNext()){ | |||
//查找已有列表中是否这人 | |||
MultiAtt att = it.next(); | |||
for (Map.Entry<String, PersonInfo> entry : mPersons.entrySet()) { | |||
String key = entry.getKey(); | |||
PersonInfo value = entry.getValue(); | |||
if (att.track_id == value.trackId) { | |||
value.updateTime = System.currentTimeMillis(); | |||
value.faceWidth = att.fa_w; | |||
value.result = att; | |||
value.bitmap = textureBitmap; | |||
mPersons.put(key, value); | |||
it.remove(); | |||
} | |||
} | |||
} | |||
} | |||
private static void filterUndeterminedFace(List<MultiAtt> results,Bitmap textureBitmap) { //在未确定人列表中对比 | |||
/** | |||
* 清理这轮未确定的人 | |||
*/ | |||
Iterator<Map.Entry<Integer, PersonInfo>> iterator = mUndeterminedPersons.entrySet().iterator(); | |||
while (iterator.hasNext()) { | |||
Map.Entry<Integer, PersonInfo> entry = iterator.next(); | |||
PersonInfo person = entry.getValue(); | |||
Iterator<MultiAtt> it = results.iterator(); | |||
while(it.hasNext()){ | |||
MultiAtt att = it.next(); | |||
if(att.track_id == person.trackId){ | |||
iterator.remove(); | |||
if(mSelectPerson != null && person.trackId == mSelectPerson.trackId){ | |||
mSelectPerson = null; | |||
} | |||
break; | |||
} | |||
} | |||
} | |||
/** | |||
* 将不符合条件的人加入未确定列表中 | |||
*/ | |||
Iterator<MultiAtt> it = results.iterator(); | |||
while(it.hasNext()){ | |||
//查找未确定列表中是否这人 | |||
MultiAtt att = it.next(); | |||
//加入已确定却是陌生人的人 不需要识别 | |||
if(mUndeterminedPersons.containsKey(att.track_id)){ | |||
PersonInfo stranger = mUndeterminedPersons.get(att.track_id); | |||
if(stranger.id.equals("-2")){ | |||
stranger.updateTime = System.currentTimeMillis(); | |||
stranger.faceWidth = att.fa_w; | |||
stranger.result = att; | |||
stranger.bitmap = textureBitmap; | |||
mUndeterminedPersons.put(att.track_id, stranger); | |||
it.remove(); | |||
return; | |||
} | |||
} | |||
if(att.hd_fa == 0 || (att.hd_fa > 0 && att.fa_quality < 0.6f)){ | |||
if(!mUndeterminedPersons.containsKey(att.track_id)){ | |||
PersonInfo message = new PersonInfo(); | |||
message.id = "-1"; | |||
message.name = ""; | |||
message.tag = "6"; | |||
message.trackId = att.track_id; | |||
message.startTime = System.currentTimeMillis(); | |||
message.result = att; | |||
message.faceWidth = att.fa_w; | |||
message.bitmap = textureBitmap; | |||
mUndeterminedPersons.put(att.track_id, message); | |||
} else{ | |||
PersonInfo message = mUndeterminedPersons.get(att.track_id); | |||
message.updateTime = System.currentTimeMillis(); | |||
message.faceWidth = att.fa_w; | |||
message.result = att; | |||
message.bitmap = textureBitmap; | |||
mUndeterminedPersons.put(att.track_id, message); | |||
} | |||
it.remove(); | |||
} | |||
} | |||
} | |||
private static final int PERSON_EXPIRE_TIME = 5000; //人物过期时间 | |||
private static final int UNKNOWN_PERSON_EXPIRE_TIME = 1500; | |||
private static final int FACE_DIFF = 70; | |||
private static final int CANDIDATE_STAY_TIME = 3000; | |||
public static void deleteExpirePerson(){ | |||
deleteExistExpirePerson(); | |||
deleteUndeterminedExpirePerson(); | |||
} | |||
public static void deleteExistExpirePerson(){ | |||
//删除过期人员 | |||
Iterator<Map.Entry<String, PersonInfo>> iterator = mPersons.entrySet().iterator(); | |||
while (iterator.hasNext()) { | |||
Map.Entry<String, PersonInfo> entry = iterator.next(); | |||
PersonInfo person = entry.getValue(); | |||
if(System.currentTimeMillis() - person.updateTime > PERSON_EXPIRE_TIME) { | |||
iterator.remove(); | |||
//置空当前选择人 | |||
if(mSelectPerson != null && person.id.equals(mSelectPerson.id)){ | |||
mSelectPerson = null; | |||
} | |||
} | |||
} | |||
} | |||
//mUndeterminedPersons 未确定人确定过程时直接清理 | |||
private static void deleteUndeterminedExpirePerson(){ | |||
Iterator<Map.Entry<Integer, PersonInfo>> iterator = mUndeterminedPersons.entrySet().iterator(); | |||
while (iterator.hasNext()) { | |||
Map.Entry<Integer, PersonInfo> entry = iterator.next(); | |||
PersonInfo person = entry.getValue(); | |||
if(System.currentTimeMillis() - person.updateTime > UNKNOWN_PERSON_EXPIRE_TIME) { | |||
iterator.remove(); | |||
//置空当前选择人 | |||
if(mSelectPerson != null && person.id.equals(mSelectPerson.id)){ | |||
mSelectPerson = null; | |||
} | |||
} | |||
} | |||
} | |||
private static PersonInfo filterHighLevelAndMaxFacePerson(Map<String, PersonInfo> persons, final int maxTag){ | |||
Map<String, PersonInfo> samePersons = new HashMap<>(); | |||
//筛选出一组最大身份的人 | |||
persons.forEach((key, value) -> { | |||
int mTag = Integer.parseInt(value.tag); | |||
if(mTag == maxTag){ | |||
samePersons.put(value.id, value); | |||
} | |||
}); | |||
//筛选出最大脸数据 | |||
AtomicReference<String> maxFaceId = new AtomicReference<>(""); | |||
AtomicReference<Integer> maxFace = new AtomicReference<>(0); | |||
samePersons.forEach((key, value) -> { | |||
if(value.faceWidth > maxFace.get()){ | |||
maxFace.set(value.faceWidth); | |||
maxFaceId.set(value.id); | |||
} | |||
}); | |||
return persons.get(maxFaceId.get()); | |||
} | |||
private static void sendMsgAndLog(Bitmap textureBitmap){ | |||
if(mSelectPerson == null){ | |||
return; | |||
} | |||
FaceManager.getInstance().updateRect(mSelectPerson.result); | |||
sendMsg(mSelectPerson); | |||
/** | |||
* 发送日志 | |||
*/ | |||
// 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(); | |||
} | |||
public static PersonInfo identifyFace(float[] feat, MultiAtt result) { | |||
String id = "-2"; | |||
String name = ""; | |||
String tag = "6"; | |||
int times = -1; | |||
int gender = (int) result.bd_gender; | |||
float thRecognition = 0.80f; //范围确定 | |||
IdentificationResult recRes = null; | |||
//底库无数据,所有人陌生人 | |||
if (Utils.userFaces.size() != 0) { | |||
recRes = FaceManager.getInstance().identifyFace(feat); | |||
if (recRes == null) { | |||
Logger.e("----------底库中查无此人----------"); | |||
// return null; | |||
return new PersonInfo(id, name, tag, -1, gender, result.track_id, 0, result); | |||
} | |||
// Log.e(TAG, "confidence: " + recRes.confidence); | |||
if (recRes.confidence >= thRecognition) { | |||
id = recRes.id.substring(0, recRes.id.length() - 2); | |||
// Log.e(TAG, "Recognized as: " + id); | |||
Emp emp = EmpDbHelper.getInstance().get(id); | |||
if(emp == null){ | |||
return new PersonInfo("-2", name, tag, times, gender, result.track_id, recRes.confidence, result); | |||
} | |||
name = !TextUtils.isEmpty(emp.nickName) ? emp.nickName : emp.name; //两个名称都传给H5 | |||
gender = emp.gender == 0 ? (int) result.bd_gender : emp.gender; | |||
tag = emp.typeId +""; | |||
Logger.e(TAG, "------------识别到人:" + name + "-------------"); | |||
Set<String> strings = Utils.userLogs.keySet(); | |||
if (strings.contains(id)) { | |||
times = 1; | |||
} | |||
return new PersonInfo(id, name, tag, times, gender, result.track_id, recRes.confidence, result); | |||
} else{ | |||
return new PersonInfo("-2", name, tag, times, gender, result.track_id, recRes.confidence, result); | |||
} | |||
} else{ | |||
return new PersonInfo("-2", name, tag, times, gender, result.track_id, 0, result); | |||
} | |||
//加上输出日志 | |||
// Set<String> strings = Utils.userLogs.keySet(); | |||
// if (!strings.contains(id)) { | |||
// DbHelper.Instance().addLogs(id, 1); | |||
// Utils.userLogs.put(id, 1); | |||
// } | |||
} | |||
public static void sendMsg(PersonInfo message) { | |||
try { | |||
JSONObject obj = new JSONObject(); | |||
obj.put("type", "faceIdentity"); | |||
JSONObject person = new JSONObject(); | |||
person.put("id", message.id); | |||
person.put("name", message.name); | |||
person.put("tag", message.tag); | |||
person.put("gender", message.gender); | |||
person.put("trackId", message.trackId); | |||
person.put("score", message.score); | |||
person.put("faceWidth", message.faceWidth); | |||
person.put("isInPicture", isContainSelectPerson); | |||
Skill skill = SkillDbHelper.getInstance().getByType(message.tag); | |||
if(skill != null){ | |||
person.put("skillStatus", skill.status); | |||
person.put("resp", skill.resp); | |||
person.put("motionName", skill.motionName); | |||
} | |||
person.put("isSpeakFinish", DuiMessageObserver.mSpeakFinishStatus); | |||
person.put("speakFinishTime", DuiMessageObserver.mSpeakFinishTime); | |||
StringBuilder allUsers = new StringBuilder(); | |||
mPersons.forEach((key, value) -> { | |||
allUsers.append(value.name).append(","); | |||
}); | |||
int index = 1; | |||
mUndeterminedPersons.forEach((key, value) -> { | |||
allUsers.append("陌生人").append(index).append(","); | |||
}); | |||
String all = allUsers.toString(); | |||
if(!TextUtils.isEmpty(all)){ | |||
all = all.substring(0, all.length() - 1); | |||
} | |||
person.put("allUsers", all); | |||
// person.put("onDutyHourStart", "10:00"); | |||
// person.put("onDutyHourEnd", "10:30"); | |||
// person.put("offDutyHourStart", "17:00"); | |||
// person.put("offDutyHourEnd", "24:00"); | |||
// person.put("dutyWord", "打卡成功"); | |||
List<Model> modelList = ModelDbHelper.getInstance().getAll(); | |||
if(modelList != null && modelList.size() > 0){ | |||
Model model = modelList.get(0); | |||
if(model.workdayHour != null){ | |||
person.put("onDutyHourStart", model.workdayHour.onDutyHourStart); | |||
person.put("onDutyHourEnd", model.workdayHour.onDutyHourEnd); | |||
person.put("offDutyHourStart", model.workdayHour.offDutyHourStart); | |||
person.put("offDutyHourEnd", model.workdayHour.offDutyHourEnd); | |||
person.put("dutyWord", "打卡成功"); | |||
} | |||
if(model.workTime != null){ | |||
person.put("workdayHourStart", model.workTime.workdayHourStart); | |||
person.put("workdayHourEnd", model.workTime.workdayHourEnd); | |||
person.put("weekendHourStart", model.workTime.weekendHourStart); | |||
person.put("weekendHourEnd", model.workTime.weekendHourEnd); | |||
} | |||
} | |||
obj.put("data", person.toString()); | |||
Date date = new Date(System.currentTimeMillis()); | |||
SimpleDateFormat spTime = new SimpleDateFormat("yyyy-MM-dd/HH:mm:ss");//yyyy-MM-dd/HH:mm:ss HH24 hh12 | |||
String sT = spTime.format(date); | |||
String sendingMsg = obj.toString(); | |||
Logger.e(sT + ":发送消息到H5: " + sendingMsg + "/"); | |||
MessageUtils.sendMessage(sendingMsg); | |||
} catch (JSONException e) { | |||
e.printStackTrace(); | |||
} | |||
} | |||
private void faceLimit(List<MultiAtt> results) { | |||
int leftLimit = 100; | |||
results.removeIf(e -> e.fa_x1 < leftLimit); | |||
int rightLimit = 2060; | |||
results.removeIf(e -> (e.fa_x1 + e.fa_w) > rightLimit); | |||
int topLimit = 100; | |||
results.removeIf(e -> e.fa_y1 < topLimit); | |||
int bottomLimit = 3740; | |||
results.removeIf(e -> e.fa_y1 + e.fa_h > bottomLimit); | |||
} | |||
private void bodyLimit(List<MultiAtt> results) { //以后修改 | |||
int leftLimit = 100; | |||
results.removeIf(e -> e.bd_x1 < leftLimit); | |||
int rightLimit = 2060; | |||
results.removeIf(e -> (e.bd_x1 + e.bd_w) > rightLimit); | |||
int topLimit = 100; | |||
results.removeIf(e -> e.bd_y1 < topLimit); | |||
int bottomLimit = 3740; | |||
results.removeIf(e -> e.bd_y1 + e.bd_h > bottomLimit); | |||
} | |||
/** | |||
* find the largest face | |||
* @param results | |||
*/ | |||
private void faceROIFilter(List<MultiAtt> results) { | |||
int maxFace = 0; | |||
for (MultiAtt att : results) { | |||
// if(mLastTrackId == att.track_id){ | |||
// Log.e(TAG,"------------------tracked---------------------"); | |||
// results.removeIf(e -> (e.track_id) != mLastTrackId); | |||
// return; | |||
// } | |||
if(att.fa_w > maxFace) { | |||
maxFace = att.fa_w; | |||
} | |||
} | |||
int maxFaceSize = maxFace; | |||
results.removeIf(e -> (e.fa_w) < maxFaceSize); | |||
} | |||
private void faceSizeFilter(List<MultiAtt> results) { | |||
int minFaceSize = 140; | |||
results.removeIf(e -> (e.fa_w) < minFaceSize); | |||
} | |||
private void faceQualityFilter(List<MultiAtt> results) { | |||
boolean enableQualityFilter = true; | |||
float thQuality = 0.60f; | |||
if (enableQualityFilter) results.removeIf(e -> (e.fa_quality) < thQuality); | |||
} | |||
public boolean hasPerson(){ | |||
MessageUtils.sendMessage("识别人数量:" + mPersons.size() + " 未识别人数量:" + mUndeterminedPersons.size()); | |||
if(mPersons.size() > 0 || mUndeterminedPersons.size() > 0){ | |||
return true; | |||
} | |||
// if(mPersons.size() > 0){ | |||
// return true; | |||
// } else if(mUndeterminedPersons.size() > 0){ | |||
// Iterator <Map.Entry< Integer, PersonInfo >> iterator = mUndeterminedPersons.entrySet().iterator(); | |||
// while (iterator.hasNext()) { | |||
// Map.Entry< Integer, PersonInfo > entry = iterator.next(); | |||
// if(entry.getValue().result.fa_quality > 0.6f){ | |||
// return true; | |||
// } | |||
// } | |||
// } | |||
return false; | |||
} | |||
private 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<>(); | |||
postParam.put("devId", Build.SERIAL); | |||
postParam.put("timestamp", System.currentTimeMillis() + ""); | |||
postParam.put("userId", userId); | |||
postParam.put("type", type); | |||
postParam.put("faceScore", confidence + ""); | |||
postParam.put("imgbase64", base64.replace("\n", "").replace("\\", "") + ""); | |||
postParam.put("sign", "123456"); | |||
RequestBody requestBody = RequestBody.create(MediaType.parse("application/json"), new JSONObject(postParam).toString()); | |||
HttpUtil.post(Config.CURRENT_URL + "system/pass/api/upload-pass", 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"); | |||
} | |||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); | |||
String time = dateFormat.format(new Date(System.currentTimeMillis())); | |||
if (status == 0) { | |||
Logger.e(time + ":上传人脸日志成功: id =" + userId); | |||
} else { | |||
Logger.e(time + ":上传人脸日志失败: error =" + errMsg); | |||
onFail(errMsg); | |||
} | |||
} catch (Exception e) { | |||
e.printStackTrace(); | |||
onFail(e.getMessage()); | |||
} | |||
} | |||
@Override | |||
public void onFail(String error) { | |||
Log.e(TAG, "sendLog onFail: " + error); | |||
} | |||
}); | |||
} | |||
public static void sendStrangerToServer(){ | |||
//有人脸且质量合格的陌生人才会发到服务端 | |||
Stream<PersonInfo> pInfos = mUndeterminedPersons.values().stream().filter(item-> item.result.hd_fa > 0 && item.result.fa_quality > 0.8f); | |||
if(pInfos.count() == 0){ | |||
return; | |||
} | |||
Stream<PersonInfo> pInfos2 = mUndeterminedPersons.values().stream().filter(item-> item.result.hd_fa > 0 && item.result.fa_quality > 0.8f); | |||
JSONArray array = new JSONArray(); | |||
pInfos2.forEach(new Consumer<PersonInfo>() { | |||
@Override | |||
public void accept(PersonInfo personInfo) { | |||
Stranger stranger = null; | |||
if(Utils.userNewFaces.size() > 0){ | |||
//陌生人人脸底库对比 | |||
IdentificationResult recRes = FaceManager.getInstance().identifyFace(personInfo.dfeatures); | |||
if (recRes == null) { | |||
stranger = saveStranger(personInfo); | |||
} else{ | |||
if (recRes.confidence >= 0.8f) { | |||
String id = recRes.id.substring(0, recRes.id.length() - 2); | |||
Stranger s = StrangerDbHelper.getInstance().get(id); | |||
if(s != null && System.currentTimeMillis() - s.timestamp > 10 * 1000){ | |||
s.timestamp = System.currentTimeMillis(); | |||
s.faceFeatures = personInfo.dfeatures; | |||
s.userId = id + ""; | |||
s.tag = personInfo.tag; | |||
StrangerDbHelper.getInstance().update(s); | |||
stranger = s; | |||
} | |||
} | |||
} | |||
} else{ | |||
stranger = saveStranger(personInfo); | |||
} | |||
if(stranger != null){ | |||
try { | |||
JSONObject object = new JSONObject(); | |||
object.put("userId",stranger.userId); | |||
byte[] bitmapBytes = BmpCompressUtils.getBytesByBitmap(Utils.CompressBmp(personInfo.bitmap, mSelectPerson.result), 100, Bitmap.CompressFormat.JPEG); | |||
String base64 = Base64.encodeToString(bitmapBytes, Base64.DEFAULT); | |||
object.put("imgbase64", base64.replace("\n", "").replace("\\", "") + ""); | |||
object.put("type", personInfo.tag); | |||
object.put("faceScore", personInfo.score); | |||
array.put(object); | |||
} catch (JSONException e) { | |||
throw new RuntimeException(e); | |||
} | |||
} | |||
} | |||
}); | |||
if(array.length() == 0){ | |||
return; | |||
} | |||
HashMap<String, Object> postParam = new HashMap<>(); | |||
postParam.put("devId", Build.SERIAL); | |||
postParam.put("timestamp", System.currentTimeMillis() + ""); | |||
postParam.put("sign", "123456"); | |||
postParam.put("records", array); | |||
RequestBody requestBody = RequestBody.create(MediaType.parse("application/json"), new JSONObject(postParam).toString()); | |||
HttpUtil.post(Config.CURRENT_URL + "system/pass/api/upload-multi-pass", 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"); | |||
} | |||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); | |||
String time = dateFormat.format(new Date(System.currentTimeMillis())); | |||
if (status == 0) { | |||
Logger.e(time + ":批量上传人脸日志成功"); | |||
} else { | |||
Logger.e(time + ":批量上传人脸日志失败: error =" + errMsg); | |||
onFail(errMsg); | |||
} | |||
} catch (Exception e) { | |||
e.printStackTrace(); | |||
onFail(e.getMessage()); | |||
} | |||
} | |||
@Override | |||
public void onFail(String error) { | |||
Log.e(TAG, "sendStrangerToServer onFail: " + error); | |||
} | |||
}); | |||
} | |||
public static Stranger saveStranger(PersonInfo personInfo) { | |||
long id = System.currentTimeMillis(); | |||
Utils.userNewFaces.put(id + "_1", personInfo.dfeatures); | |||
Stranger stranger = new Stranger(); | |||
stranger.timestamp = id; | |||
stranger.userId = id + ""; | |||
stranger.tag = personInfo.tag; | |||
stranger.faceFeatures = personInfo.dfeatures; | |||
StrangerDbHelper.getInstance().add(stranger); | |||
return stranger; | |||
} | |||
} |
@@ -0,0 +1,396 @@ | |||
package com.aispeech.nativedemo.face; | |||
import android.graphics.Bitmap; | |||
import android.text.TextUtils; | |||
import com.aispeech.nativedemo.db.EmpDbHelper; | |||
import com.aispeech.nativedemo.entity.Emp; | |||
import com.aispeech.nativedemo.entity.PersonInfo; | |||
import com.aispeech.nativedemo.entity.Reception; | |||
import com.aispeech.nativedemo.log.Logger; | |||
import com.aispeech.nativedemo.network.ws.MessageUtils; | |||
import com.aispeech.nativedemo.utils.Utils; | |||
import com.lenovo.lefacesdk.IdentificationResult; | |||
import com.lenovo.lefacesdk.MultiAtt; | |||
import java.text.SimpleDateFormat; | |||
import java.util.Date; | |||
import java.util.HashMap; | |||
import java.util.Iterator; | |||
import java.util.List; | |||
import java.util.Map; | |||
import java.util.Set; | |||
import java.util.concurrent.atomic.AtomicInteger; | |||
public class FaceReceptionMode { | |||
private static final String TAG = "FaceReceptionMode"; | |||
private static final long COLLECT_TIME = 2000l; | |||
private final static long ROUND_TIMES = 3; | |||
private final static long SESSION_TIME = 5 * 60 * 1000; | |||
private static int mCollectTimes = 0; | |||
private static Map<String, PersonInfo> mGreetPersons = new HashMap<>(); | |||
private static Map<String, PersonInfo> mUngreetPersons = new HashMap<>(); | |||
private static Map<Integer, PersonInfo> mUndeterminedPersons = new HashMap<>(); | |||
public static long mInterval = 0; | |||
public static Reception mReception = null; | |||
public static boolean isStrangerAsk = false; | |||
public static long mFreeTime = 0; | |||
public static List<MultiAtt> detectMultiAtt(Bitmap textureBitmap) { | |||
if(mInterval == 0){ | |||
mInterval = System.currentTimeMillis(); | |||
} | |||
if(mFreeTime == 0){ | |||
mFreeTime = System.currentTimeMillis(); | |||
} | |||
return FaceManager.getInstance().detectMultiAtt(textureBitmap); | |||
} | |||
public static void checkSessionExpire(boolean isSelf){ | |||
if(isSelf || System.currentTimeMillis() - mFreeTime > SESSION_TIME){ | |||
MessageUtils.receptionModeStep("会话时间超时,结束接待模式"); | |||
IdentityMode.MODE_CURRENT = IdentityMode.MODE_CHAT; | |||
mUngreetPersons.clear(); | |||
mGreetPersons.clear(); | |||
mUndeterminedPersons.clear(); | |||
mCollectTimes = 0; | |||
mReception = null; | |||
mFreeTime = 0; | |||
isStrangerAsk = false; | |||
mInterval = 0; | |||
MessageUtils.endReceptionMode(); | |||
} | |||
} | |||
public static boolean featExtract(List<MultiAtt> results, Bitmap textureBitmap) { | |||
mFreeTime = System.currentTimeMillis(); | |||
List<float[]> employeeList = FaceManager.getInstance().featExtract(results, textureBitmap); | |||
for (int j = 0; j < employeeList.size(); j++) { | |||
float[] feat = employeeList.get(j); | |||
if(feat.length != 256){ | |||
continue; | |||
} | |||
PersonInfo person = identifyFace(feat, results.get(j)); | |||
if(person != null){ | |||
person.dfeatures = feat; | |||
person.bitmap = textureBitmap; | |||
Logger.e("识别对象为:" + person.name); | |||
if(person.id.equals("-2")){ //添加识别条件 人脸质量高和识别置信度底 | |||
if(mUndeterminedPersons.containsKey(person.trackId)){ | |||
PersonInfo origin = mUndeterminedPersons.get(person.trackId); | |||
origin.updateTime = System.currentTimeMillis(); | |||
origin.result = person.result; | |||
origin.faceWidth = person.faceWidth; | |||
origin.bitmap = person.bitmap; | |||
mUndeterminedPersons.put(person.trackId, origin); | |||
} else{ | |||
mUndeterminedPersons.put(person.trackId, person); | |||
} | |||
} else{ | |||
//已经认出人的处理 | |||
if(mGreetPersons.containsKey(person.id)){ | |||
//已打招呼不处理 | |||
continue; | |||
} | |||
if(mUngreetPersons.containsKey(person.id)){ | |||
//未打招呼更新 | |||
PersonInfo origin = mUngreetPersons.get(person.id); | |||
origin.updateTime = System.currentTimeMillis(); | |||
origin.result = person.result; | |||
origin.faceWidth = person.faceWidth; | |||
origin.bitmap = person.bitmap; | |||
mUngreetPersons.put(person.id, origin); | |||
} else{ | |||
//未打招呼新增 | |||
mUngreetPersons.put(person.id, person); | |||
} | |||
//从未识别列表中移除 | |||
if(mUndeterminedPersons.containsKey(person.trackId)){ | |||
mUndeterminedPersons.remove(person.trackId); | |||
} | |||
} | |||
} | |||
} | |||
if(System.currentTimeMillis() - mInterval < COLLECT_TIME){ | |||
return false; | |||
} | |||
mInterval = System.currentTimeMillis(); | |||
mCollectTimes++; | |||
if(mCollectTimes == ROUND_TIMES){ | |||
MessageUtils.receptionModeStep("第3轮收集数据,开始打招呼"); | |||
mCollectTimes = 0; | |||
return true; | |||
} else{ | |||
MessageUtils.receptionModeStep("第" + mCollectTimes + "轮收集数据"); | |||
} | |||
return false; | |||
} | |||
public static void confirmCurrentWord(){ | |||
if(mUngreetPersons.size() == 0 && mUndeterminedPersons.size() == 0){ | |||
if(mGreetPersons.size() > 0){ | |||
MessageUtils.receptionModeStep("已经打过招呼"); | |||
} else{ | |||
MessageUtils.receptionModeStep("没有识别到人"); | |||
} | |||
return; | |||
} | |||
if(IdentityMode.MODE_CURRENT != IdentityMode.MODE_RECEPTION){ | |||
MessageUtils.receptionModeStep("当前不是接待模式"); | |||
return; | |||
} | |||
Reception reception = mReception; | |||
if(reception == null){ | |||
MessageUtils.receptionModeStep("接待任务为空"); | |||
return; | |||
} | |||
Date date = new Date(System.currentTimeMillis()); | |||
SimpleDateFormat time = new SimpleDateFormat("MM-dd"); | |||
String dateStr = time.format(date); | |||
if(!dateStr.equals(reception.date)){ | |||
MessageUtils.receptionModeStep("不在接待时间范围内"); | |||
return; | |||
} | |||
StringBuilder word = new StringBuilder(); | |||
AtomicInteger index1 = new AtomicInteger(0); | |||
mUngreetPersons.forEach((key, person) -> { | |||
if(person.tag.equals("4")){ | |||
index1.getAndIncrement(); | |||
word.append(person.name).append(","); | |||
} | |||
}); | |||
if(index1.get() > 0){ | |||
word.append(index1.get() > 1 ? "你们好," : "您好,"); | |||
} | |||
AtomicInteger index2 = new AtomicInteger(0); | |||
mUngreetPersons.forEach((key, person) -> { | |||
if(person.tag.equals("5")){ | |||
index2.getAndIncrement(); | |||
word.append(person.name).append(","); | |||
} | |||
}); | |||
if(index2.get() > 0){ | |||
word.append(index2.get() > 1 ? "你们好," : "你好,"); | |||
} | |||
AtomicInteger index3 = new AtomicInteger(0); | |||
mUngreetPersons.forEach((key, person) -> { | |||
String id = person.id; | |||
if(reception.guide.size() > 0 && reception.first.contains(id)){ | |||
index3.getAndIncrement(); | |||
word.append(person.name).append(","); | |||
} | |||
}); | |||
mUngreetPersons.forEach((key, person) -> { | |||
String id = person.id; | |||
if(reception.guide.size() > 0 && reception.second.contains(id)){ | |||
index3.getAndIncrement(); | |||
word.append(person.name).append(","); | |||
} | |||
}); | |||
mUngreetPersons.forEach((key, person) -> { | |||
String id = person.id; | |||
if(reception.guide.size() > 0 && reception.third.contains(id)){ | |||
index3.getAndIncrement(); | |||
word.append(person.name).append(","); | |||
} | |||
}); | |||
if(index3.get() > 0){ | |||
word.append(index3.get() > 1 ? "你们好" : "你好"); | |||
} | |||
if(TextUtils.isEmpty(word.toString())){ | |||
if(mUndeterminedPersons.size() > 2 && !isStrangerAsk){ | |||
MessageUtils.receptionModeStep("播放托底话术"); | |||
word.append(reception.underpinWord); | |||
isStrangerAsk = true; | |||
} | |||
} | |||
if(!TextUtils.isEmpty(word.toString())){ | |||
sendMsg(word.toString()); | |||
} else{ | |||
MessageUtils.receptionModeStep("招呼语为空"); | |||
} | |||
} | |||
//过滤人物 | |||
public static void filterPersonForFeatExtract(List<MultiAtt> results, Bitmap textureBitmap){ | |||
filterExactLyFace(results, mGreetPersons, textureBitmap); | |||
filterExactLyFace(results, mUngreetPersons, textureBitmap); | |||
filterUndeterminedFace(results, textureBitmap); | |||
} | |||
private static void filterExactLyFace(List<MultiAtt> results, Map<String, PersonInfo> persons, Bitmap textureBitmap){ //判断在认识人列表中是否存在 | |||
Iterator<MultiAtt> it = results.iterator(); | |||
while(it.hasNext()){ | |||
//查找已有列表中是否这人 | |||
MultiAtt att = it.next(); | |||
for (Map.Entry<String, PersonInfo> entry : persons.entrySet()) { | |||
String key = entry.getKey(); | |||
PersonInfo value = entry.getValue(); | |||
if (att.track_id == value.trackId) { | |||
value.updateTime = System.currentTimeMillis(); | |||
value.faceWidth = att.fa_w; | |||
value.result = att; | |||
value.bitmap = textureBitmap; | |||
persons.put(key, value); | |||
it.remove(); | |||
} | |||
} | |||
} | |||
} | |||
private static void filterUndeterminedFace(List<MultiAtt> results,Bitmap textureBitmap) { //在未确定人列表中对比 | |||
/** | |||
* 清理这轮未确定的人 | |||
*/ | |||
Iterator<Map.Entry<Integer, PersonInfo>> iterator = mUndeterminedPersons.entrySet().iterator(); | |||
while (iterator.hasNext()) { | |||
Map.Entry<Integer, PersonInfo> entry = iterator.next(); | |||
PersonInfo person = entry.getValue(); | |||
Iterator<MultiAtt> it = results.iterator(); | |||
while(it.hasNext()){ | |||
MultiAtt att = it.next(); | |||
if(att.track_id == person.trackId){ | |||
iterator.remove(); | |||
break; | |||
} | |||
} | |||
} | |||
/** | |||
* 将不符合条件的人加入未确定列表中 | |||
*/ | |||
Iterator<MultiAtt> it = results.iterator(); | |||
while(it.hasNext()){ | |||
//查找未确定列表中是否这人 | |||
MultiAtt att = it.next(); | |||
//加入已确定却是陌生人的人 不需要识别 | |||
if(mUndeterminedPersons.containsKey(att.track_id)){ | |||
PersonInfo stranger = mUndeterminedPersons.get(att.track_id); | |||
if(stranger.id.equals("-2")){ | |||
stranger.updateTime = System.currentTimeMillis(); | |||
stranger.faceWidth = att.fa_w; | |||
stranger.result = att; | |||
stranger.bitmap = textureBitmap; | |||
mUndeterminedPersons.put(att.track_id, stranger); | |||
it.remove(); | |||
return; | |||
} | |||
} | |||
if(att.hd_fa == 0 || (att.hd_fa > 0 && att.fa_quality < 0.6f)){ | |||
if(!mUndeterminedPersons.containsKey(att.track_id)){ | |||
PersonInfo message = new PersonInfo(); | |||
message.id = "-1"; | |||
message.name = ""; | |||
message.tag = "6"; | |||
message.trackId = att.track_id; | |||
message.startTime = System.currentTimeMillis(); | |||
message.result = att; | |||
message.faceWidth = att.fa_w; | |||
message.bitmap = textureBitmap; | |||
mUndeterminedPersons.put(att.track_id, message); | |||
} else{ | |||
PersonInfo message = mUndeterminedPersons.get(att.track_id); | |||
message.updateTime = System.currentTimeMillis(); | |||
message.faceWidth = att.fa_w; | |||
message.result = att; | |||
message.bitmap = textureBitmap; | |||
mUndeterminedPersons.put(att.track_id, message); | |||
} | |||
it.remove(); | |||
} | |||
} | |||
} | |||
private static final int PERSON_EXPIRE_TIME = 10000; //人物过期时间 | |||
private static final int UNKNOWN_PERSON_EXPIRE_TIME = 10000; | |||
public static void deleteExpirePerson(){ | |||
// deleteExistExpirePerson(mGreetPersons); | |||
deleteExistExpirePerson(mUngreetPersons); | |||
deleteUndeterminedExpirePerson(); | |||
} | |||
public static void deleteExistExpirePerson(Map<String, PersonInfo> persons){ | |||
//删除过期人员 | |||
Iterator<Map.Entry<String, PersonInfo>> iterator = persons.entrySet().iterator(); | |||
while (iterator.hasNext()) { | |||
Map.Entry<String, PersonInfo> entry = iterator.next(); | |||
PersonInfo person = entry.getValue(); | |||
if(System.currentTimeMillis() - person.updateTime > PERSON_EXPIRE_TIME) { | |||
iterator.remove(); | |||
} | |||
} | |||
} | |||
//mUndeterminedPersons 未确定人确定过程时直接清理 | |||
private static void deleteUndeterminedExpirePerson(){ | |||
Iterator<Map.Entry<Integer, PersonInfo>> iterator = mUndeterminedPersons.entrySet().iterator(); | |||
while (iterator.hasNext()) { | |||
Map.Entry<Integer, PersonInfo> entry = iterator.next(); | |||
PersonInfo person = entry.getValue(); | |||
if(System.currentTimeMillis() - person.updateTime > UNKNOWN_PERSON_EXPIRE_TIME) { | |||
iterator.remove(); | |||
//置空当前选择人 | |||
} | |||
} | |||
} | |||
public static PersonInfo identifyFace(float[] feat, MultiAtt result) { | |||
String id = "-2"; | |||
String name = ""; | |||
String tag = "6"; | |||
int times = -1; | |||
int gender = (int) result.bd_gender; | |||
float thRecognition = 0.80f; //范围确定 | |||
IdentificationResult recRes = null; | |||
//底库无数据,所有人陌生人 | |||
if (Utils.userFaces.size() != 0) { | |||
recRes = FaceManager.getInstance().identifyFace(feat); | |||
if (recRes == null) { | |||
Logger.e("----------底库中查无此人----------"); | |||
// return null; | |||
return new PersonInfo(id, name, tag, -1, gender, result.track_id, 0, result); | |||
} | |||
// Log.e(TAG, "confidence: " + recRes.confidence); | |||
if (recRes.confidence >= thRecognition) { | |||
id = recRes.id.substring(0, recRes.id.length() - 2); | |||
// Log.e(TAG, "Recognized as: " + id); | |||
Emp emp = EmpDbHelper.getInstance().get(id); | |||
if(emp == null){ | |||
return new PersonInfo("-2", name, tag, times, gender, result.track_id, recRes.confidence, result); | |||
} | |||
name = !TextUtils.isEmpty(emp.nickName) ? emp.nickName : emp.name; //两个名称都传给H5 | |||
gender = emp.gender == 0 ? (int) result.bd_gender : emp.gender; | |||
tag = emp.typeId +""; | |||
Logger.e(TAG, "------------识别到人:" + name + "-------------"); | |||
Set<String> strings = Utils.userLogs.keySet(); | |||
if (strings.contains(id)) { | |||
times = 1; | |||
} | |||
return new PersonInfo(id, name, tag, times, gender, result.track_id, recRes.confidence, result); | |||
} else{ | |||
return new PersonInfo("-2", name, tag, times, gender, result.track_id, recRes.confidence, result); | |||
} | |||
} else{ | |||
return new PersonInfo("-2", name, tag, times, gender, result.track_id, 0, result); | |||
} | |||
} | |||
public static void sendMsg(String message) { | |||
MessageUtils.sendTtsNlpText(message); | |||
Iterator<Map.Entry<String, PersonInfo>> iterator = mUngreetPersons.entrySet().iterator(); | |||
while (iterator.hasNext()) { | |||
Map.Entry<String, PersonInfo> entry = iterator.next(); | |||
PersonInfo person = entry.getValue(); | |||
mGreetPersons.put(person.id, person); | |||
iterator.remove(); | |||
} | |||
} | |||
} |
@@ -0,0 +1,7 @@ | |||
package com.aispeech.nativedemo.face; | |||
public class IdentityMode { | |||
public final static String MODE_CHAT = "chat"; | |||
public final static String MODE_RECEPTION = "reception"; | |||
public static String MODE_CURRENT = MODE_CHAT; | |||
} |
@@ -35,4 +35,30 @@ public class LogFile { | |||
} | |||
return null; | |||
} | |||
public static String saveDjLogMessageFile(String logMessage) { | |||
logMessage = logMessage.replace("djlog-", ""); | |||
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"; | |||
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; | |||
} | |||
} |
@@ -377,7 +377,12 @@ final class LoggerPrinter implements Printer { | |||
mSettings.getLogAdapter().d(finalTag, chunk); | |||
break; | |||
} | |||
LogFile.saveLogMessageFile(chunk); | |||
if(chunk.contains("djlog")){ | |||
LogFile.saveDjLogMessageFile(chunk); | |||
} else{ | |||
LogFile.saveLogMessageFile(chunk); | |||
} | |||
// if (logType >= mSettings.getLog2FileLevel() && mSettings.isLog2File()) { | |||
// LogFile.saveLogMessageFile(chunk, mSettings.getLogFilePath()); | |||
// } | |||
@@ -15,6 +15,8 @@ import com.aispeech.nativedemo.db.InitializeDbHelper; | |||
import com.aispeech.nativedemo.dds.DDSManager; | |||
import com.aispeech.nativedemo.entity.Initialize; | |||
import com.aispeech.nativedemo.face.FaceManager; | |||
import com.aispeech.nativedemo.face.FaceReceptionMode; | |||
import com.aispeech.nativedemo.face.IdentityMode; | |||
import com.aispeech.nativedemo.log.Logger; | |||
import com.aispeech.nativedemo.mqtt.MqttManager; | |||
import com.aispeech.nativedemo.network.DigiNetworkManager; | |||
@@ -58,14 +60,15 @@ public class DigiWebSocketServer extends WebSocketServer { | |||
Logger.e("onOpen()一个客户端连接成功:" + conn.getRemoteSocketAddress()); | |||
Utils.websocketList.add(conn.getRemoteSocketAddress().toString()); | |||
mConns.add(conn); | |||
InetSocketAddress address = conn.getRemoteSocketAddress(); | |||
InetAddress address1 = address.getAddress(); | |||
String ad1 = address1.getHostAddress(); | |||
// InetSocketAddress address = conn.getRemoteSocketAddress(); | |||
// InetAddress address1 = address.getAddress(); | |||
// String ad1 = address1.getHostAddress(); | |||
// String ad2 = address1.getHostName(); | |||
getActivateStatus(ad1); | |||
getActivateStatus(); | |||
MessageUtils.sendWakeupStatus(DuiMessageObserver.mIsSleep); | |||
MessageUtils.sendFaceSDKInitStatus(FaceManager.getInstance(context).getInitResult()); | |||
MessageUtils.sendFaceSDKInitStatus(FaceManager.getInstance().getInitResult()); | |||
MessageUtils.sendSpeechSDKInitStatus(DDSService.initCompleted); | |||
MessageUtils.getReceptionMode(); | |||
} | |||
@Override | |||
@@ -81,8 +84,14 @@ public class DigiWebSocketServer extends WebSocketServer { | |||
public void onMessage(WebSocket conn, String message) { | |||
// 这里在网页测试端发过来的是文本数据 测试网页 http://www.websocket-test.com/ | |||
// 需要保证android 和 加载网页的设备(我这边是电脑) 在同一个网段内,连同一个wifi即可 | |||
Logger.e("onMessage()网页端来的消息->" + conn.getRemoteSocketAddress() + ": " + message); | |||
// Logger.e("onMessage()网页端来的消息->" + conn.getRemoteSocketAddress() + ": " + message); | |||
//Collection<WebSocket> client = new ArrayList<>(); | |||
if(message.contains("djlog-")){ | |||
Logger.e(message); | |||
return; | |||
} else{ | |||
Logger.e("onMessage()网页端来的消息->" + conn.getRemoteSocketAddress() + ": " + message); | |||
} | |||
if (message.equals("ping")) { | |||
broadcast("tong"); | |||
heartbeatTime = System.currentTimeMillis(); | |||
@@ -116,6 +125,14 @@ public class DigiWebSocketServer extends WebSocketServer { | |||
} else{ | |||
DDSManager.getInstance().stopDDSDialog(); | |||
} | |||
} else if(type.equals("receptionMode")){ | |||
boolean status = obj.optBoolean("status"); | |||
if(status){ | |||
IdentityMode.MODE_CURRENT = IdentityMode.MODE_RECEPTION; | |||
} else{ | |||
IdentityMode.MODE_CURRENT = IdentityMode.MODE_CHAT; | |||
FaceReceptionMode.checkSessionExpire(true); | |||
} | |||
} | |||
} catch (JSONException e) { | |||
throw new RuntimeException(e); | |||
@@ -183,7 +200,7 @@ public class DigiWebSocketServer extends WebSocketServer { | |||
mConns.clear(); | |||
} | |||
private void getActivateStatus(String address) { | |||
private void getActivateStatus() { | |||
HashMap<String, String> map = new HashMap<>(); | |||
HttpUtil.get(Config.CURRENT_URL + "message/api/get_activate/" + Build.SERIAL, map, new HttpUtil.HttpCallback<String>() { | |||
@@ -7,19 +7,17 @@ import com.aispeech.dui.dds.DDS; | |||
import com.aispeech.dui.dds.DDSMode; | |||
import com.aispeech.dui.dds.exceptions.DDSNotInitCompleteException; | |||
import com.aispeech.nativedemo.DuiApplication; | |||
import com.aispeech.nativedemo.MainActivity; | |||
import com.aispeech.nativedemo.asr.observer.DuiMessageObserver; | |||
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.log.Logger; | |||
import com.aispeech.nativedemo.shape.ShapeManager; | |||
import org.json.JSONException; | |||
import org.json.JSONObject; | |||
import java.text.SimpleDateFormat; | |||
import java.util.Date; | |||
import java.util.List; | |||
public class MessageUtils { | |||
@@ -195,6 +193,34 @@ public class MessageUtils { | |||
} | |||
} | |||
public static void sendTtsText(String data){ | |||
try { | |||
if(!TextUtils.isEmpty(data)){ | |||
JSONObject jo = new JSONObject(); | |||
jo.put("type", "djTtsText"); | |||
jo.put("data", data); | |||
Logger.e("发给叠境tts:" + data); | |||
sendMessage(jo.toString()); | |||
} | |||
} catch (JSONException e) { | |||
e.printStackTrace(); | |||
} | |||
} | |||
public static void sendTtsNlpText(String data){ | |||
try { | |||
if(!TextUtils.isEmpty(data)){ | |||
JSONObject jo = new JSONObject(); | |||
jo.put("type", "djTtsNlpText"); | |||
jo.put("data", data); | |||
Logger.e("思必驰NLP结果发给叠境tts:" + data); | |||
sendMessage(jo.toString()); | |||
} | |||
} catch (JSONException e) { | |||
e.printStackTrace(); | |||
} | |||
} | |||
public static void sendRest(){ | |||
List<Model> modelList = ModelDbHelper.getInstance().getAll(); | |||
if(modelList != null && modelList.size() > 0){ | |||
@@ -232,4 +258,37 @@ public class MessageUtils { | |||
e.printStackTrace(); | |||
} | |||
} | |||
public static void getReceptionMode(){ | |||
try { | |||
JSONObject jo = new JSONObject(); | |||
jo.put("type", "getReceptionMode"); | |||
jo.put("data", "getReceptionMode"); | |||
sendMessage(jo.toString()); | |||
} catch (JSONException e) { | |||
throw new RuntimeException(e); | |||
} | |||
} | |||
public static void endReceptionMode(){ | |||
try { | |||
JSONObject jo = new JSONObject(); | |||
jo.put("type", "reception"); | |||
jo.put("data", false); | |||
sendMessage(jo.toString()); | |||
} catch (JSONException e) { | |||
throw new RuntimeException(e); | |||
} | |||
} | |||
public static void receptionModeStep(String message){ | |||
try { | |||
JSONObject jo = new JSONObject(); | |||
jo.put("type", "receptionStep"); | |||
jo.put("data", message); | |||
sendMessage(jo.toString()); | |||
} catch (JSONException e) { | |||
throw new RuntimeException(e); | |||
} | |||
} | |||
} |
@@ -0,0 +1,31 @@ | |||
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,0 +1,66 @@ | |||
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,0 +1,228 @@ | |||
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,0 +1,219 @@ | |||
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(); | |||
} | |||
} |
@@ -153,6 +153,11 @@ public class UploadManager { | |||
File[] logs = file.listFiles(); | |||
if(logs != null && logs.length > 0){ | |||
for(File log : logs){ | |||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); | |||
String time = dateFormat.format(new Date(System.currentTimeMillis())); | |||
if(log.getName().contains(time)){ | |||
return; | |||
} | |||
HashMap<String, String> map = new HashMap<>(); | |||
map.put("devId", Build.SERIAL); | |||
map.put("logType", uploadType + ""); | |||
@@ -44,7 +44,6 @@ import java.util.List; | |||
public class Utils { | |||
public static LinkedHashMap<String, float[]> userFaces = new LinkedHashMap<>(); | |||
public static LinkedHashMap<String, float[]> userFaces2 = new LinkedHashMap<>(); | |||
public static LinkedHashMap<String, float[]> userNewFaces = new LinkedHashMap<>(); | |||
public static LinkedHashMap<String, Integer> userLogs = new LinkedHashMap<>(); | |||
public static LinkedHashMap<String, Long> logsTime = new LinkedHashMap<>(); | |||
@@ -40,6 +40,7 @@ import com.aispeech.nativedemo.db.ModelDbHelper; | |||
import com.aispeech.nativedemo.db.SkillDbHelper; | |||
import com.aispeech.nativedemo.dds.DDSManager; | |||
import com.aispeech.nativedemo.entity.Emp; | |||
import com.aispeech.nativedemo.face.FaceChatMode; | |||
import com.aispeech.nativedemo.face.FaceManager; | |||
import com.aispeech.nativedemo.mqtt.MqttManager; | |||
import com.aispeech.nativedemo.network.ws.MessageUtils; | |||
@@ -324,7 +325,7 @@ public class AlertWindowView extends ConstraintLayout implements FaceManager.Upd | |||
private void initManager(Context context) { | |||
mWSManager = WebSocketManager.getInstance(mActivity.getApplicationContext()); | |||
mFaceManager = FaceManager.getInstance(mActivity.getApplicationContext()); | |||
mFaceManager = FaceManager.getInstance(); | |||
mFaceManager.setCallback(this); | |||
mCameraController = CameraController.getInstance(mActivity.getApplicationContext()); | |||
mCameraController.initTexture(mTextureView); | |||
@@ -477,17 +478,17 @@ public class AlertWindowView extends ConstraintLayout implements FaceManager.Upd | |||
try { | |||
Log.e(TAG, "-----------------detect face----------------"); | |||
textureBitmap = mTextureView.getBitmap(); | |||
List<MultiAtt> results = mFaceManager.detectMultiAtt(textureBitmap); | |||
List<MultiAtt> results = FaceChatMode.detectMultiAtt(textureBitmap); | |||
if (results != null && results.size() > 0) { | |||
mFaceManager.filterPersonForFeatExtract(results); | |||
FaceChatMode.filterPersonForFeatExtract(results, textureBitmap); | |||
//删除过期人员 | |||
mFaceManager.deleteExpirePerson(); | |||
FaceChatMode.deleteExpirePerson(); | |||
boolean isContinue = mFaceManager.featExtract(results, textureBitmap); | |||
boolean isContinue = FaceChatMode.featExtract(results, textureBitmap); | |||
if(isContinue){ | |||
DDSManager.getInstance().wakeUpDDSDialog(); | |||
mFaceManager.confirmCurrentPerson(textureBitmap); | |||
FaceChatMode.confirmCurrentPerson(textureBitmap); | |||
} | |||
// if(!mFaceManager.hasPerson()){ | |||
// DDSManager.getInstance().stopDDSDialog(); | |||