1. videowebplugin
hik web视频插件videowebplugin目前只支持配合div使用不,支持基于 iframe 方式也不支持浏览器页面弹出页面的使用方式 加载完成之后显示如下 如果是iframe中加载一个iframe用于打开页面,Chrome浏览器中点击插件会闪烁,分析jsWebControl-1.0.0.min.js可看到插件加载顺序为获取到play所在div位置(width和height,没有margin时,会按照默认计算),然后加载插件显示的位置,第二我理解为加载插件前置动画(后来查看到加载完成之后是动态img只是会一直不断加载,像是一个流,只是通过websocket一直接收然后渲染图像),第三步通过iscenter中心登录加载插件显示在初始化获取到的div的位置上。
插件位置对应的div
<div id="playWnd" class="playWnd" style="background-color: #515A6E"> function initPlugin () { oWebControl = new WebControl({ szPluginContainer: "playWnd", iServicePortStart: 15900, iServicePortEnd: 15909, szClassId:"23BF3B0A-2C56-4D97-9C03-0CB103AA8F11", // 用于IE10使用ActiveX的clsid cbConnectSuccess: function () { setCallbacks(); oWebControl.JS_StartService("window", { dllPath: "./VideoPluginConnect.dll" }).then(function () { oWebControl.JS_CreateWnd("playWnd", width, height).then(function () { initCamera(); }); }, function () { }); }, cbConnectError: function () { oWebControl = null; $("#weberr").html("插件未启动,正在尝试启动,请稍候..."); WebControl.JS_WakeUp("VideoWebPlugin://"); initCount ++; if (initCount < 3) { setTimeout(initPlugin, 3000); } else { $("#weberr").html("插件启动失败,请检查插件是否安装!"); } }, cbConnectClose: function (bNormalClose) { // JS_Disconnect正常断开:bNormalClose = true oWebControl = null; } }); }这个函数用于调用刚才安装的web插件,显示动画
function initCamera(){ getPubKey(function () { appkey = appkey.replace(/(^\s*)/g, ""); appkey = appkey.replace(/(\s*$)/g, ""); secret = setEncrypt(res_secret); secret = secret.replace(/(^\s*)/g, ""); secret = secret.replace(/(\s*$)/g, ""); ip = ip.replace(/(^\s*)/g, ""); ip = ip.replace(/(\s*$)/g, ""); szPort = szPort.replace(/(^\s*)/g, ""); szPort = szPort.replace(/(\s*$)/g, ""); snapDir = snapDir.replace(/(^\s*)/g, ""); snapDir = snapDir.replace(/(\s*$)/g, ""); videoDir = videoDir.replace(/(^\s*)/g, ""); videoDir = videoDir.replace(/(\s*$)/g, ""); var port = parseInt(szPort); var showSmart = parseInt(szShowSmart); var showToolbar = parseInt(szShowToolbar); var isHttps = "1"; var enableHttps = parseInt(isHttps); $(".encryptedFields").each(function (index, item) { var $item = $(item); if ($item.prop('checked')) { var value = $item.val(); if (value !== 'secret') { encryptedFields.push(value); } if (value == 'ip') { ip = setEncrypt(ip) } if (value == 'appkey') { appkey = setEncrypt(appkey) } if (value == 'snapDir') { snapDir = setEncrypt(snapDir) } if (value == 'videoDir') { videoDir = setEncrypt(videoDir) } if (value == 'layout') { layout = setEncrypt(layout) } } }); encryptedFields = encryptedFields.join(","); if (!appkey) { showCBInfo("appkey不能为空!", 'error'); return } if (!secret) { showCBInfo("secret不能为空!", 'error'); return } if (!ip) { showCBInfo("ip不能为空!", 'error'); return } if (!port) { showCBInfo("端口不能为空!", 'error'); return } else if (!/^([0-9]|[1-9]\d{1,3}|[1-5]\d{4}|6[0-5]{2}[0-3][0-5])$/.test(port)) { showCBInfo("端口填写有误!", 'error'); return } oWebControl.JS_RequestInterface({ funcName: "init", argument: JSON.stringify({ appkey: appkey, secret: secret, ip: ip, playMode: 0, // 预览 port: port, snapDir: snapDir, videoDir: videoDir, layout: layout, enableHTTPS: enableHttps, showToolbar: showToolbar, showSmart: showSmart, buttonIDs: btIds, encryptedFields: encryptedFields }) }).then(function (oData) { showCBInfo(JSON.stringify(oData ? oData.responseMsg : '')); UpdatePlayTypeValue(); UpdateSnapTypeValue(); UpdateSetOSDTypeValue(); }); }) }这两个方法加载完成之后插件就正常显示出来了,但是前边说过,hik只支持div,所以在此处需要修改一下插件加载方式。 解决方法
jsWebControl-1.0.0.min.js发现initPlugin和initCamera函数分别加载了插件,但是加载的方式不同。initPlugin加载通过最外层iframe开始计算div所在位置(或者说是浏览器的大小这样理解透彻一些),initCamera通过当前iframe计算div所在位置,结果就是两个插件显示位置不一样,导致插件闪烁。 所以我们可以修改js函数,当然这样最简单,但是难度太大,很多参数完全不知道内部方法,后边我就封装一个初始化方法,用于每次初始化width和height,获取上下左右。 function checkRise(){ clientHeight = window.parent.parent.document.documentElement.clientHeight; //当前页面高度 ifrHeight = document.documentElement.clientHeight; //head宽度 //topHeight = clientHeight - ifrHeight; //总宽度 clientWidth = window.parent.parent.document.documentElement.clientWidth; //当前页宽度 ifrtWidth = document.documentElement.clientWidth; //菜单宽度 // menuwidth = clientWidth - ifrtWidth; width = ifrtWidth - menuwidth - 200; height = ifrHeight - 23; } 第一次可以计算页面宽高,然后通过浏览器大小计算出加载插件的位置,第二步我们就可以移动插件到指定位置。监听浏览器大小事件和插件窗口大小改变事件‘’监听浏览器窗口改变大小事件
$(window).resize(function () { checkRise(); var newheight = clientHeight - topHeight - inittop - 5; var newWidth =clientWidth - menuwidth - 200; $("#playWnd").css("margin-top", Number(topHeight) + Number(inittop) -10 + "px"); $("#playWnd").css("margin-left", Number(menuwidth) + Number(initLeft) + 1 + "px"); $("#playWnd").css("width", newWidth + "px"); $("#playWnd").css("height", newheight + "px"); if (oWebControl != null) { oWebControl.JS_Resize(newWidth, newheight); //setWndCover(); $("#playWnd").css("margin-top", Number(inittop) +1 + "px"); $("#playWnd").css("margin-left", Number(initLeft) + 1 + "px"); /* $("#playWnd").css("width", newWidth + "px"); $("#playWnd").css("height", newheight + "px"); */ } });监听浏览器滚动事件
$(window).scroll(function () { checkRise(); var newheight = clientHeight - topHeight - inittop - 5; var newWidth =clientWidth - menuwidth - 200; $("#playWnd").css("margin-top", Number(topHeight) + Number(inittop) + "px"); $("#playWnd").css("margin-left", Number(menuwidth) + Number(initLeft) + 1 + "px"); $("#playWnd").css("width", newWidth + "px"); $("#playWnd").css("height", newheight + "px"); if (oWebControl != null) { oWebControl.JS_Resize(newWidth, newheight); //setWndCover(); $("#playWnd").css("margin-top", Number(inittop) + 15 + "px"); $("#playWnd").css("margin-left", Number(initLeft) + 1 + "px"); /* $("#playWnd").css("width", newWidth + "px"); $("#playWnd").css("height", newheight + "px"); } });后续我还补充了Windows隐藏和显示事件等,代码后续在下载中可自行下载。 2020-07-02更新
原插件不支持iframe以及插件闪烁问题说明 原开发文档中说明了不支持iframe,但是后续分析了原因,插件的位置是根据浏览器大小来计算得到一个位置,img是根据iframe位置计算得到一个位置,所以插件显示异常,出现各种问题。
解决方法其实前文已经详细描述过了,这里在分析一下 明白不支持iframe的原因,那就可以根据原因去一步一步实现了,按照上边的步骤封装初始化方法获取play div的位置,然后加载插件,获取img的位置,然后再去调用封装的初始化方法,计算得到img位置和play div位置的差别,然后根据封装的方法移动到和img重合即可,封装方法文章中已经有了。
关于修改js支持iframe的方法说明 此修改方法只是按照当前使用环境修改,如要求太高此方法不建议使用,耗时太多,需经过大量测试才可确定是否能够正常使用。如还需海康设置实时直播,可以使用IE8以上浏览器,采用IE内核开发无控件海康设备直播画面,效果很流畅,比使用此控件流畅,且此控件占用CPU和内存比较大。 之前有很多码农反应很多问题,后续我会努力解决大家问题,会根据问题类型更新此文章或者重写,毕竟我也看着有点乱,因为当时只是想分享出来。
插件和demo以及开发文档下载