html调用海康威视websdk3.4(解决iframe打开,以及iframe弹窗拖动,浏览器窗口变动播放窗口定位错误问题)
工作随笔,非专业前端,做个工作记录。
以下代码解决调用海康威视websdk 播放视频,视频插件在页面定位问题,可跟随窗口移动,和在iframe中插件定位错误问题。
直接上代码:
<div class="video-placeholder" id="video_container"> <div id="divPlugin" data-position_x="0" data-position_y="0"></div> </div>
在视频容器:<div id="divPlugin" data-position_x="0" data-position_y="0"></div>添加data属性position_x,position_y用来存储容器位置,计算插件偏移量。
修改 webvideoctrl.js 源码:
const P = () => { let t = $("#" + e.szContainerID), n = window.innerWidth || document.documentElement.clientWidth, r = window.innerHeight || document.documentElement.clientHeight; if (t.css('display') == "none") { return !1; } if (!t.length || !t.get(0)) return !1; let i = t.get(0).getBoundingClientRect(), o = e.iTopHeight || 0; const s = window.innerWidth - document.documentElement.clientWidth; let position_x = t.data("video_position_x");//修改部分------获取视频容器位置x坐标 let position_y = t.data("video_position_y");//修改部分------获取视频容器位置y坐标 let a = Math.max(0 - i.left, 0), d = Math.max(o - i.top, 0), c = Math.max(i.right - (n - s) - position_x, 0),//修改部分------计算偏移量减去x坐标 u = Math.max(i.bottom - r - position_y, 0),//修改部分------计算偏移量减去y坐标 l = t.width(), p = t.height(); a = Math.min(a, l), d = Math.min(d, p), c = Math.min(c, l), u = Math.min(u, p), a >= l || d >= p || c >= l || u >= p ? this.I_HidPlugin() : this.I_ShowPlugin(), m("left", Math.round(a)), m("top", Math.round(d)), m("right", Math.round(c)), m("bottom", Math.round(u)) }
在页面js中添加两个方法initVideoPosition()、getElementPositionInTopWindow()定位播放插件位置:
//定位插件位置 function initVideoPosition() { $("#divPlugin").css({}); var vt = window.parent; console.log(vt); if (vt.name.indexOf("iframe") >= 0 || vt != window.self) { var element = document.getElementById("video_container"); var iframePosition = $(window.frameElement).offset(); console.log("frame位置:", iframePosition); const parentPosition = getElementPositionInTopWindow(element, false); console.log("上层屏幕位置:", parentPosition); const position = getElementPositionInTopWindow(element, true); console.log("屏幕位置:", position); video_position_x = position.x - parentPosition.x + iframePosition.left; video_position_y = position.y - parentPosition.y + iframePosition.top; console.log("最终位置:", video_position_x, video_position_y); $("#divPlugin").css({ position: 'absolute', top: video_position_y, left: video_position_x, }); $("#divPlugin").data("video_position_x", video_position_x) $("#divPlugin").data("video_position_y", video_position_y) } } ///获取元素位置 function getElementPositionInTopWindow(targetElement, isTop) { let x = 0; let y = 0; let currentElement = targetElement; let currentWindow = targetElement.ownerDocument.defaultView; // 1. 获取元素在当前窗口中的位置 let rect = currentElement.getBoundingClientRect(); x = rect.left; y = rect.top; if (!isTop) { if (currentWindow !== currentWindow.parent) { const frameElement = currentWindow.frameElement; if (frameElement) { // 获取iframe在父文档中的位置 const frameRect = frameElement.getBoundingClientRect(); // 添加边框偏移 // if (config.includeBorders) { const style = getComputedStyle(frameElement); x += parseInt(style.borderLeftWidth) || 0; y += parseInt(style.borderTopWidth) || 0; // } x += frameRect.left; y += frameRect.top; // 添加父窗口滚动偏移 // if (config.includeScroll) { x += currentWindow.parent.scrollX; y -= currentWindow.parent.scrollY; // } return { x, y }; } } } // 2. 逐级向上遍历每个iframe层级 while (currentWindow !== top) { const frameElement = currentWindow.frameElement; // 3. 获取iframe边框厚度 const style = getComputedStyle(frameElement); const borderLeft = parseInt(style.borderLeftWidth) || 0; const borderTop = parseInt(style.borderTopWidth) || 0; // 4. 获取iframe在父文档中的位置 const frameRect = frameElement.getBoundingClientRect(); // 5. 累加位置和边框 x += frameRect.left + borderLeft; y += frameRect.top + borderTop; // 6. 考虑父窗口的滚动偏移 const parentWindow = currentWindow.parent; x += parentWindow.scrollX; y -= parentWindow.scrollY; // 7. 移动到上一层窗口 currentWindow = parentWindow; currentElement = frameElement; } // 8. 加上顶层窗口的滚动偏移 x += top.scrollX; y -= top.scrollY; return { x, y }; }
修改完成,开始初始化视频插件:
$(function () { WebVideoCtrl.I_InitPlugin({ bWndFull: true,//是否支持单窗口双击全屏,默认支持 true:支持 false:不支持 iWndowType: 1, cbSelWnd: function (xmlDoc) { g_iWndIndex = parseInt($(xmlDoc).find("SelectWnd").eq(0).text(), 10); var szInfo = "当前选择的窗口编号:" + g_iWndIndex; console.log(szInfo); }, cbDoubleClickWnd: function (iWndIndex, bFullScreen) { var szInfo = "当前放大的窗口编号:" + iWndIndex; if (!bFullScreen) { szInfo = "当前还原的窗口编号:" + iWndIndex; } console.log(szInfo); }, cbEvent: function (iEventType, iParam1, iParam2) { if (2 == iEventType) { // 回放正常结束 console.log("窗口" + iParam1 + "回放结束!"); } else if (-1 == iEventType) { console.log("设备" + iParam1 + "网络错误!"); } else if (3001 == iEventType) { clickStopRecord(g_szRecordType, iParam1); } }, cbInitPluginComplete: function () { WebVideoCtrl.I_InsertOBJECTPlugin("divPlugin").then(() => { // 检查插件是否最新 WebVideoCtrl.I_CheckPluginVersion().then((bFlag) => { if (bFlag) { alert("检测到新的插件版本,请安装最新版插件!"); } }); initVideoPosition(); WebVideoCtrl.I_Resize($(".video-placeholder").width(), $(".video-placeholder").height()); }, () => { alert("插件初始化失败,请确认是否已安装插件!"); }); } }); // 窗口事件绑定 $(window).bind({ resize: function () { // const offset = window.top.$('iframe').offset(); initVideoPosition(); console.log($("#divPlugin").width(), $("#divPlugin").height()) WebVideoCtrl.I_Resize($(".video-placeholder").width(), $(".video-placeholder").height()); } }); });
在视频插件页面封装一个方法,定位插件位置和改变窗口大小:
function MoveEndIframe() { initVideoPosition() WebVideoCtrl.I_Resize($(".video-placeholder").width(), $(".video-placeholder").height()); }
以下是使用iframe打开页面代码,以layui 弹框为例,在moveEnd 、 success 、end回调函数中根据以下代码修改,调用,解决弹框拖动视频插件跟随窗口拖动:
layui 弹窗代码: layer.open({ type: 2, area: ['680px', '520px'], content: '/layer/test/iframe.html', fixed: false, // 不固定 maxmin: true, shadeClose: true, btn: ['获取表单值', '取消'], btnAlign: 'c', moveEnd:function(layero) { var iframeWin = $(layero).find('iframe')[0]; iframeWin.contentWindow.MoveEndIframe(); }, success:function (layero) { //添加防抖函数 var debounce = function(fn, delay) { var timer; return function() { clearTimeout(timer); timer = setTimeout(fn, delay); }; }; ///监听窗口大小改变,重新定位插件位置 var handleResize = debounce(function() { var iframeWin = $(layero).find('iframe')[0]; iframeWin.contentWindow.MoveEndIframe(); }, 300); // 300ms防抖 // 绑定resize事件 window.addEventListener('resize', handleResize); // 存储事件引用(用于关闭时移除) layero.data('resizeHandler', handleResize); }, end:function () { var handler = $(this).data('resizeHandler'); if (handler) { window.removeEventListener('resize', handler); } } yes: function(index, layero){ } });
浙公网安备 33010602011771号