Android平台上集成海康SDK
以上是我之前写的一篇Android平台上集成海康SDK的文章,其中对于Android平台上集成海康SDK、基于海康SDK进行二次开发基本上进行了详细地介绍。

这篇文章,在之前的基础上我对代码进行了优化和封装,我们来看,

/*** Created by Administrator on 2017/2/28.* 封装的海康播放库*/
public class PlayerHikvision {private static final String TAG = "Hikvision";public int mLogId = -1;public int mPort = -1;public int mPlayId = -1;public int mPlaybackId = -1;private SurfaceView surfaceView;public boolean mStopPlayback;private Handler handler;private int chanNo;public PlayerHikvision(SurfaceView surfaceView, Handler handler) {this.surfaceView = surfaceView;this.handler = handler;}/*** 登录设备* @param ip* @param port* @param userName* @param password* @param channelNo*/private void login(String ip, int port, String userName, String password, int channelNo) {HCNetSDK.getInstance().NET_DVR_Init();  //初始化海康的Device Network SDKNET_DVR_DEVICEINFO_V30 oNetDvrDeviceInfoV30 = new NET_DVR_DEVICEINFO_V30();  //设备参数mLogId = HCNetSDK.getInstance().NET_DVR_Login_V30(ip, port, userName, password, oNetDvrDeviceInfoV30);  //调用设备登录接口LogUtils.i(TAG, "logId:" + mLogId);if (mLogId == -1) {  //登录失败int errorCode = HCNetSDK.getInstance().NET_DVR_GetLastError();  //得到错误码,并根据错误码得到具体原因switch (errorCode) {case 1:messageFeedback("连接设备失败:设备的用户名或者密码错误");  //设备的用户名或者密码错误break;case 7:messageFeedback("连接设备失败:设备离线或者连接超时");  //连接设备失败:设备离线或者连接超时break;default:messageFeedback("连接设备失败:其他错误");  //连接设备失败:其他错误break;}} else {  //成功登录设备,动态换算通道号NET_DVR_IPPARACFG_V40 net_dvr_ipparacfg_v40 = new NET_DVR_IPPARACFG_V40();  //IP设备资源和IP通道资源配置HCNetSDK.getInstance().NET_DVR_GetDVRConfig(mLogId, HCNetSDK.NET_DVR_GET_IPPARACFG_V40, 0, net_dvr_ipparacfg_v40);  //获取设备设置信息LogUtils.i(TAG, "模拟通道数:" + net_dvr_ipparacfg_v40.dwAChanNum);LogUtils.i(TAG, "IP通道数:" + net_dvr_ipparacfg_v40.dwDChanNum);if (net_dvr_ipparacfg_v40.dwAChanNum == 0 && net_dvr_ipparacfg_v40.dwDChanNum == 0) {chanNo = channelNo;} else {if (channelNo > net_dvr_ipparacfg_v40.dwAChanNum) {chanNo = (channelNo - net_dvr_ipparacfg_v40.dwAChanNum) + 32;} else {chanNo = channelNo;}}}}/*** 实时预览* @param ip* @param port* @param userName* @param password* @param streamType* @param channelNo*/public void live(String ip, int port, String userName, String password, int streamType, int channelNo) {if (mLogId == -1) {  //未登录设备,先登录设备login(ip, port, userName, password, channelNo);}if (mLogId != -1) {  //已经登录设备,下一步:实时预览RealPlayCallBack fRealDataCallBack = getRealPlayerCbf();  //得到实时预览回调if (fRealDataCallBack == null) {LogUtils.e(TAG, "实时预览回调对象创建失败");messageFeedback("实时预览失败");return;}NET_DVR_PREVIEWINFO previewInfo = new NET_DVR_PREVIEWINFO();  //实时预览设置previewInfo.lChannel = chanNo;  //通道号previewInfo.dwStreamType = streamType;  //码流类型previewInfo.bBlocked = 1;  //阻塞流获取mPlayId = HCNetSDK.getInstance().NET_DVR_RealPlay_V40(mLogId, previewInfo, fRealDataCallBack);  //调用实时预览接口if (mPlayId == -1) {  //实时预览失败if (streamType == 1) {previewInfo.dwStreamType = 0;  //尝试换一种码流播放mPlayId = HCNetSDK.getInstance().NET_DVR_RealPlay_V40(mLogId, previewInfo, fRealDataCallBack);if (mPlayId == -1) {LogUtils.e(TAG, "实时预览失败,错误码:" + HCNetSDK.getInstance().NET_DVR_GetLastError());messageFeedback("实时预览失败");return;}} else {LogUtils.e(TAG, "实时预览失败,错误码:" + HCNetSDK.getInstance().NET_DVR_GetLastError());messageFeedback("实时预览失败");return;}}}}/*** 远程回放* @param ip* @param port* @param userName* @param password* @param channelNo* @param beginYear* @param beginMonth* @param beginDay* @param beginHour* @param beginMinute* @param beginSecond* @param endYear* @param endMonth* @param endDay* @param endHour* @param endMinute* @param endSecond*/public void playback(String ip, int port, String userName, String password, int channelNo,int beginYear, int beginMonth, int beginDay, int beginHour, int beginMinute, int beginSecond,int endYear, int endMonth, int endDay, int endHour, int endMinute, int endSecond) {if (mLogId == -1) {  //未登录设备,先登录设备login(ip, port, userName, password, channelNo);}if (mLogId != -1) {  //已经登录设备,下一步:远程回放PlaybackCallBack fPlaybackCallBack = getPlaybackPlayerCbf();  //得到远程回放回调if (fPlaybackCallBack == null) {LogUtils.e(TAG, "远程回放回调对象创建失败");messageFeedback("远程回放失败");return;}NET_DVR_TIME beginTime = new NET_DVR_TIME();NET_DVR_TIME endTime = new NET_DVR_TIME();beginTime.dwYear = beginYear;beginTime.dwMonth = beginMonth;beginTime.dwDay = beginDay;beginTime.dwHour = beginHour;beginTime.dwMinute = beginMinute;beginTime.dwSecond = beginSecond;endTime.dwYear = endYear;endTime.dwMonth = endMonth;endTime.dwDay = endDay;endTime.dwHour = endHour;endTime.dwMinute = endMinute;endTime.dwSecond = endSecond;mPlaybackId = HCNetSDK.getInstance().NET_DVR_PlayBackByTime(mLogId, chanNo, beginTime, endTime);  //调用远程回放接口if (mPlaybackId != -1) {if (!HCNetSDK.getInstance().NET_DVR_SetPlayDataCallBack(mPlaybackId, fPlaybackCallBack)) {LogUtils.e(TAG, "设置远程回放回调失败,错误码:" + HCNetSDK.getInstance().NET_DVR_GetLastError());messageFeedback("远程回放失败");return;}NET_DVR_PLAYBACK_INFO net_dvr_playback_info = null;if (!HCNetSDK.getInstance().NET_DVR_PlayBackControl_V40(mPlaybackId, PlaybackControlCommand.NET_DVR_PLAYSTART, null, 0, net_dvr_playback_info)) {LogUtils.e(TAG, "远程回放开始失败,错误码:" + HCNetSDK.getInstance().NET_DVR_GetLastError());messageFeedback("远程回放失败");return;}mStopPlayback = false;} else {LogUtils.e(TAG, "远程回放失败,错误码:" + HCNetSDK.getInstance().NET_DVR_GetLastError());messageFeedback("远程回放失败");}}}/*** 获取录像段文件* @param ip* @param port* @param userName* @param password* @param channelNo* @param beginYear* @param beginMonth* @param beginDay* @param beginHour* @param beginMinute* @param beginSecond* @param endYear* @param endMonth* @param endDay* @param endHour* @param endMinute* @param endSecond* @return*/public List<NET_DVR_FINDDATA_V30> getRecordFile(String ip, int port, String userName, String password, int channelNo,int beginYear, int beginMonth, int beginDay, int beginHour, int beginMinute, int beginSecond,int endYear, int endMonth, int endDay, int endHour, int endMinute, int endSecond) {List<NET_DVR_FINDDATA_V30> recordList = new ArrayList<NET_DVR_FINDDATA_V30>();if (mLogId == -1) {  //未登录设备,先登录设备login(ip, port, userName, password, channelNo);}if (mLogId != -1) {NET_DVR_FILECOND net_dvr_filecond = new NET_DVR_FILECOND();  //被搜索录像文件信息net_dvr_filecond.lChannel = chanNo;  //通道号net_dvr_filecond.dwFileType = 0xff;  //录像文件类型 0xff代表所有net_dvr_filecond.dwIsLocked = 0xff;  //是否锁定 0xff代表所有net_dvr_filecond.dwUseCardNo = 0;  //是否使用卡号搜索NET_DVR_TIME beginTime = new NET_DVR_TIME();NET_DVR_TIME endTime = new NET_DVR_TIME();beginTime.dwYear = beginYear;beginTime.dwMonth = beginMonth;beginTime.dwDay = beginDay;beginTime.dwHour = beginHour;beginTime.dwMinute = beginMinute;beginTime.dwSecond = beginSecond;endTime.dwYear = endYear;endTime.dwMonth = endMonth;endTime.dwDay = endDay;endTime.dwHour = endHour;endTime.dwMinute = endMinute;endTime.dwSecond = endSecond;net_dvr_filecond.struStartTime = beginTime;net_dvr_filecond.struStopTime = endTime;int findFileId = HCNetSDK.getInstance().NET_DVR_FindFile_V30(mLogId, net_dvr_filecond);  //调用搜索录像文件接口if (findFileId != -1) {  //查询录像文件成功for (int i = 0; i < 4000; i++) {  //最多4000份录像段文件NET_DVR_FINDDATA_V30 net_dvr_finddata_v30 = new NET_DVR_FINDDATA_V30();int iRet = HCNetSDK.getInstance().NET_DVR_FindNextFile_V30(findFileId, net_dvr_finddata_v30);if (-1 == iRet) {  //调用失败break;} else {if (iRet == 1000) {  //文件信息获取成功recordList.add(net_dvr_finddata_v30);} else if (iRet == 1003) {  //无更多文件break;}//还有一些其他状态,这里不可任何处理,既不加上该录像段文件,也不跳出循环}}} else {LogUtils.e(TAG, "查询录像失败,错误码:" + HCNetSDK.getInstance().NET_DVR_GetLastError());}}return recordList;}/*** 停止实时预览* @param playId* @param port*/public void stopLive(int playId, int port) {if (playId != -1) {if (HCNetSDK.getInstance().NET_DVR_StopRealPlay(playId)) {Player.getInstance().stopSound();if (Player.getInstance().stop(port)) {if (Player.getInstance().closeStream(port)) {if (Player.getInstance().freePort(port)) {LogUtils.i(TAG, "停止实时预览成功");} else {LogUtils.e(TAG, "停止实时预览,调用freePort接口失败,错误码:" + Player.getInstance().getLastError(port));}} else {LogUtils.e(TAG, "停止实时预览,关闭流失败,错误码:" + Player.getInstance().getLastError(port));}} else {LogUtils.e(TAG, "停止实时预览,调用stop接口失败,错误码:" + Player.getInstance().getLastError(port));}} else {LogUtils.e(TAG, "调用停止实时预览接口失败,错误码:" + HCNetSDK.getInstance().NET_DVR_GetLastError());}}}/*** 停止远程回放* @param playbackId* @param port*/public void stopPlayback(int playbackId, int port) {if (playbackId != -1) {if (HCNetSDK.getInstance().NET_DVR_StopPlayBack(playbackId)) {Player.getInstance().stopSound();if (Player.getInstance().stop(port)) {if (Player.getInstance().closeStream(port)) {if (Player.getInstance().freePort(port)) {mStopPlayback = true;LogUtils.i(TAG, "停止远程回放成功");} else {LogUtils.e(TAG, "停止远程回放,调用freePort接口失败,错误码:" + Player.getInstance().getLastError(port));}} else {LogUtils.e(TAG, "停止远程回放,关闭流失败,错误码:" + Player.getInstance().getLastError(port));}} else {LogUtils.e(TAG, "停止远程回放,调用stop接口失败,错误码:" + Player.getInstance().getLastError(port));}} else {LogUtils.e(TAG, "调用停止远程回放接口失败,错误码:" + HCNetSDK.getInstance().NET_DVR_GetLastError());}}}/*** 登出设备* @param logId*/public void logout(int logId) {if (logId != -1) {if (HCNetSDK.getInstance().NET_DVR_Logout_V30(logId)) {LogUtils.i(TAG, "登出设备成功");} else {LogUtils.e(TAG, "登出设备失败,错误码:" + HCNetSDK.getInstance().NET_DVR_GetLastError());}}}private RealPlayCallBack getRealPlayerCbf() {RealPlayCallBack cbf = new RealPlayCallBack() {public void fRealDataCallBack(int iRealHandle, int iDataType, byte[] pDataBuffer, int iDataSize) {processRealData(1, iDataType, pDataBuffer, iDataSize, Player.STREAM_REALTIME);}};return cbf;}private PlaybackCallBack getPlaybackPlayerCbf() {PlaybackCallBack cbf = new PlaybackCallBack() {@Overridepublic void fPlayDataCallBack(int iPlaybackHandle, int iDataType, byte[] pDataBuffer, int iDataSize) {processRealData(1, iDataType, pDataBuffer, iDataSize, Player.STREAM_FILE);}};return cbf;}private void processRealData(int iPlayViewNo, int iDataType, byte[] pDataBuffer, int iDataSize, int iStreamMode) {if (HCNetSDK.NET_DVR_SYSHEAD == iDataType) {mPort = Player.getInstance().getPort();if (mPort == -1) {LogUtils.e(TAG, "获取端口失败,错误码:" + Player.getInstance().getLastError(mPort));return;}LogUtils.i(TAG, "获取端口成功,端口:" + mPort);Player.getInstance().renderPrivateData(mPort, 0x00000002, 0);  //取消显示移动侦测if (iDataSize > 0) {if (!Player.getInstance().setStreamOpenMode(mPort, iStreamMode)) {LogUtils.e(TAG, "设置流打开类型失败");return;}if (!Player.getInstance().openStream(mPort, pDataBuffer, iDataSize, 2 * 1024 * 1024)) {LogUtils.e(TAG, "打开流失败");return;}if (!Player.getInstance().play(mPort, surfaceView.getHolder())) {LogUtils.e(TAG, "播放失败");return;}if (!Player.getInstance().playSound(mPort)) {LogUtils.e(TAG, "播放声音失败");return;}messageFeedback(null);}} else {if (!Player.getInstance().inputData(mPort, pDataBuffer, iDataSize)) {for (int i = 0; i < 4000 && mPlaybackId >= 0 && !mStopPlayback; i++) {if (Player.getInstance().inputData(mPort, pDataBuffer, iDataSize)) {break;}if (i % 100 == 0) {LogUtils.e(TAG, "输入数据失败,错误码:" + Player.getInstance().getLastError(mPort) + ", i:" + i);}try {Thread.sleep(10);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}}/*** 抓图* @return*/public Bitmap capturePicture() {Bitmap bitmap = null;if (mPort >= 0) {Player.MPInteger stWidth = new Player.MPInteger();Player.MPInteger stHeight = new Player.MPInteger();if (Player.getInstance().getPictureSize(mPort, stWidth, stHeight)) {int nSize = 5 * stWidth.value * stHeight.value;byte[] picBuf = new byte[nSize];Player.MPInteger stSize = new Player.MPInteger();if (Player.getInstance().getBMP(mPort, picBuf, nSize, stSize)) {bitmap = BitmapFactory.decodeByteArray(picBuf, 0, stSize.value);}}}return bitmap;}/*** 暂停/播放* @param status  1---暂停;0---播放*/public void pauseOrPlay(int status) {Player.getInstance().pause(mPort, status);}private void messageFeedback(String msg) {Message message = Message.obtain();message.obj = msg;handler.sendMessage(message);}
}

这个类是已经封装好的可以直接拿去用的。这里做几点说明:
1、代码中有一处是动态换算通道号。这是因为在我们业务系统下,我们是在一个Web的设备管理系统中添加上设备,而在这里添加上的设备的通道号是默认从1开始的,1、2、3、4…这种,所以我们在APP中需要动态换算通道号。我们并没有在APP中调用海康SDK的接口去获取通道号。
2、在停止实时预览和停止远程回放的方法中,我们并没有对关闭声音的结果做判断。这是因为我们经过测试发现,关闭声音可能失败,但是实时预览或者远程回放仍然可以停止,并且有些视频就是听不到声音的,对于是否可以听声音,这个国内国外貌似还有不同的政策上的限制,也许是前端设备上的设置导致听不到声音并且关闭声音失败,具体原因不清楚。
3、在PlayerHikvision中我们没有写出切换画质。其实这个很简单,这里就说一下,
切换画质:
我们在调用live方法时传入不同的码流类型即可实现切换画质,注意:切换画质只支持实时预览,不支持远程回放。

Android平台上集成海康SDK(二)相关推荐

  1. Android平台上集成海康SDK

    在项目中需要接入海康设备,因此我们集成了海康Android版本SDK.它分为Device Network SDK和Player SDK.前者用于设备连接.网络通信:后者用于解码.播放. 在APP中,关 ...

  2. Android平台上集成大华SDK(二)

    Android平台上集成大华SDK 以上是我之前写的一篇Android平台上集成大华SDK的文章,其中对于Android平台上集成大华SDK.基于大华SDK进行二次开发基本上进行了详细地介绍. 这篇文 ...

  3. Android平台上集成大华SDK

    在项目中需要接入大华设备,因此我们集成了大华Android版本SDK.与海康SDK类似,它也是分为NetSDK和PlaySDK. 前者用于设备连接.网络通信:后者用于解码.播放. 在APP中,关于大华 ...

  4. Springboot集成海康SDK(以海康USB_SDK为例)

    新建Springboot项目 Pom文件 <!--Spring boot 2.3.2--> <parent><groupId>org.springframework ...

  5. 海康摄像头二次开发python_python实现海康sdk二次开发,移动侦测事件(一)

    1.概述 最近一段时间要从海康摄像头读取数据,作为程序的输入源,c++版本有海康有自己的demo,较为简单,很容易就实现了,但是为我们其他的程序都是基于python的,因此,需要使用Python调用海 ...

  6. Android平台上集成萤石SDK

    这篇文章,就Android平台上如何集成萤石SDK进行讲解. 前言: 萤石是海康威视集团旗下的一家做视频云的公司.我们接入萤石设备,实现实时预览.远程回放.抓图.切换画质等功能. 关于具体如何接入,包 ...

  7. 视频联网云平台EasyCVR集成海康EHome协议:Ehome协议预览流程

    之前我们讲了EasyCVR视频平台集成了海康EHome协议系统配置,EasyCVR集成海康EHome私有协议内容繁杂琐碎,测试内容众多,所以我们特地开辟一个系列,如果大家有兴趣,可以翻阅以往的博客了解 ...

  8. Android平台上集成乐橙SDK

    这篇文章,就Android平台上如何集成乐橙SDK进行讲解. 前言: 乐橙是浙江大华技术股份有限公司旗下的一家专注视频智能硬件,视频云和视频智能技术,为视频应用提供云视频能力的服务商. 我们接入乐橙设 ...

  9. java海康sdk_java 集成 海康 SDK

    1.pom 依赖jna,最好用 3.0.9,其他的少文件 com.sun.jna-local jna-local 3.0.9 使用命令将jar放到依赖库 mvn install:install-fil ...

最新文章

  1. virtaulbox视图模式常用切换
  2. 物联网智能硬件设备身份验证机制
  3. 基础练习 十进制转十六进制 C语言
  4. P5273 【模板】多项式幂函数 (加强版)
  5. python 扫描枪_python 之serial、pyusb 使用开发
  6. @synthesis 使用的时候注意的地方
  7. vue baidu map之获取选中点的经纬度
  8. mysql查询临时表是否存在_[转]SQL判断临时表是否存在
  9. preferredsize JAVA_Java JScrollPane.getPreferredSize方法代码示例
  10. 操作计算机的英文,操作计算机必读的53个英文单词
  11. VMware基础架构和运营管理
  12. 【HDU 5033】【经典单调栈问题】Building
  13. typescript面试题_vue 248+个知识点(面试题)为你保驾护航
  14. linux通过usb链接网络,Nokia N9 通过USB连接使用PC(Linux)主机的网络
  15. python画满天星_跟我学解Python题-海龟制图满天星
  16. android的sd卡分区,超强Android系统SD卡分区教程!
  17. HL7 v2.5 入门
  18. 计算机网络实验四协议分析心得,计算机网络学习心得体会范文
  19. 微信小程序相关操作示例
  20. C++之STL空间置配器

热门文章

  1. 项目管理软件排行榜!盘点前十名!
  2. 信道特性(带宽、时延)
  3. ftp客户端android版,Primitive FTPd(FTP客户端)
  4. Vue2-搭建书写健身app项目
  5. chrome浏览器下载加速
  6. block、多线程与GCD总结
  7. 每天小练笔2-大数求和
  8. layui 数据表格 table的一些技巧,及自定义模板的使用
  9. 主持人群星会缅怀罗京 朱迅眼圈发红
  10. 使用memtester工具对嵌入式Linux内存压力测试