一、 开发环境
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的更多相关文章

  1. 海康网络摄像机调用SDK解码Java版

    两个回调函数: FRealDataCallBack 实现预览回调数据 DecCallBack 解码回调函数 在HCNetSDK.java补充相关函数和结构声明 //播放库函数声明,PlayCtrl.d ...

  2. 树莓派+android things+实时音视频传输demo之遥控小车

    做了个测试小车,上面安装了摄像头,通过外网进行视频传输: https://www.bilibili.com/video/av23817880/

  3. 海康SDK JAVA版本调用步骤及问题介绍

    一.前言 本文为海康SDK JAVA版本Demo的介绍,采用Eclipse运行,以及一些问题记录. 海康SDK版本:SDK_Win32 Eclipse版本:Mars2.0 JDK版本:1.8.0_15 ...

  4. 海康SDK编程指南(C#二次开发版本)

    海康SDK编程指南 目前使用的海康SDK包括IPC_SDK(硬件设备),Plat_SDK(平台),其中两套SDK都需单独调用海康播放库PlayCtrl.dll来解码视频流,返回视频信息和角度信息.本文 ...

  5. 海康SDK编程指南

    转至心澄欲遣 目前使用的海康SDK包括IPC_SDK(硬件设备),Plat_SDK(平台),其中两套SDK都需单独调用海康播放库PlayCtrl.dll来解码视频流,返回视频信息和角度信息.本文仅对视 ...

  6. 前端Web浏览器基于Flash如何实时播放监控视频画面(三)之使用ffmpeg‘推流’

    本片文章只是起到抛砖引玉的作用,能从头到尾走通就行,并不做深入研究.为了让文章通俗易懂,尽量使用白话描述. 0x001: 下载ffmpeg 开源免费的推流软件有很多,这里以 ffmpeg 为例.ffm ...

  7. 海康视频监控---Demo

    1,使用在页面中调用ActiveX控件 <object classid='clsid:E7EF736D-B4E6-4A5A-BA94-732D71107808' codebase='' stan ...

  8. 海康相机SDK二次开发只有视频无声音问题

    海康SDK相信做企业开发的的同仁,在项目中经常会用到,毕竟使用范围这么广. 本次就开发遇到的奇葩问题来说明一下我们的解决方案. 场景 虽然海康有4200客户端,但是对于高度定制化的项目,肯定不能再使用 ...

  9. iNeuOS工业互联平台,WEB组态(iNeuView)集成rtmp和websocket视频元件,支持海康、大华等摄像头实时显示视频

    目       录 1.      概述... 1 2.      平台演示... 2 3.      硬件摄像头... 2 4.      视频流协议转换管理... 2 5.      组态视频元件 ...

随机推荐

  1. Java final 修饰符知识点总结

    final从字面上理解含义为“最后的,最终的”.在Java中也同样表示出此种含义. final可以用来修饰变量(包括类属性.对象属性.局部变量和形参).方法(包括类方法和对象方法)和类. 1. fin ...

  2. js设置和读取cookie

    /*path参数:表示cookie所在的目录,.net默认为/(根目录).在同一个服务器上有目录如下:/test/,/test/aa/,/test /bb/,现设一个cookie1的path为/tes ...

  3. ASP.NET Boilerplate Zero启动方式

    1.打开解决方案还原nuget包 2.设置 ModuleZeroSampleProject.Web 为启动项目[带有有数据库连接字符串的项目] 3.重启vs后.打开  视图>其他窗口>程序 ...

  4. 习题:codevs 1035 火车停留解题报告

    本蒟蒻又来写解题报告了.这次的题目是codevs 1035 火车停留. 题目大意就是给m个火车的到达时间.停留时间和车载货物的价值,车站有n个车道,而火车停留一次车站就会从车载货物价值中获得1%的利润 ...

  5. PHP内核探索之变量(6)- 后续内核探索系列大纲备忘

    年前因为工作比较饱和,现在又忙着换工作的事情,基本停止了对博文的更新.后续的博文,还是慢慢补上吧. 为了不至于过于发散,先搞个未成形的大纲,如下: PHP内核探索之变量  不平凡的字符串 PHP内核探 ...

  6. 参数化命令相关知识点之==================防止SQl的注入

    一: 使用参数化命令查询DAL类: public DataTable StudentDAL(string name,string gender) { string str="连接字符串&qu ...

  7. AWS CloudFront CDN直接全站加速折腾记The request could not be satisfied. Bad request

    ERROR The request could not be satisfied. Bad request. Generated by cloudfront (CloudFront) Request ...

  8. 20款高质量的 HTML5 网站模板【免费下载】

    下面的列表集合了20款高质量的免费 HTML5 网站模板,这些专业的模板能够让你的网站吸引很多的访客.这些免费的 HTML5 模板虽然不是响应式的,不过都很实用.赶紧来看看. 您可能感兴趣的相关文章 ...

  9. 【再探backbone 01】模型-Model

    前言 点保存时候不注意发出来了,有需要的朋友将就看吧,还在更新...... 几个月前学习了一下backbone,这段时间也用了下,感觉之前对backbone的学习很是基础,前几天有个园友问我如何将路由 ...

  10. Spring------概述

    Spring框架------概述: spring是j2ee应用程序框架,是轻量级的IOC和AOP的容器框架,主要是针对JAVABean的生命周期进行管理的轻量级容器,可以单独使用,也可以和Struts ...