本章节详细介绍在Android平台如何快速方便添加IPC SDK
1、拓扑图
IPC设备和Android设备连接拓扑图如下:
1、Android设备有一套自有的用户管理模块,有唯一ID识别机制。Android设备在管理用户时,需要保留一张用户人脸图片。
2、IPC设备使用人脸图片作为识别预输入。
3、Android设备激活IPC设备后,通过局域网把用户人脸图片以及与用户唯一关联的ID传递给IPC设备
4、IPC设备从人脸图片提取人脸特征值,并把特征值与用户ID保存到数据库。
5、IPC设备监控到用户进入,查询注册的数据库,返回用户唯一ID的IPC设备。
6、Android设备获取到唯一ID值后,在用户管理模块根据该唯一ID进行查询,显示用户信息
2、IPC激活
IPC设备使用时,如果未激活,需要先激活IPC设备。激活步骤如下:
2.1 SDK初始化
APP_ID:激活与API调用校验使用的账号。
SECRET_KEY:API调用所需的签名密钥。
LICENSE:激活API所需的激活码。
IPCameraManager mIPCameraManager = IPCameraManager.getInstance(context);
mIPCameraManager.init(APP_ID, SECRET_KEY, LICENSE);
2.2 配网
IPC设备激活时需要连接到互联网。IPC连接互联网时,可以通过无线(wifi)或有线(以太网口)连接到路由器。无线连接时需要做配网设置。
有线接入:
有线接入只需要通过网线把IPC设备和集成SDK的Android设备接入到同一局域网即可,不需要其它设置。
无线接入:
无线配网方式相对要复杂点,步骤如下:
- 使用手机/PC的无线网卡扫描IPC的AP热点,一般AP热点的名称为SUNMI_XXXX,其中XXXX为MAC地址最后2个字节的16进制数字,MAC地址可以通过设备机身后背的标贴或者包装盒的标贴查到,AP热点本身是无加密的。
- 使用手机/PC的无线网卡连接IPC的AP热点,此时手机/PC就会获取到IPC分配的IP地址(按照设备发现描述的方法即可获取到),一般会是192.168.200.XXX,手机/PC的网关地址就是IPC的地址,一般会是192.168.200.1。
- 调用无线配置 API(见获取无线扫描AP列表 (无需签名校验)的描述)获取IPC扫描到的AP热点。
- 调用无线配置 API(见设置无线参数(无需签名校验)的描述)设置IPC要连接的无线网络(例如无线路由器的SSID和密码),使得IPC能够从网关处获取到IP地址。
- 如果网络是可以正常上网的话,IPC取到IP地址后很快就会亮蓝灯,此时表明IPC可以正常连接Internet了。
// 获取IPC扫描的AP热点
private void getWifiList() {
BasicConfig.getInstance(context).getApListWithoutAuth(sunmiDevice.getDeviceid(),
new RPCCallback‹RPCResponse‹IpcApBean››() {
@Override
public void onComplete(RPCResponse‹IpcApBean› result) {
if (result.code() == RPCErrorCode.SUCCESS) {
wifiListGetSuccess(result.data());
} else {
Log.i(TAG, "getApListWithoutAuth failed, errcode: " + result.code());
}
}
});
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
if (wifiList.size() == 0) {
setNoWifiVisible(View.VISIBLE);
}
}
}, TIMEOUT_GET_WIFI);
}
// 设置IPC连接的AP热点
private void setIpcWifi(String ssid, String psw) {
showLoadingDialog();
BasicConfig.getInstance(context).setWifiConfWithoutAuth(sunmiDevice.getDeviceid(),
ssid, psw, new RPCCallback‹RPCResponse›() {
@Override
public void onComplete(RPCResponse result) {
if (result.code() == RPCErrorCode.SUCCESS) {
hideLoadingDialog();
shortTip("配置成功,请等待设备联网,联网后指示灯会变成蓝色");
createWaitDialog();
} else {
hideLoadingDialog();
shortTip("配置失败");
}
}
@Override
public void onError(Throwable t) {
hideLoadingDialog();
shortTip("配置失败");
}
});
}
2.3 激活
通过 2.2配网 后,IPC通过无线连接到路由或者直接有线连接路由。
由于使用IPC的其它API时需要签名校验,所以在使用API之前需要激活IPC。激活只需要在第一次使用IPC时进行,后续都不再需要激活。
调用active接口既可以激活IPC设备。 代码如下:
//激活ipc设备,并设置回调接口
DeviceManage.getInstance(context).activate(ipcList.get(postion).getDeviceid(),
new RPCCallback‹RPCResponse›() {
//IPC返回相关错误码。
@Override
public void onComplete(RPCResponse result) {
if (result.code() == RPCErrorCode.SUCCESS || result.code() == RPCErrorCode.DEVICE_ACTIVATED) {
Log.i(TAG, "activate ipc success");
} else {
Log.i(TAG, "activate ipc failed");
}
}
//网络问题导致无法通信,会调用onError接口
@Override
public void onError(Throwable t) {
Log.i(TAG, "activate ipc failed");
}
});
2.4 画面调整
由于IPC的人脸识别对于人脸图像质量有一定要求,因此在使用IPC前需要调整IPC的画面,以达到最好的体验效果。画面调整包括镜头的调焦、对焦。步骤如下:
2.4.1 RTSP 播放
首先需要通过预览画面查看IPC设备镜头是对焦,画面是否清晰。IPC设备是通过RTSP协议传递视频流,所以开发一款RTSP播放器才能看到视频流。
调用VideoStream.getInstance(context).getLiveStream接口可以获取到RTSP播放流的地址。代码流程如下:
private void openMediaPlayer() {
new Thread(new Runnable() {
@Override
public void run() {
//获取播放流
VideoStream.getInstance(context).getLiveStream(mDevice.getDeviceid(),
new RPCCallback‹RPCResponse‹RPCResponse.LiveAddressBean››() {
@Override
public void onComplete(RPCResponse‹RPCResponse.LiveAddressBean› result) {
if (result.code() == RPCErrorCode.SUCCESS) {
Log.i(TAG, "live url: " + result.data().fhd_live_url);
if (mPlayer == null) {
//自定义的rtsp播放器
mPlayer = new SunmiPlayer(context);
mPlayer.setListener(new SunmiPlayerListener() {
@Override
public void onPrepared(IMediaPlayer iMediaPlayer) {
iMediaPlayer.start();
}
});
mPlayer.setSurface(mVideoView.getHolder().getSurface());
//获取到ipc返回的播放流rtsp地址
String liveUrl = result.data().fhd_live_url.replaceFirst("^rtsp://", "rtsp://admin:admin@");
//自定义播放器开始播放rtsp视频流
mPlayer.setUp(liveUrl);
}
}
}
});
}
}).start();
}
2.4.2 调焦、对焦
private BasicConfig mBasicConfig;
public void init() {
...
mBasicConfig = BasicConfig.getInstance(context);
...
}
// 调焦
private void func1(){
...
mBasicConfig.setZoom(mDevice.getDeviceid(), zfBean.zoom, new RPCCallback‹RPCResponse›() {
@Override
public void onComplete(RPCResponse result) {
Log.i(TAG, "setZoom, code:" + result.code());
}
});
...
}
// 自动对焦
private void func2() {
...
mBasicConfig.autoFocus(mDevice.getDeviceid(), xRelative, yRelative, new RPCCallback‹RPCResponse›() {
@Override
public void onComplete(RPCResponse result) {
Log.d(TAG, "autoFocus, code:" + result.code());
if (result.code() == RPCErrorCode.SUCCESS) {
mBasicConfig.getZoomFocusConf(mDevice.getDeviceid(), new RPCCallback‹RPCResponse‹RPCResponse.ZoomFocusBean››() {
@Override
public void onComplete(RPCResponse‹RPCResponse.ZoomFocusBean› result) {
if (result.code() == RPCErrorCode.SUCCESS) {
zfBean = result.data();
mSbZoom.setProgress(zfBean.zoom);
}
}
});
}
}
});
...
}
// 自动对焦如果不够清晰,可以手动对焦进行微调
private void func3() {
...
mBasicConfig.manualFocus(mDevice.getDeviceid(), focus, new RPCCallback‹RPCResponse›() {
@Override
public void onComplete(RPCResponse result) {
if (result.code() == RPCErrorCode.SUCCESS) {
zfBean.focus = focus;
}
}
});
....
}
2.4.3 设置门线
设置门线主要是更精确地判断人流的方向(进门、出门、路过),提高人流统计的准确度。
调用接口PeopleFlowStats.getInstance(context).setDoorLine设置门线。代码如下:
private void func() {
...
PeopleFlowStats.getInstance(context).setDoorLine(mDevice.getDeviceid(), 0, lineStart[0],
lineStart[1], lineEnd[0], lineEnd[1], new RPCCallback‹RPCResponse›() {
@Override
public void onComplete(RPCResponse result) {
if (result.code() == RPCErrorCode.SUCCESS) {
stopPlay();
finish();
startActivity(new Intent(context, MainActivity.class));
}
}
});
...
}
3、注册人脸
IPC激活好以后,向设备注册人脸信息。
Android设备端注册人脸时,需要同步向IPC设备注册人脸需要传递用户人脸照片、以及唯一标识用户的ID。
通过接口IPCameraManager.getInstance(context).addFaceRecord向IPC注册人脸。代码如下:
/*
*传递人脸照片路径: picPath,
* 用户唯一ID: uid
*/
IPCameraManager.getInstance(context).addFaceRecord(picPath, uid, new RPCCallback‹RPCResponse›() {
//IPC设备调用成功后会调用onComplete
@Override
public void onComplete(RPCResponse result) {
Log.i(TAG, "addFaceRecord, code:" + result.code());
if (result.code() != 0){
showToast(context, "添加人脸失败 code: " + result.code());
} else {
showToast(context, "添加人脸成功");
}
}
//IPC设备离线时,调用会调用onError
@Override
public void onError(Throwable t) {
super.onError(t);
Log.i(TAG, "addFaceRecord, Exception:" + t.getMessage());
showToaste(context, "添加人脸失败 ");
}
});
4、删除人脸
Android设备端删除用户时,需要同步删除IPC设备的人脸信息。Andorid端设备需要传递用户唯一ID。
调用接口 IPCameraManager.getInstance(context).addFaceRecord 向IPC删除人脸。代码如下:
//传递用户唯一ID:userId
IPCameraManager.getInstance(context).deleteFaceRecord(userId,new RPCCallback‹RPCResponse‹RPCResponse.FaceDeleteSubResult››() {
@Override
public void onComplete(RPCResponse‹RPCResponse.FaceDeleteSubResult› result) {
Log.i(TAG, "deleteFaceRecord, code:" + result.code());
if (result.code() != 0){
showToast(context, "删除人脸失败 code: " + result.code());
} else {
showToast(context, "删除人脸成功");
}
}
@Override
public void onError(Throwable t) {
super.onError(t);
Log.i(TAG, "addFaceRecord, Exception:" + t.getMessage());
}
});
5、 监听人脸识别消息
Android设备注册好人脸信息后,即可以监听IPC设备人脸识别信息。通过IPC返回的ID信息,查询数据库,显示用户详细信息。
调用IPCameraManager.getInstance(context).setFaceDetectListener即可监听人脸信息,代码如下:
IPCameraManager.getInstance(context).setFaceDetectListener(new FaceDetectListener() {
@Override
public void onFaceDetect(String userId) {
String userName = null;
if (userName == null) {
showToast(getApplicationContext(), "未注册的用户进店");
} else {
showToast(getApplicationContext(), "用户[ " + userName + " ]进店");
}
}
});