草庐IT

vue+js+海康web开发包接入海康威视摄像头

weixin_46653941 2024-06-16 原文

一、登录海康开放平台下载web开发包,下载需要先登录海康账号,没有的需先注册一个。

海康开放平台web开发包下载地址:https://open.hikvision.com/download/5cda567cf47ae80dd41a54b3?type=10&id=4c945d18fa5f49638ce517ec32e24e24

二、将web开发包引入vue项目

  1. 下载后解压的包目录如下:

  1. 将把webs下的整个codebase文件夹和jquery-1.7.1.min.js都复制到public文件夹下,在index.html下引入对应文件,必须引入的只有jquery-1.7.1.min.js和webVideoCtrl.js

<!-- 海康插件引入 -->
    <script src="./jquery-1.7.1.min.js"></script>
    <script src="./codebase/encryption/AES.js"></script>
    <script src="./codebase/encryption/cryptico.min.js"></script>
    <script src="./codebase/encryption/crypto-3.1.2.min.js"></script>
    <script id="videonode" src="./codebase/webVideoCtrl.js"></script>

三、安装webs/codebase/WebComponentsKit.exe(可不做此操作

四、运行解压包的nginx-1.10.2/start.bat,nginx启动端口可以自行修改;此处默认80,其中为了方便开发环境下测试,我把nginx-1.10.2放到项目中与public文件夹同级,因此nginx的root路径设置为../dist(项目打包路径,根据需要自行修改)

开发环境配置:在vue.config.js文件下配置nginx对应的反向代理,以下webSocketVideoCtrlProxy反向配置暂未配置成功,因此开发过程看不了视频,但可以进行登录等其他与websocket无关的接口的调用,想要成功拉流看视频得先打包部署,这个有弄懂的小伙伴可以告知一下

"/ISAPI": {
  target: "http://127.0.0.1/ISAPI", // 本地nginx服务
  changeOrigin: true,
  ws: true,
  pathRewrite: {
    "^/ISAPI": "/",
  },
},
"/SDK": {
  target: "http://127.0.0.1/SDK", // 本地nginx服务
  changeOrigin: true,
  ws: true,
  pathRewrite: {
    "^/SDK": "/",
  },
},
// webSocketVideoCtrlProxy反向配置暂未配置成功,当前配置在开发过程不需要打包就可实现除播放视频外的其他功能

注意:

1、本地开发过程nginx服务必须运行

2、开发过程运行项目地址必须是本地ip地址,不能用localhost那个,否则登录不成功

3、开发过程想要预览监控视频,需要先打包,然后访问部署后的项目路径,访问ip必须是服务器ip地址,不能用localhost或者127.0.0.1,否则登录不成功

五、初始化

<div
      id="divPlugin"
      style="height: 100%; width: 100%"
 ></div>

注意:Dom元素ID必须是divPlugin,不然会出问题

初始化函数如下:

/**
 * 初始化
 * @param {number} iWndowType 分屏类型:1 - 1*1,2 - 2*2,3 - 3*3,4 - 4*4,默认值1,单画面
 * @param {number} width 插件的宽度(单位为”px”, 100%表示撑满插件容器)
 * @param {number} height 插件的高度(单位为”px”, 100%表示撑满插件容器)
 * @returns null
 */
let init = (iWndowType, width, height) => {
  console.log("window.WebVideoCtrl-------", window.WebVideoCtrl, width, height);
  // 检查浏览器是否支持无插件
  if (!webVideoCtrl.I_SupportNoPlugin()) {
    Message.warning(
      "当前浏览器不支持无插件预览监控视频,已自动切换成插件模式,如果还未安装插件请安装"
    );
    // 检查插件是否已经安装
    const isInstall = webVideoCtrl.I_CheckPluginInstall();
    if (isInstall == -1) {
      Message.warning(
        "您还未安装过插件,请先下载WebComponentsKit.exe双击安装!"
      );
      return;
    }
  }
  // 初始化插件
  webVideoCtrl.I_InitPlugin(width, height, {
    szColorProperty:
      "plugin-background:ffffff; sub-background:00000; sub-border:D0DAE4; sub-border-select:409EFF", // 表示插件的背景颜色,插件子窗口的背景颜色,窗口边框的颜色,窗口边框选中后的颜色
    iWndowType,
    bNoPlugin: true, // 支持无插件
    cbSelWnd: (xmlDoc) => {
      let iWndIndex = parseInt($(xmlDoc)?.find("SelectWnd").eq(0).text(), 10);
      console.log("当前选择的窗口编号:" + iWndIndex);
    },
    cbDoubleClickWnd: (iWndIndex, bFullScreen) => {
      let szInfo = "当前放大的窗口编号:" + iWndIndex;
      if (!bFullScreen) {
        szInfo = "当前还原的窗口编号:" + iWndIndex;
      }
      console.log(szInfo);
    },
    cbInitPluginComplete: () => {
      // 嵌入播放插件
      webVideoCtrl.I_InsertOBJECTPlugin("divPlugin");
      console.log("初始化成功--------");
      resize();
      // 检查插件是否最新
      if (webVideoCtrl.I_CheckPluginVersion() == -1) {
        Message.warning("检测到新的插件版本,双击WebComponentsKit.exe升级!");
        return;
      }
    }, // 插件初始化完成回调,必须要定义
  });
};

在实际使用过程,iWndowType不管怎么设置都不起效,只有在窗口resize后才起作用,所以在初始化成功后手动加了resize()给它调整大小,resize()函数封装在下面可以找到。

六、主要函数封装

  1. 调整大小

/**
 * 调整大小
 */
let resize = () => {
  webVideoCtrl.I_Resize($("#divPlugin").width(), $("#divPlugin").height());
};
  1. 登录:初始化成功后调用,登录成功后根据需要获取通道信息,这里我获取的是数字通道的数据

/**
 * 登录
 * @param {string} ip 设备的 IP 地址或者普通域名
 * @param {number} prototocol http 协议,1 表示 http 协议 2 表示 https 协议
 * @param {number} port 登录设备的 http/https 端口号,根据 iPrototocol 选择传入不同的端口
 * @param {string} userName 登录用户名称
 * @param {string} password 用户密码
 */
let login = (ip, prototocol, port, userName, password) => {
  webVideoCtrl.I_Login(ip, prototocol, port, userName, password, {
    async: true, // http 交互方式,true 表示异步,false 表示同步
    cgi: 1, // CGI 协议选择,1 表示 ISAPI,2 表示 PSIA,如果不传这个参数,会自动选择一种设备支持的协议.
    // 登录成功回调
    success: (xmlDoc) => {
      console.log("login success-----------", xmlDoc);
      // getAnalogChannelInfo(`${ip}_${port}`, {
      //   async: true,
      //   success: (analogChannelInfo) => {
      //     let analogCameras = analysisAnalogChannelInfo(analogChannelInfo);
      //     console.log(
      //       "获取模拟通道----------",
      //       analogChannelInfo,
      //       analogCameras
      //     );
      //   },
      //   error: (statusA, xmlDocA) => {
      //     console.log("获取模拟通道 error-----------", statusA, xmlDocA);
      //   },
      // });
      getDigitalChannelInfo(`${ip}_${port}`, {
        async: true,
        success: (digitalChannelInfo) => {
          let digitalCameras = analysisDigitalChannelInfo(digitalChannelInfo);
          console.log(
            "获取数字通道----------",
            digitalChannelInfo,
            digitalCameras
          );
        },
        error: (statusD, xmlDocD) => {
          console.log("获取数字通道 error-----------", statusD, xmlDocD);
        },
      });
      // getZeroChannelInfo(`${ip}_${port}`, {
      //   async: true,
      //   success: (zeroChannelInfo) => {
      //     let zeroCameras = analysisZeroChannelInfo(zeroChannelInfo);
      //     console.log("获取零通道----------", zeroChannelInfo, zeroCameras);
      //   },
      //   error: (statusZ, xmlDocZ) => {
      //     console.log("获取零通道 error-----------", statusZ, xmlDocZ);
      //   },
      // });
    },
    // 失败函数回调
    error: () => {
      console.log("login error-----------");
    },
  });
};
  1. 登出

/**
 * 登出
 * @param {string} deviceIdentify 设备标识(IP_Port)
 * @returns  成功返回 0,失败返回-1
 */
let logout = (deviceIdentify) => {
  return webVideoCtrl.I_Logout(deviceIdentify);
};
  1. 获取模拟通道

/**
 * 获取模拟通道
 * @param {string} deviceIdentify  设备标识(IP_Port)
 * @param {*} options 可选参数对象:
 * * async http 交互方式,true 表示异步,false 表示同步;
 * * success 成功回调函数,有一个参数,表示返回的 XML 内容。;
 * * error 失败回调函数,有两个参数,第一个是 http 状态码,第二个是设备返回的 XML(可能为空)
 */
let getAnalogChannelInfo = (deviceIdentify, options) => {
  webVideoCtrl.I_GetAnalogChannelInfo(deviceIdentify, options);
};
  1. 解析模拟通道XML内容

/**
 * 解析模拟通道XML内容
 * @param {XMLDocument} xmlDoc XML内容
 * @returns cameraList: 监控列表
 */
let analysisAnalogChannelInfo = (xmlDoc) => {
  let cameraList = [];
  let channels = $(xmlDoc)?.find("VideoInputChannel");
  $.each(channels, (i, channel) => {
    let id = $(channel).find("id").eq(0).text();
    let name = $(channel).find("name").eq(0).text();
    if (name == "") {
      name = "Camera " + (i < 9 ? "0" + (i + 1) : i + 1);
    }
    cameraList.push({
      id,
      name,
    });
  });
  return cameraList;
};
  1. 获取数字通道

/**
 * 获取数字通道
 * @param {string} deviceIdentify  设备标识(IP_Port)
 * @param {*} options 可选参数对象:
 * * async http 交互方式,true 表示异步,false 表示同步;
 * * success 成功回调函数,有一个参数,表示返回的 XML 内容。;
 * * error 失败回调函数,有两个参数,第一个是 http 状态码,第二个是设备返回的 XML(可能为空)
 */
let getDigitalChannelInfo = (deviceIdentify, options) => {
  webVideoCtrl.I_GetDigitalChannelInfo(deviceIdentify, options);
};
  1. 解析数字通道XML内容

/**
 * 解析数字通道XML内容
 * @param {XMLDocument} xmlDoc XML内容
 * @param {boolean} filterOnline 是否过滤禁用的数字通道
 * @returns cameraList: 监控列表
 */
let analysisDigitalChannelInfo = (xmlDoc, filterOnline) => {
  let cameraList = [];
  let channels = $(xmlDoc)?.find("InputProxyChannelStatus");

  $.each(channels, (i, channel) => {
    let id = $(channel).find("id").eq(0).text();
    let name = $(channel).find("name").eq(0).text();
    let online = $(channel).find("online").eq(0).text();
    if (filterOnline && online == "false") {
      // 过滤禁用的数字通道
      return true;
    }
    if (name == "") {
      name = "IPCamera " + (i < 9 ? "0" + (i + 1) : i + 1);
    }
    cameraList.push({
      id,
      name,
      online,
    });
  });
  return cameraList;
};
  1. 获取零通道

/**
 * 获取零通道
 * @param {string} deviceIdentify  设备标识(IP_Port)
 * @param {*} options 可选参数对象:
 * * async http 交互方式,true 表示异步,false 表示同步;
 * * success 成功回调函数,有一个参数,表示返回的 XML 内容。;
 * * error 失败回调函数,有两个参数,第一个是 http 状态码,第二个是设备返回的 XML(可能为空)
 */
let getZeroChannelInfo = (deviceIdentify, options) => {
  webVideoCtrl.I_GetZeroChannelInfo(deviceIdentify, options);
};
  1. 解析零通道XML内容

/**
 * 解析零通道XML内容
 * @param {XMLDocument} xmlDoc XML内容
 * @param {boolean} filterEnabled 是否过滤禁用的零通道
 * @returns cameraList: 监控列表
 */
let analysisZeroChannelInfo = (xmlDoc, filterEnabled) => {
  let cameraList = [];
  let channels = $(xmlDoc)?.find("ZeroVideoChannel");

  $.each(channels, (i, channel) => {
    let id = $(channel).find("id").eq(0).text();
    let name = $(channel).find("name").eq(0).text();
    if (name == "") {
      name = "Zero Channel " + (i < 9 ? "0" + (i + 1) : i + 1);
    }
    let enabled = $(channel).find("enabled").eq(0).text();
    if (filterEnabled && enabled == "false") {
      // 过滤禁用的零通道
      return true;
    }
    cameraList.push({
      id,
      name,
      enabled,
    });
  });
  return cameraList;
};
  1. 开始预览

/**
 * 开始预览
 * @param {string} deviceIdentify 设备标识(IP_Port)
 * @param {*} options 可选参数对象:
 * * iWndIndex 播放窗口,如果不传,则默认使用当前选择窗口播放(默认选中窗口 0)
 * * iStreamType 码流类型 1-主码流,2-子码流,默认使用主码流预览
 * * iChannelID 播放通道号,默认通道 1
 * * bZeroChannel 是否播放零通道,默认为 false
 * * iPort RTSP 端口号,可以选择传入,如果不传,开发包会自动判断设备的 RTSP 端口
 * * success 成功回调函数
 * * error 失败回调函数
 */
let startRealPlay = (deviceIdentify, options) => {
  webVideoCtrl.I_StartRealPlay(deviceIdentify, options);
};
  1. 停止播放

/**
 * 停止播放
 * @param {*} options   可选参数对象:
 * * iWndIndex 播放窗口号,可不传,表示操作当前选中窗口
 * * success 成功回调函数
 * * error 失败回调函数
 */
let stopPlay = (options) => {
  webVideoCtrl.I_Stop(options);
};

常用函数封装文件下载地址:https://download.csdn.net/download/weixin_46653941/87555074

详细API可以看自己下载的开发包内的Web3.2_控件开发包编程指南.pdf,上面这个下载地址只是我自己二次封装的一些API。

实操结果图(涉及隐私加了马赛克):

有关vue+js+海康web开发包接入海康威视摄像头的更多相关文章

  1. ruby - 使用 C 扩展开发 ruby​​gem 时,如何使用 Rspec 在本地进行测试? - 2

    我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当

  2. Ruby Sinatra 配置用于生产和开发 - 2

    我已经在Sinatra上创建了应用程序,它代表了一个简单的API。我想在生产和开发上进行部署。我想在部署时选择,是开发还是生产,一些方法的逻辑应该改变,这取决于部署类型。是否有任何想法,如何完成以及解决此问题的一些示例。例子:我有代码get'/api/test'doreturn"Itisdev"end但是在部署到生产环境之后我想在运行/api/test之后看到ItisPROD如何实现? 最佳答案 根据SinatraDocumentation:EnvironmentscanbesetthroughtheRACK_ENVenvironm

  3. ruby - 是否可以覆盖 gemfile 进行本地开发? - 2

    我们的git存储库中目前有一个Gemfile。但是,有一个gem我只在我的环境中本地使用(我的团队不使用它)。为了使用它,我必须将它添加到我们的Gemfile中,但每次我checkout到我们的master/dev主分支时,由于与跟踪的gemfile冲突,我必须删除它。我想要的是类似Gemfile.local的东西,它将继承从Gemfile导入的gems,但也允许在那里导入新的gems以供使用只有我的机器。此文件将在.gitignore中被忽略。这可能吗? 最佳答案 设置BUNDLE_GEMFILE环境变量:BUNDLE_GEMFI

  4. ruby - 在 Windows 机器上使用 Ruby 进行开发是否会适得其反? - 2

    这似乎非常适得其反,因为太多的gem会在window上破裂。我一直在处理很多mysql和ruby​​-mysqlgem问题(gem本身发生段错误,一个名为UnixSocket的类显然在Windows机器上不能正常工作,等等)。我只是在浪费时间吗?我应该转向不同的脚本语言吗? 最佳答案 我在Windows上使用Ruby的经验很少,但是当我开始使用Ruby时,我是在Windows上,我的总体印象是它不是Windows原生系统。因此,在主要使用Windows多年之后,开始使用Ruby促使我切换回原来的系统Unix,这次是Linux。Rub

  5. ruby-on-rails - 在 Rails 开发环境中为 .ogv 文件设置 Mime 类型 - 2

    我正在玩HTML5视频并且在ERB中有以下片段:mp4视频从在我的开发环境中运行的服务器很好地流式传输到chrome。然而firefox显示带有海报图像的视频播放器,但带有一个大X。问题似乎是mongrel不确定ogv扩展的mime类型,并且只返回text/plain,如curl所示:$curl-Ihttp://0.0.0.0:3000/pr6.ogvHTTP/1.1200OKConnection:closeDate:Mon,19Apr201012:33:50GMTLast-Modified:Sun,18Apr201012:46:07GMTContent-Type:text/plain

  6. 世界前沿3D开发引擎HOOPS全面讲解——集3D数据读取、3D图形渲染、3D数据发布于一体的全新3D应用开发工具 - 2

    无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD

  7. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

  8. 计算机毕业设计ssm+vue基本微信小程序的小学生兴趣延时班预约小程序 - 2

    项目介绍随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱小学生兴趣延时班预约小程序的设计与开发被用户普遍使用,为方便用户能够可以随时进行小学生兴趣延时班预约小程序的设计与开发的数据信息管理,特开发了小程序的设计与开发的管理系统。小学生兴趣延时班预约小程序的设计与开发的开发利用现有的成熟技术参考,以源代码为模板,分析功能调整与小学生兴趣延时班预约小程序的设计与开发的实际需求相结合,讨论了小学生兴趣延时班预约小程序的设计与开发的使用。开发环境开发说明:前端使用微信微信小程序开发工具:后端使用ssm:VU

  9. 微信小程序开发入门与实战(Behaviors使用) - 2

    @作者:SYFStrive @博客首页:HomePage📜:微信小程序📌:个人社区(欢迎大佬们加入)👉:社区链接🔗📌:觉得文章不错可以点点关注👉:专栏连接🔗💃:感谢支持,学累了可以先看小段由小胖给大家带来的街舞👉微信小程序(🔥)目录自定义组件-behaviors    1、什么是behaviors    2、behaviors的工作方式    3、创建behavior    4、导入并使用behavior    5、behavior中所有可用的节点    6、同名字段的覆盖和组合规则总结最后自定义组件-behaviors    1、什么是behaviorsbehaviors是小程序中,用于实现

  10. ruby-on-rails - environment.rb 中设置的常量在开发模式中消失 - 2

    了解Rails缓存如何工作的人可以真正帮助我。这是嵌套在Rails::Initializer.runblock中的代码:config.after_initializedoSomeClass.const_set'SOME_CONST','SOME_VAL'end现在,如果我运行script/server并发出请求,一切都很好。然而,在我的Rails应用程序的第二个请求中,一切都因单元化常量错误而变得糟糕。在生产模式下,我可以成功发出第二个请求,这意味着常量仍然存在。我已通过将以上内容更改为以下内容来解决问题:config.after_initializedorequire'some_cl

随机推荐