Android
1. 名词解释
名词 | 释义 |
---|---|
oauthToken | 授权凭证接口获取的access_token |
deviceSerial | 设备序列号 |
channelNo | 设备通道号 |
deviceSerial + channelNo | 摄像头唯一标志 |
PTZ | 云台控制,通过终端控制操作设备 |
2. 功能介绍
功能 | 说明 |
---|---|
预览 | 直播预览,可设置直播分辨率 |
回放(SD卡、云存储) | 回放:SD卡(本地)、云存储 |
设备对讲 | 对讲(包含半双工对讲和全双工对讲) |
预览、回放边播边录 | 播放过程中录像 |
预览、回放边播边截屏 | 播放过程中截屏 |
设备的设置功能 | 提供设备设置接口api(声音、清晰度等) |
云台控制 | 设备控制接口(云台、变倍画面) |
可视对讲 | 可视对讲(接听、拒接、挂断) |
3. 快速集成
3.1. 环境准备
3.2. Token获取
3.3. SDK下载
3.4. SDK集成
android{
defaultConfig {
...
ndk {
abiFilters "armeabi-v7a", "arm64-v8a"
}
}
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
...
repositories
{
flatDir {
dirs 'libs'
}
}
}
ndk {
abiFilters "armeabi-v7a", "arm64-v8a"
}
dependencies {
implementation(name: 'CloudOpenSDK-x.x.x',ext:'aar') //x.x.x对应的是SDK的版本号
implementation 'com.google.code.gson:gson:2.8.5'
implementation 'com.squareup.okhttp3:okhttp:3.8.1' //3.8.1或以上
implementation 'javax.jmdns:jmdns:3.4.1'
}
3.5. 配置权限
//网络状态权限
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
//网络权限
<uses-permission android:name="android.permission.INTERNET"/>
//录音权限
<uses-permission android:name="android.permission.RECORD_AUDIO" />
//存储权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
//可视对讲所需权限
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
3.6. 代码混淆
-dontwarn com.ezviz.**
-keep class com.ezviz.** { *;}
-dontwarn com.ez.**
-keep class com.ez.** { *;}
-dontwarn com.hc.**
-keep class com.hc.** { *;}
-dontwarn com.neutral.netsdk.**
-keep class com.neutral.netsdk.** { *;}
-dontwarn com.hik.**
-keep class com.hik.** { *;}
-dontwarn com.hikvision.audio.**
-keep class com.hikvision.audio.** { *;}
-dontwarn com.hikvision.keyprotect.**
-keep class com.hikvision.keyprotect.** { *;}
-dontwarn com.hikvision.sadp.**
-keep class com.hikvision.sadp.** { *;}
-dontwarn com.hikvision.netsdk.**
-keep class com.hikvision.netsdk.** { *;}
-dontwarn com.hikvision.wifi.**
-keep class com.hikvision.wifi.** { *;}
-dontwarn com.hikvision.cloud.sdk.**
-keep class com.hikvision.cloud.sdk.** { *;}
-dontwarn com.videogo.**
-keep class com.videogo.** { *;}
-dontwarn okhttp3.**
-keep class okhttp3.** { *;}
-dontwarn com.mediaplayer.audio.**
-keep class com.mediaplayer.audio.** { *;}
-dontwarn org.MediaPlayer.PlayM4.**
-keep class org.MediaPlayer.PlayM4.** { *;}
-dontwarn com.sun.jna.**
-keep class com.sun.jna.**{*;}
#Gson混淆配置
-keepattributes Annotation
-keep class sun.misc.Unsafe { *; }
-keep class com.idea.fifaalarmclock.entity.*
-keep class com.google.gson.stream.* { *; }
#引用mars的xlog,混淆配置
-keep class com.tencent.mars.** {
public protected private *;
}
3.7. SDK初始化
CloudOpenSDK.getInstance()
.setLogDebugMode(true) // 默认日志开关状态:打开,正式发布需要关掉
//sdk数据缓存加密开关(例如SP存储),放在init()方法前设置
.setDataCacheEncrypt(true, "123456")//密码长度不限制
.init(
this,
"服务端下发的oauthToken",
new OnCommonCallBack() {
@Override
public void onSuccess() {
Log.d("AppApplication", "初始化成功");
}
@Override
public void onFailed(Exception e) {
Log.d("AppApplication", "初始化失败");
}
});
3.8. 预览
// 预览
// 创建播放器
CloudVideoPlayer player=CloudOpenSDK.getInstance().createPlayer(mDeviceSerial, mChannelNo);
// 设置播放器的显示
Surface player.setSurfaceHolder(mSurfaceView.getHolder());
// 设备如果设置了视频加密,需要设置视频加密密码,默认为设备的6位验证码
player.setPlayVerifyCode("设备验证码");
// 开始预览播放
player.startRealPlay();
// 设置播放监听
player.setOnRealPlayListener(new CloudVideoPlayer.OnRealPlayListener() {
@Override
public void onVideoSizeChanged(int videoWidth, int videoHeight) {} @Override public void onRealPlaySuccess() {
// 播放成功
}
@Override
public void onStopRealPlaySuccess() {// 停止播放成功}
@Override
public void onRealPlayFailed(int errorCode, String moduleCode, String description, String sulution) {
if (errorCode == 400035 || errorCode == 400036) {
// 回调时查看errorCode,如果为400035(需要输入验证码)和400036(验证码错误),则需要开发者自己处理让用户重新输入验证密码,并调用setPlayVerifyCode设置密码,然后重新启动播放
}
}
});
//停止直播
player.stopRealPlay();
//释放资源
player.release();
//开启录像,recordFile录制本地路径,例如:
Environment.getExternalStorageDirectory().getPath()+"/abc" player.startLocalRecordWithFile(String recordFile)
//结束本地直播流录像与startLocalRecordWithFile成对使用
player.stopLocalRecord()
//截图
player.capturePicture()
//声音开关
player.openSound();
player.closeSound();
//PTZ 云台控制接口,该接口为耗时操作,必须在线程中调用
CloudOpenSDK.getInstance().controlPTZ(
String deviceSerial, //设备序列号
int channelNo, //通道号
EZConstants.EZPTZCommand command,//ptz控制命令
EZConstants.EZPTZAction action,//控制启动/停止
int speed);//速度(0-2)
/**
* 设置指定监控点视频清晰度
* <p>
* 该接口为耗时操作,必须在线程中调用
* </p>
*
* @param videoLevel 清晰度 0-流畅 1-均衡 2-高品质 3-超清
* @return
*/
player.setVideoLevel(levelVal);
//设置成功
// 停止播放 Stop play
player.stopRealPlay();
// 开始播放 start play
player.startRealPlay();
3.9. 回放
//回放
CloudVideoPlayer player =
CloudOpenSDK.getInstance().createPlayer(mDeviceSerial, mChannelNo);
//设置播放器的显示Surface
player.setSurfaceHolder(mBackPlayerSv.getHolder());
//设备加密的需要传入密码
//该接口必须在收到400035(需要输入验证码)和400036(验证码错误)错误回调时调用
player.setPlayVerifyCode(ConfigCst.VERIFY_CODE); //设置回放回调
player.setOnBackPlayListener(new CloudVideoPlayer.OnBackPlayListener() {
@Override
public void onVideoSizeChanged(int videoWidth, int videoHeight) {}
@Override
public void onBackPlaySuccess() {//回放成功}
@Override
public void onStopBackPlaySuccess() {//停止回放成功}
@Override
public void onBackPlayFailed(int errorCode, String moduleCode, String description, String sulution) {
if (errorCode == 400035 || errorCode == 400036) {
//回调时查看errorCode,如果为400035(需要输入验证码)和400036(验证码错误),则需要开发者自己处理让用户重新输入验证密码,并调用setPlayVerifyCode设置密码,然后重新启动播放
}
}
});
/**
* 开始云存储远程回放
* @param cloudFile 云存储文件信息 参见下文中的 查询云存储录像信息列表
* @return true 表示成功, false 表示失败
*/
player.startPlayback(EZCloudRecordFile cloudFile);
//或者
/**
* 开始远程SD卡回放
* @param deviceFile SD卡文件信息 参见下文中的 查询远程SD卡存储录像信息列表
* @return true 表示成功, false 表示失败
*/
player.startPlayback(EZDeviceRecordFile deviceFile);
//或者
/**
* 开始远程SD卡回放---按时间回放
* @param startTime 开始时间
* @param stopTime 结束时间
* @return true 表示成功, false 表示失败
*/
player.startPlayback(Calendar startTime, Calendar stopTime);
//停止远程回放
player.stopPlayback();
/**
* 查询云存储录像信息列表
* 该接口中有网络操作,需要在线程中调用
* @param deviceSerial 设备序列号
* @param cameraNo camera的序号,EZCameraInfo.cameraNo
* @param startTime 查询时间范围开始时间
* @param endTime 查询时间范围结束时间
* @return 云存储录像信息列表
* @throws BaseException
*/
CloudOpenSDK.getEZOpenSDK().searchRecordFileFromCloud(String deviceSerial, int cameraNo, Calendar startTime, Calendar endTime);
/**
* 查询远程SD卡存储录像信息列表
* 该接口为耗时操作,必须在线程中调用
*/
CloudOpenSDK.getEZOpenSDK().searchRecordFileFromDevice(String deviceSerial, int cameraNo, Calendar startTime, Calendar endTime);
/**
* 设置回放的倍数(快慢)
* {@link com.videogo.openapi.EZConstants.EZPlaybackRate}
* <li>1倍: EZ_PLAYBACK_RATE_1(1)</li>
* <li>4倍: EZ_PLAYBACK_RATE_4(4)</li>
* <li>1/4倍: EZ_PLAYBACK_RATE_4_1(5)</li>
* <li>6倍: EZ_PLAYBACK_RATE_8(6)</li>
* <li>1/8倍: EZ_PLAYBACK_RATE_8_1(7)</li>
* <li>16倍: EZ_PLAYBACK_RATE_16(8)</li>
* <li>1/16倍:EZ_PLAYBACK_RATE_16_1(9)</li>
*
* @param rate
* @return
*/
player.setPlaybackRate(EZConstants.EZPlaybackRate rate);
3.10. 可视对讲
CloudVideoPlayer player =
CloudOpenSDK.getInstance().createPlayer(mDeviceSerial, mChannelNo);
//设备加密的需要传入密码
//该接口必须在收到400035(需要输入验证码)和400036(验证码错误)错误回调时调用
player.setPlayVerifyCode(String verifyCode);
//开启对讲
player.startVoiceTalk();
//关闭对讲
player.stopVoiceTalk();
//注意对于半双工对讲:需要调用上面接口开启对讲
//开启对讲后能听到设备端声音,但是设备端听不到自己的声音,需要以下操作
setVoiceTalkStatus
//设备端听,手机端说
player.setVoiceTalkStatus(true);
//手机端听,设备端说
player.setVoiceTalkStatus(false);
//设置对讲监听
player.setOnVoiceTalkListener(new
CloudVideoPlayer.OnVoiceTalkListener() {
@Override
public void onVoiceTalkSuccess() {
}
@Override
public void onVoiceTalkFail(int errorCode, String moduleCode, String
description, String sulution) {
//回调时查看errorCode,如果为400035(需要输入验证码)和400036(验证码错误),
//则需要开发者自己处理让用户重新输入验证密码,并调用setPlayVerifyCode设置密码,然后
重新启动播放
}
});
TalkCallInfo talkCallInfo = new TalkCallInfo();
talkCallInfo.setDeviceSerial(mDeviceSerial);//设备序列号
talkCallInfo.setRoomNum("102");//房间号,例如102中1是楼层号,02是房间号
talkCallInfo.setPeriodNumber("1");//期号
talkCallInfo.setBuildingNumber("1");//楼号
talkCallInfo.setUnitNumber("1");//单元号
talkCallInfo.setFloorNumber("1");//层号
talkCallInfo.setDevIndex("1");//设备序号,非必填
talkCallInfo.setUnitType(HConfigCst.UnitType.WALL);//类型: outdoor门口机,wall围墙机
/**
* 同步信令 包括接听 挂断 拒接等等
* cmdType:HConfigCst.CallCommand.CALL_ANSWER 接听
* cmdType:HConfigCst.CallCommand.CALL_HANGUP 挂断
* cmdType:HConfigCst.CallCommand.CALL_REJECT 拒接
* cmdType:HConfigCst.CallCommand.BELL_TIMEOUT 响铃超时
*/
public void
sendVideoIntercomCallSignal(final TalkCallInfo talkCallInfo,final String cmdType,final OnCommonCallBack cb) {
VideoIntercomCallManager.sendVideoIntercomCallSignal(talkCallInfo,cmdType, cb);
}
//调用方法
CloudOpenSDK.getInstance().sendVideoIntercomCallSignal(talkCallInfo,
HConfigCst.CallCommand.CALL_HANGUP,
new OnCommonCallBack() {
@Override
public void onSuccess() {//挂断成功}
@Override
public void onFailed(Exception e) {}
});
/**
* 获取通话状态
*/
public void getVideoIntercomCallStatus(final String deviceSerial,final OnCommonCallBackV2<String> cb);
//调用,返回状态有三种:
//空闲:HConfigCst.IDLE
//响铃中:HConfigCst.RING
//通话中:HConfigCst.ONCALL
CloudOpenSDK.getInstance().getVideoIntercomCallStatus("设备序列号",
new OnCommonCallBackV2<String>() {
@Override
public void onSuccess(String data) {
if (HConfigCst.CallStatus.RING.equals(status)) {
//TODO接听、拒接
}
}
@Override
public void onFailed(Exception e) {}
});
3.11. 局域网设备预览
1、在局域网设备预览前,请确保设备已配网或已连网。
2、在局域网设备预览前,请确保手机与设备处于同一局域网或手机直接连接支持热点模式的设备。
1、在同一局域网下,搜索到该设备或者手动添加该设备。
2、判断该设备是否激活。
3、判断该设备是否多通道。
4、进行登录操作,登陆成功后进行局域网预览相关操作。
3.11.1找到该设备信息
EZHCNetDeviceSDK.getInstance().startLocalSearch()
接口进行搜索,搜索到一台设备就回调一次EZSADPDeviceInfo
信息。1、搜索到的
EZSADPDeviceInfo.getDeviceSerial()
中的序列号是全信息(例如CS-C6CN-3B2WFR0120181201CCCHC74540922),真正的序列号为最后几位(例如C74540922),可根据这个进行判断相对应的设备。2、搜索接口可能长时间没有返回结果(原因:1.不在同一局域网;2.该局域网下没有设备;3.扫描超时;),这时候建议开发者设置一个超时时间或者重试机制。
3、记得在功能使用结束后或者页面的onDestroy()处,调用EZHCNetDeviceSDK.getInstance().stopLocalSearch()停止搜索。
4、建议在调用
startLocalSearch()
前请调用下stopLocalSearch()
方法。 //局域网设备搜索开始接口
EZHCNetDeviceSDK.getInstance().startLocalSearch(new EZHCNetDeviceSDK.SadpDeviceFoundListener() {
@Override
public void onDeviceFound(final EZSADPDeviceInfo sadpDeviceInfo) {
LogUtil.d(TAG,
"onDeviceFound " + sadpDeviceInfo.getDeviceSerial() + " " + sadpDeviceInfo.getDeviceSerial());
//判断设备是否已激活
if (sadpDeviceInfo.isActived()){
//已激活,则进行下一步的操作
}else{
//未激活,则先跳到激活页面进行激活操作
}
}
});
//局域网设备激活接口,这里的序列号为全序列号信息
EZHCNetDeviceSDK.getInstance().activeDeviceWithSerial(mSeriNo, mPassword)
//局域网设备搜索停止接口
EZHCNetDeviceSDK.getInstance().stopLocalSearch();
3.11.2.局域网登录
/**
* 如果知道设备的IP和端口号,则不需要进行搜索操作,可直接进行登录操作
*
* @param userName 设备管理员名称,默认admin
* @param pwd 设备管理员密码,海康设备默认为Hik+验证码,萤石设备默认为验证码
* @param deviceip 设备Ip地址
* @param port 设备端口号
*/
EZHCNetDeviceSDK.getInstance().loginDeviceWithUerName(String userName, String pwd, String deviceip, int port);
3.11.3.是否多通道
if (loginDeviceInfo.getByChanNum() + loginDeviceInfo.getByIPChanNum() > 1) {
// 多通道
} else if (loginDeviceInfo.getByChanNum() + loginDeviceInfo.getByIPChanNum() == 1) {
if (loginDeviceInfo.getByChanNum() > 0) {
//单通道
} else {
//没有通道,例如NVR下面没有挂载任何设备
}
} else {
//设备不支持预览操作
showNotSupportViewDailog();
}
3.11.4.局域网预览
//局域网预览
//创建播放器
LanVideoPlayer mLanVideoPlayer = CloudOpenSDK.getInstance().createLanPlayer(mUserId, mChannelNo, 1);
mLanVideoPlayer.setSurfaceHolder(mSurfaceView.getHolder());
//设置播放监听
mLanVideoPlayer.setLanPlayListener(new CloudOpenSDKListener.OnLanRealPlayListener() {
@Override
public void onVideoSizeChanged(int videoWidth, int videoHeight) {
}
@Override
public void onRealPlaySuccess() {
LogUtils.deBug("LanVideoPlayer onRealPlaySuccess");
//预览成功
}
@Override
public void onStopRealPlaySuccess() {
LogUtils.deBug("LanVideoPlayer onStopRealPlaySuccess");
//停止预览成功
}
@Override
public void onRealPlayFailed(int errorCode, String moduleCode, String description, String sulution) {
LogUtils.deBug("LanVideoPlayer onRealPlayFailed");
//预览失败
}
});
//开始预览
mLanVideoPlayer.startRealPlay();
//释放资源
mLanVideoPlayer.release();
//停止预览
mLanVideoPlayer.stopRealPlay();
//开启声音
mLanVideoPlayer.openSound();
//关闭声音
mLanVideoPlayer.closeSound();
//开始录制
mLanVideoPlayer.startRecordingEx(recordPath);
//停止录制
mLanVideoPlayer.stopRecordingEx();
//抓图
mLanVideoPlayer.capturePicture(picPath);
4. 错误码
错误码 | 说明 |
---|---|
10100 | 服务器异常 |
10101 | 服务平台服务器返回数据异常 |
10102 | 接口调用过于频繁 |
10105 | 请求包含语法错误或无法完成请求 |
10110 | SDK初始化失败 |
10111 | SDK未初始化,请初始化 |
10125 | token失效,请刷新 |
10150 | 同步信令失败 |
10151 | 获得可视对讲通话状态异常 |
10160 | 云台控制操作异常 |