• 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/

  • 相关阅读:
    Linux(Centos7)下redis5安装、部署、开机自启
    请求*.html后缀无法返回json数据的问题
    Linux搭建图片服务器减轻传统服务器的压力(nginx+vsftpd)
    Centos7和Centos6防火墙开放端口配置方法(避坑教学)
    分享一个酷炫动态登录页面html
    分布式全文搜索解决方案
    PHP实现支付宝登录
    PHP发送短信
    PHP中发送qq邮件
    ES6新语法(二)
  • 原文地址:https://www.cnblogs.com/qiaoyihang/p/6166181.html
Copyright © 2020-2023  润新知