之前采用的UIKit的形式进行视频播放,因为业务要求转换成了Web视频控件的形式。但是Web控件存在不少的兼容性问题
- 开发的直播系统(www.a.com)是通过Iframe嵌入到门户网站(www.b.com)中,并且部署的地址不同于门户地址:
由于系统页面和门户网站不同域,导致测试环境无法正常打开插件,因此找运维进行nginx代理配置到同一域名下,后可以正常打开插件。 - 视频控件的层级导致弹框,下拉框等弹层被遮挡:
在弹层的弹出事件上调用oWebControl.JS_HideWnd方法,对视频控件进行隐藏,也可以采取oWebControl.JS_CuttingPartWindow对部窗口进行隐藏,但是计算较复杂,页面弹框较多,计算难度较大。 - 系统使用的react代码,如果在hooks上进行控件生成,会导致后台启动多个进程,导致电脑卡顿或者内存占用较大:
单独出来一个js方法,对视频控件实例进行存储,然后在外部调用初始化方法,这样可以避免重复初始化导致的内存问题
let oWebControl: any; // 播放器实例
let _oWebControlId: any; // 对应DomId
// 对插件进行初始化
export const webControlInit = ({
id,
cbConnectSuccess,
cbConnectError,
cbConnectClose
}: IWebControlInit) => {
if (!oWebControl || id !== _oWebControlId) {
_oWebControlId = id;
// @ts-ignore
oWebControl = new WebControl({
szPluginContainer: id,
iServicePortStart: 14510, // 对应 LocalServiceConfig.xml 中的ServicePortStart值
iServicePortEnd: 14519, // 对应 LocalServiceConfig.xml 中的ServicePortEnd值
cbConnectSuccess: cbConnectSuccess,
cbConnectError: cbConnectError,
cbConnectClose: cbConnectClose
});
}
return oWebControl;
};
- 由于门户网站外的菜单、tab切换,门户网站的点击事件并未向内部iframe通信,导致视频无法正常控制隐藏显示
采取监听dom情况的方法去解决,在window对象上增加监听事件,监听其blur,focus事件,当页面失焦了,对视频控件进行隐藏,聚焦后继续显示,但是这种方法还有一个问题,就是当点击视频控件的时候,会导致页面失焦,窗口会短暂隐藏,导致视频控件的截图,回放等功能无法正常使用。
经过一番研究,发现只能对视频控件范围的点击事件做特殊处理,通过监听mouseMove,记录鼠标的最后放置位置(由于鼠标在视频控件上时是无法触发mouseMove的,只能记录下来),然后在视频控件范围内的失焦事件,不触发JS_HideWnd,
let mouseEvent: MouseEvent | undefined = undefined;
// 允许的误差范围 避免挪入视频时鼠标的最终位置有误差
const range = 50;
// 监听
useEffect(() => {
window.addEventListener('blur', onBlur);
window.addEventListener('focus', pageShow);
window.addEventListener('mousemove', onMouseMove)
return () => {
window.removeEventListener("blur", onBlur);
window.removeEventListener("focus", pageShow);
window.removeEventListener("mousemove", onMouseMove);
};
}, []);
// 防抖 避免频繁操作
const { run: setMouseAsync } = useDebounceFn(
(val) => {
mouseEvent = val
},
{
wait: 300
}
)
// 监听move事件
const onMouseMove = (e: MouseEvent) => {
setMouseAsync(e);
}
// 监听失焦事件
const onBlur = () => {
try {
const el = document.getElementById("playWnd");
const { left, top, right, bottom } = el?.getBoundingClientRect() || { left: 0, top: 0, right: 0, bottom: 0 };
if (mouseEvent) {
const clientX = mouseEvent?.clientX;
const clientY = mouseEvent?.clientY;
if (
!(
(Math.abs(clientX - left) < range || Math.abs(clientX - right) < range || (clientX >= left && clientX <= right)) &&
(Math.abs(clientY - top) < range || Math.abs(clientY - bottom) < range || (clientY >= top && clientY <= bottom))
)
) {
pageHide();
}
}
} catch (error) {
console.log(error);
}
}
涉及到的场景比较特殊,是通过iframe嵌入系统,再在系统中打开视频控件,所以特别记录下