Shi_zy

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){

}
});

 

 

posted on 2025-07-01 11:45  Shi_zy  阅读(519)  评论(1)    收藏  举报

导航