1.公司需要展示海康摄像头的预览画面

2.经过我两天的搜索资料加尝试,几种方式

2.1后端转码,前端调接口取太麻烦,对服务器负荷大

2.2 vlc插件对rtsp取流 高版本的各种浏览器不支持了vlc插件

2.3 WEB无插件开发包 V3.2 需要支持websocket,不是所有海康设备都支持,而且要自己去开启这个配置

2.4 WEB3.0控件开发包 V3.0 这个原理和vlc插件一模一样,谁会特意下个低版本谷歌

2.5 WEB3.3控件开发包 V3.3 从海康描述来说,非常适合,然后开始钻研,用了一个三天左右,成功迁移到vue项目,并实现预览,本来还要实现在预览画面上配置smart事件的区域,但是这个画面层级太高,我完全无法在画面上加个canvas,然后在canvas上作图.最终效果如下,切换通道可以切换画面

海康插件下载地址海康开放平台

1.把压缩包解压后,把

webVideoCtrl.js 
jsVideoPlugin-1.0.0.min.js
jquery-1.7.1.min.js三个文件拷贝到自己项目的src/utils文件夹下,然后你准备在哪个页面做预览效果,就在这个页面引入这三个js文件,webVideoCtrl.js的代码是需要改动的(改动是因为它本身是针对html也就是压缩包那样的结构去做的,现在为了适配我的vue,需要改代码,如果你直接使用原html页面,那本文章就不需要参考,你可以demo文件夹直接放在public下,然后vue中跳转,地址就是/demo/index.html,最终会指向public/demo/index.html,然后把除了画面以外的所有样式都改为不可见,注意不能把多余的登陆预览回放组件删掉,否则会有很多调不通的报错),jsVideoPlugin-1.0.0.min.js的代码不需要改动,jquery-1.7.1.min.js也不需要改动

这边我为了修改webVideoCtrl.js先用idea打开然后格式化了这个文件,格式化之后,里面会有if else导致的报错 比如if(a) b else c;把它换行成

if(a) b

else c 就是如果不用大括号包起来,if和else代码不能在同一行

vue页面代码如下

 开始绘制停止绘制清除绘制人类车辆确 定取 消import { addByServerIdAndAlgId,addByServerIdAndPointId,deleteByServerIdAndPointId,deleteByServerIdAndAlgId,setRule,addAlgorithmServer, delAlgorithmServer, getAlgorithmServer, listAlgorithmServer, updateAlgorithmServer,getRuleByServerIdAndAlgIdAndPointId } from '@/api/alg/algorithmServer'import { listMonitorPointAll } from '@/api/alg/monitorPoint';import { listAlgorithmAll } from '@/api/alg/algorithm';import $ from '@/utils/webVideoCtrl';import a from '@/utils/jsVideoPlugin-1.0.0.min';import b from '@/utils/jquery-1.7.1.min';import axios from "axios";export default {name: 'smartEvent',data() {return {points:[],algorithms:[],directionList:[{label:'左->右',value:"left-right"},{label:'左右',value:"any"},{label:'左{this.points=res.data.points;this.algorithms=res.data.algorithms;if (res.data.points.length!=0){this.ruleForm.monitorPointId=res.data.points[0].id;}if(res.data.algorithms.length!=0){this.algorithmId=res.data.algorithms[0].id;}this.$forceUpdate;WebVideoCtrl.I_InitPlugin({bWndFull: false, //是否支持单窗口双击全屏,默认支持 true:支持 false:不支持iWndowType: 1,bDebugMode: true,cbInitPluginComplete: function () {WebVideoCtrl.I_InsertOBJECTPlugin("divPlugin").then(() => {console.log("插件初始化")// 检查插件是否最新WebVideoCtrl.I_CheckPluginVersion().then((bFlag) => {if (bFlag) {alert("检测到新的插件版本,双击开发包目录里的HCWebSDKPlugin.exe升级!");}});}, () => {alert("插件初始化失败,请确认是否已安装插件;如果未安装,请双击开发包目录里的HCWebSDKPlugin.exe安装!");axios.get('/file/HCWebSDKPlugin.exe',{responseType: 'blob'}).then(res => {console.log(res);const url = window.URL.createObjectURL(new Blob([res.data]));const link = document.createElement('a');link.href = url;link.setAttribute('download', 'HCWebSDKPlugin.exe');document.body.appendChild(link);link.click();})});}});if (this.algorithmId&&this.ruleForm.monitorPointId){console.log("预览初始化")this.getRule();};})},methods: {handleClick(tab, event){for(let i =0;i=4){return;}this.actionArr.push({x:e.offsetX,y:e.offsetY})this.drawActionArr();}},mouseMove(e){console.log(e);},filterAlg(){this.ShowAlgList=this.AllAlgList.filter(function (element,index,array){return element.name.search(e)!=-1;})},filterChannel(e){this.ShowPointList=this.AllPointList.filter(function (element,index,array){return element.name.search(e)!=-1;})},handleAlgAdd(index){let element = this.ShowAlgList[index];let find=this.form.algorithms.find((value => value.id==element.id));if (!find){addByServerIdAndAlgId({algorithmId:element.id,serverId:this.id}).then(response=>{this.form.algorithms.push(element);})}},handleChannelAdd(index){let element = this.ShowPointList[index];let find=this.form.points.find((value => value.id==element.id));if (!find){addByServerIdAndPointId({pointId:element.id,serverId:this.id}).then(response=>{this.form.points.push(element);})}},drawActionArr(){if (this.actionArr.length>0){const canvasDraw0 = this.$refs.canvas0;const ctx=canvasDraw0.getContext('2d');ctx.fillStyle="black";ctx.clearRect(0, 0, canvasDraw0.width, canvasDraw0.height)for (let i = 0; i <this.actionArr.length ; i++) {ctx.beginPath();ctx.arc(this.actionArr[i].x,this.actionArr[i].y,5,0,2*Math.PI,true);ctx.fill();ctx.closePath();ctx.font="20px Georgia";ctx.fillText(i+1,this.actionArr[i].x,this.actionArr[i].y)}ctx.beginPath();ctx.moveTo(this.actionArr[0].x,this.actionArr[0].y);for (let i = 1; i  {this.clearDraw();this.humanCheck=false;this.vehicleCheck=false;if (response.data){this.ruleForm = response.data;this.actionArr=this.ruleForm.coordinates" /> {this.loading = falsethis.form = response.datathis.open = truethis.title = '修改算法服务器'})},/** 提交按钮 */submitForm() {this.$refs['form'].validate(valid => {if (valid) {this.buttonLoading = trueif (this.form.id != null) {updateAlgorithmServer(this.form).then(response => {this.$modal.msgSuccess('修改成功')this.open = falsethis.getList()}).finally(() => {this.buttonLoading = false})} else {addAlgorithmServer(this.form).then(response => {this.$modal.msgSuccess('新增成功')this.open = falsethis.getList()}).finally(() => {this.buttonLoading = false})}}})},submitRuleForm() {if(this.drawFlag){alert("请先完成绘制");return;}this.$refs['ruleForm'].validate(valid => {if (valid) {this.buttonLoading = trueif (!this.humanCheck&&!this.vehicleCheck){this.ruleForm.detectionTarget='all'} else if(this.humanCheck&&!this.vehicleCheck){this.ruleForm.detectionTarget='human'}else if(!this.humanCheck&&this.vehicleCheck){this.ruleForm.detectionTarget='vehicle'}else {this.ruleForm.detectionTarget='human,vehicle'}if (this.actionArr.length!==0){this.ruleForm.coordinates= this.actionArr.map(function(value) {return {x:4*value.x,y:4*value.y}})}setRule(this.ruleForm).then(response => {this.$modal.msgSuccess('新增成功')this.openRule = falsethis.getList()}).finally(() => {this.buttonLoading = false})}})},/** 导出按钮操作 */handleExport() {this.$download.excel('/alg/algorithmServer/export', this.queryParams)}}}.hide {display: none;}.item {height: 30px;line-height: 30px;margin: 0 15px;}.plugin {width: 250px;height: 250px;}.channel-list {max-height: 660px;overflow: scroll;}::-webkit-scrollbar {width: 5px;height: 5px;}::-webkit-scrollbar-track {width: 6px;background: none;-webkit-border-radius: 2em;-moz-border-radius: 2em;border-radius: 2em;}::-webkit-scrollbar-thumb {background-color: rgba(144, 147, 153, .5);background-clip: padding-box;min-height: 28px;-webkit-border-radius: 2em;-moz-border-radius: 2em;border-radius: 2em;transition: background-color .3s;cursor: pointer;}::-webkit-scrollbar-thumb:hover {background-color: rgba(144, 147, 153, .3);}.view {min-width: 1120px;padding: 10px 15px;}

webVideoCtrl.js主要修改初始化插件的代码,原先有个获取dirName方法就是获取webVideoCtrl.js自己的文件路径前缀,通过这个路径拼接再去找到jsVideoPlugin.js,但是vue结构下打包后这个文件路径获取肯定不对,所有我把webVideoCtrl.js和jsVideoPlugin.js放到utils里,然后通过require([./xxx.js])的方法在webVideoCtrl.js中引入jsVideoPlugin.js,注意它是把整个jsVideoPlugin.js存到了自身的window.JSvideoPlugin变量中,方便之后调用,然后它这边还有个值得注意的是窗口号,因为我只需要单窗口,所有我的窗口号传的都0;

this.I_InitPlugin = function(options) {m_utilsInc.extend(m_options, options)if ('object' === typeof exports && typeof module !== 'undefined') {require([ './jsVideoPlugin-1.0.0.min.js'], function(o) {window.JSVideoPlugin = o.JSVideoPluginif (options.cbInitPluginComplete) {options.cbInitPluginComplete()}})} else if ('function' === typeof define && define.amd) {require([ './jsVideoPlugin-1.0.0.min.js'], function(o) {window.JSVideoPlugin = o.JSVideoPluginif (options.cbInitPluginComplete) {options.cbInitPluginComplete()}})} else {m_utilsInc.loadScript( './jsVideoPlugin-1.0.0.min.js', function() {if (options.cbInitPluginComplete) {options.cbInitPluginComplete()}})}window.addEventListener('resize', function() {if (m_pluginOBJECT !== null) {var oElem = $('#' + m_options.szContainerID)m_pluginOBJECT.JS_Resize(oElem.width(), oElem.height())}})window.addEventListener('unload', function() {})window.addEventListener('scroll', function() {})}