Android海康监控视频调用demo
一、 开发环境
1、 操作系统:windows7(X64)
2、 开发工具:eclipse adt Build: v22.2.1-833290 JDK7 android SDK
3、 客户端设备版本:HUAWEI C8813 android 4.1.1
4、 监控设备型号:HIK/DS-8116HC-F/AF-DVR-II-B/16-16
5、 所需库文件(SDK):海康视频8116 播放库和网络库
二、 开发背景
目前的DVR所监控的视频只能在IE下实时预览,先应项目需要在移动平台进行实时预览
三、 环境搭建
1、 创建android工程在libs目录下导入开发项目所需要的依赖架包和库文件
2、 编写活动主页面
3、 编写主activity其中有一个广播接收器StartRenderingReceiver
4、 编写设备实体类
5、 编写视频播放核心类所有的状态-1 均表示未完成
6、 给项目赋权限
四、 相关说明
先介绍下为什麽要用两个sdk,海康威视android 网络库是用来与设备建立远程连接,音、视频解码,进行实时预览、回放等等功能的,但是它所得到的仅仅是二进制的音、视频数据而已,要真正的显示到手机界面上,还需要海康威视android 播放库sdk得支持,通过播放库sdk,才可以将视频显示到SurfaceView之上。流程如下图

核心代码如下:
public class HC_DVRManager {
private final static String TAG = "HC_DEBUG";
public final static String ACTION_START_RENDERING = "action_start_rendering";
public final static String ACTION_DVR_OUTLINE = "action_dvr_outline";
/**
* 设备信息
* 模拟通道数bychannum
* 数字通道数byipchanum
*/
private NET_DVR_DEVICEINFO_V30 deviceInfo_V30 = null;
/**
* 登入标记 -1未登入,0已登入
*/
private int m_iLogID = -1;
/**
* 播放标记 -1未播放,0正在播放
*/
private int m_iPlayID = -1;
private int m_iPort = -1;
private String ip;
private int port;
private String username;
private String password;
private int channel;
private SurfaceHolder holder;
/**
* 用于发广播的上下文
*/
private Context context;
private static HC_DVRManager manager = null;
private HC_DVRManager() {
}
public static synchronized HC_DVRManager getInstance() {
if (manager == null) {
manager = new HC_DVRManager();
}
return manager;
}
/**
* 设置播放设备信息
*
* @param bean
*/
public void setDeviceBean(DeviceBean bean) {
this.ip = bean.getIP();
this.port = Integer.parseInt(bean.getPort());
this.username = bean.getUserName();
this.password = bean.getPassWord();
this.channel = Integer.parseInt(bean.getChannel());
}
/**
* 设置播放视口
* @param holder
*/
public void setSurfaceHolder(SurfaceHolder holder) {
this.holder = holder;
}
/**
* 用于发送广播的上下文
* @param context
*/
public void setContext(Context context) {
this.context = context;
}
public void initSDK() {
if (m_iPlayID >= 0) {
stopPlay();
}
if (HCNetSDK.getInstance().NET_DVR_Init()) {
Log.i(TAG, "初始化SDK成功!");
} else {
Log.e(TAG, "初始化SDK失败!");
}
}
public void loginDevice() {
deviceInfo_V30 = new NET_DVR_DEVICEINFO_V30();
m_iLogID = HCNetSDK.getInstance().NET_DVR_Login_V30(ip, port, username, password, deviceInfo_V30);
System.out.println("下面是设备信息************************");
System.out.println("userId=" + m_iLogID);
System.out.println("通道开始=" + deviceInfo_V30.byStartChan);
System.out.println("通道个数=" + deviceInfo_V30.byChanNum);
System.out.println("设备类型=" + deviceInfo_V30.byDVRType);
System.out.println("ip通道个数=" + deviceInfo_V30.byIPChanNum);
if (m_iLogID < 0) {
Log.e(TAG, "登入设备失败!" + getErrorMsg(HCNetSDK.getInstance().NET_DVR_GetLastError()));
} else {
Log.i(TAG, "登入设备成功!");
}
}
public synchronized void realPlay() {
try {
if (m_iLogID < 0) {
Log.e(TAG, "尝试重新登入");
int count = 0;
while (count < 10) {
Log.i(TAG, "正在第" + (count + 1) + "次重新登入");
loginDevice();
if (m_iLogID < 0) {
count++;
Thread.sleep(200);
} else {
Log.i(TAG, "第" + (count + 1) + "次登入成功");
break;
}
}
if (m_iLogID < 0) {
Log.e(TAG, "尝试登入" + count + "次均失败!");
return;
}
}
if (m_iPlayID < 0) {
//预览参数配置
NET_DVR_CLIENTINFO ClientInfo = new NET_DVR_CLIENTINFO();
ClientInfo.lChannel = channel + deviceInfo_V30.byStartChan;
ClientInfo.lLinkMode = 0;
// 多播地址,需要多播预览时配置
ClientInfo.sMultiCastIP = null;
m_iPlayID = HCNetSDK.getInstance().NET_DVR_RealPlay_V30(m_iLogID, ClientInfo, getRealPlayerCallBack(), true);
if (m_iPlayID < 0) {
Log.e(TAG, "实时播放失败!" + getErrorMsg(HCNetSDK.getInstance().NET_DVR_GetLastError()));
if (HCNetSDK.getInstance().NET_DVR_GetLastError() == 416) {
//发送广播
context.sendBroadcast(new Intent(ACTION_DVR_OUTLINE));
}
return;
} else {
Log.i(TAG, "开始实时播放!");
}
} else {
Log.d(TAG, "正在播放中?");
}
} catch (Exception e) {
Log.e(TAG, "异常:" + e.toString());
}
}
/**
* 获取实时播放回调
*
* @return
*/
private RealPlayCallBack getRealPlayerCallBack() {
return new RealPlayCallBack() {
/**
* iRealHandle 当前的预览句柄
* iDataType 数据类型
* pDataBuffer 存放数据的缓冲区指针
* iDataSize 缓冲区大小
*/
@Override
public void fRealDataCallBack(int iRealHandle, int iDataType, byte[] pDataBuffer, int iDataSize) {
processRealData(iDataType, pDataBuffer, iDataSize, Player.STREAM_REALTIME);
}
};
}
/**
* 停止播放
*/
public synchronized void stopPlay() {
if (m_iPlayID < 0) {
Log.d(TAG, "已经停止?");
return;
}
// 停止网络播放
if (HCNetSDK.getInstance().NET_DVR_StopRealPlay(m_iPlayID)) {
Log.i(TAG, "停止实时播放成功!");
} else {
Log.e(TAG, "停止实时播放失败!" + getErrorMsg(HCNetSDK.getInstance().NET_DVR_GetLastError()));
return;
}
// 停止本地播放
if (Player.getInstance().stop(m_iPort)) {
Log.i(TAG, "停止本地播放成功!");
} else {
Log.e(TAG, "停止本地播放失败!");
return;
}
// 关闭视频流
if (Player.getInstance().closeStream(m_iPort)) {
Log.i(TAG, "关闭视频流成功!");
} else {
Log.e(TAG, "关闭视频流失败!");
return;
}
// 释放播放端口
if (Player.getInstance().freePort(m_iPort)) {
Log.i(TAG, "释放播放端口成功!");
} else {
Log.e(TAG, "释放播放端口失败!");
return;
}
// 播放端口复位
m_iPort = -1;
// 正在播放标记复位
m_iPlayID = -1;
Log.i(TAG, "停止播放成功!");
}
/**
* 登出设备
*/
public void logoutDevice() {
if (HCNetSDK.getInstance().NET_DVR_Logout_V30(m_iLogID)) {
m_iLogID = -1;
Log.i(TAG, "登出设备成功!");
} else {
m_iLogID = 0;
Log.e(TAG, "登出设备失败!" + getErrorMsg(HCNetSDK.getInstance().NET_DVR_GetLastError()));
}
}
/**
* 释放海康SDK
*/
public void freeSDK() {
// 清理缓存
if (HCNetSDK.getInstance().NET_DVR_Cleanup()) {
Log.i(TAG, "释放SDK资源成功!");
} else {
Log.e(TAG, "释放SDK资源失败!");
}
}
/**
* 视频流解码
*
* @param iDataType
* @param pDataBuffer
* @param iDataSize
* @param iStreamMode
*/
private void processRealData(int iDataType, byte[] pDataBuffer, int iDataSize, int iStreamMode) {
int i = 0;
try {
switch (iDataType) {
case HCNetSDK.NET_DVR_SYSHEAD:
Log.d(TAG, "处理头数据");
if (m_iPort >= 0) {
break;
}
m_iPort = Player.getInstance().getPort();
if (m_iPort == -1) {
Log.e(TAG, "获取播放端口失败!");
break;
} else {
Log.i(TAG, "获取播放端口成功!");
}
if (iDataSize > 0) {
if (Player.getInstance().setStreamOpenMode(m_iPort, iStreamMode)) {
Log.i(TAG, "设置视频流成功!");
} else {
Log.e(TAG, "设置视频流失败!");
break;
}
//抓图回调函数
PlayerDisplayCB displayCB = new PlayerDisplayCB() {
@Override
public void onDisplay(int arg0, ByteBuffer arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7) {
if (null != context) {
context.sendBroadcast(new Intent(ACTION_START_RENDERING));
} else {
Log.e(TAG, "Context为空!没有setContext(Context context)?");
}
Log.d(TAG, "开始画面渲染");
if (Player.getInstance().setDisplayCB(m_iPort, null)) {
Log.i(TAG, "移除显示回调成功!");
} else {
Log.e(TAG, "移除显示回调失败!");
}
}
};
if (Player.getInstance().setDisplayCB(m_iPort, displayCB)) {
Log.i(TAG, "设置显示回调成功!");
} else {
Log.e(TAG, "设置显示回调失败!");
break;
}
if (Player.getInstance().setDisplayBuf(m_iPort, 10)) { // 帧率,不设置为默认15
Log.i(TAG, "设置播放缓冲区最大缓冲帧数成功!");
} else {
Log.e(TAG, "设置播放缓冲区最大缓冲帧数失败!");
break;
}
if (Player.getInstance().openStream(m_iPort, pDataBuffer, iDataSize, 2 * 1024 * 1024)) {
Log.i(TAG, "打开视频流成功!");
} else {
Log.e(TAG, "打开视频流失败!");
break;
}
if (Player.getInstance().play(m_iPort, holder)) {
Log.i(TAG, "本地播放成功!");
} else {
Log.e(TAG, "本地播放失败!");
break;
}
} else {
Log.e(TAG, "视频流无数据!");
}
break;
case HCNetSDK.NET_DVR_STREAMDATA:
case HCNetSDK.NET_DVR_STD_AUDIODATA:
case HCNetSDK.NET_DVR_STD_VIDEODATA:
// Log.i(TAG, "处理流数据");
if (iDataSize > 0 && m_iPort != -1) {
for (i = 0; i < 400; i++) {
if (Player.getInstance().inputData(m_iPort, pDataBuffer, iDataSize)) {
Log.i(TAG, "输入数据成功!");
break;
}
Thread.sleep(10);
}
if (i == 400) {
Log.e(TAG, "输入数据失败!");
}
}
break;
default:
break;
}
} catch (Exception e) {
Log.e(TAG, "视频流解码异常!" + e.toString());
}
}
五、 项目运行相关



目前就介绍这么多了,大家需要源码的可以留下邮箱
注:转载请注明出处
博客地址:http://qiaoyihang.iteye.com/
Android海康监控视频调用demo的更多相关文章
- 海康网络摄像机调用SDK解码Java版
两个回调函数: FRealDataCallBack 实现预览回调数据 DecCallBack 解码回调函数 在HCNetSDK.java补充相关函数和结构声明 //播放库函数声明,PlayCtrl.d ...
- 树莓派+android things+实时音视频传输demo之遥控小车
做了个测试小车,上面安装了摄像头,通过外网进行视频传输: https://www.bilibili.com/video/av23817880/
- 海康SDK JAVA版本调用步骤及问题介绍
一.前言 本文为海康SDK JAVA版本Demo的介绍,采用Eclipse运行,以及一些问题记录. 海康SDK版本:SDK_Win32 Eclipse版本:Mars2.0 JDK版本:1.8.0_15 ...
- 海康SDK编程指南(C#二次开发版本)
海康SDK编程指南 目前使用的海康SDK包括IPC_SDK(硬件设备),Plat_SDK(平台),其中两套SDK都需单独调用海康播放库PlayCtrl.dll来解码视频流,返回视频信息和角度信息.本文 ...
- 海康SDK编程指南
转至心澄欲遣 目前使用的海康SDK包括IPC_SDK(硬件设备),Plat_SDK(平台),其中两套SDK都需单独调用海康播放库PlayCtrl.dll来解码视频流,返回视频信息和角度信息.本文仅对视 ...
- 前端Web浏览器基于Flash如何实时播放监控视频画面(三)之使用ffmpeg‘推流’
本片文章只是起到抛砖引玉的作用,能从头到尾走通就行,并不做深入研究.为了让文章通俗易懂,尽量使用白话描述. 0x001: 下载ffmpeg 开源免费的推流软件有很多,这里以 ffmpeg 为例.ffm ...
- 海康视频监控---Demo
1,使用在页面中调用ActiveX控件 <object classid='clsid:E7EF736D-B4E6-4A5A-BA94-732D71107808' codebase='' stan ...
- 海康相机SDK二次开发只有视频无声音问题
海康SDK相信做企业开发的的同仁,在项目中经常会用到,毕竟使用范围这么广. 本次就开发遇到的奇葩问题来说明一下我们的解决方案. 场景 虽然海康有4200客户端,但是对于高度定制化的项目,肯定不能再使用 ...
- iNeuOS工业互联平台,WEB组态(iNeuView)集成rtmp和websocket视频元件,支持海康、大华等摄像头实时显示视频
目 录 1. 概述... 1 2. 平台演示... 2 3. 硬件摄像头... 2 4. 视频流协议转换管理... 2 5. 组态视频元件 ...
随机推荐
- iOS App上架AppStore 会遇到的坑
前言部分 前言:非原创 文章摘自:http://zhuanlan.zhihu.com/100000PM/20010725 相信大家一定非常「深恶痛疾」AppStore的一系列产品上架规则.每次产品上架 ...
- 不可或缺 Windows Native (11) - C++: hello c++, C++ 与 C语言的区别小介
[源码下载] 不可或缺 Windows Native (11) - C++: hello c++, C++ 与 C语言的区别小介 作者:webabcd 介绍不可或缺 Windows Native 之 ...
- 制作Java视频播放器
一.工程准备 首先需要下载并安装VLC播放器,然后下载vlcj外部库. 下载slf4j中的slf4j-api-1.7.13.jar. slf4j- nop-1.7.13.jar 将vlc安装目录下的l ...
- 使用maven创建Archetype
Archetype原型 也就是说为项目生成一个原型,可以把这个项目发布,其他人就可以直接通过命令构建一个原型项目了. 其实我一开始也是不知道maven还有这个功能的,但是在使用的springside的 ...
- x8086汇编在显存中显示字符串
题目:在屏幕中间显示绿色,绿底红色,白底蓝色的字符串‘welcome to masm!’ 80X25彩色字符模式显示缓冲区的结构: 在内存地址结构中,B8000H~BFFFFH共32KB的空间,为80 ...
- 「Ionic」使用chrom時的跨域問題
前言:在angularjs請求數據時,會遇到跨域問題,解決辦法有很多,但是都不是我想要的(很多人云亦云,都解決不了問題).如果你只是想在本機測試使用,可以參考如下設置. 具體辦法: 1.在电脑上新 ...
- Lucene.net站内搜索—2、Lucene.Net简介和分词
目录 Lucene.net站内搜索—1.SEO优化 Lucene.net站内搜索—2.Lucene.Net简介和分词Lucene.net站内搜索—3.最简单搜索引擎代码Lucene.net站内搜索—4 ...
- mysql 5.7.15 vs mysql 5.6.31性能测试以及不同linux内核性能比较
最近,将部分开发和测试环境的mysql升级到5.7之后,今天抽时间测试了下5.6和5.7 PK查询的性能,使用mysqlslap进行测试,测试结果发现在低配下,percona 5.6.31大约比5.7 ...
- Wrangle – 响应式的,触摸友好的多选插件
Wrangle 是一个响应式,触摸友好的选择插件,支持 jQuery 以及 Zepto.Wrangle 为多项选择提供了一个独特的方法:通过画一条贯穿项目的线条来选择项目.它给你的应用程序的一种新的方 ...
- [deviceone开发]-企业OA项目开源分享
一.简介 是一个真实的企业OA项目改造的开源项目,几乎涵盖了所有常用的组件,包括环信实现在线聊天等功能,类似微信的朋友圈功能,自定义的智能搜索等,而且这个是真实的通过Http链接后台web服务,里面很 ...