class VideoPlay { constructor(spaceId, websocket, socketCode, vModeObj = {}, options) { // spaceId,socketCode不能相同,vModeObj播放模式,是否轮播 this.handleName = spaceId; this.socketCode = socketCode; this.vModeObj = vModeObj; this.toolL = null; // 浏览器左侧、下方、右侧条宽度 this.toolH = null; // 浏览器上方的高度,放大缩小时会变化 this.fullToolL = null; // 最大化时浏览器左侧、下方、右侧条宽度 this.fullToolH = null; // 最大化时浏览器上方高度 this.space = document.querySelector(spaceId); // 传入的存放视频区域id或者class this.spaceStartOffsetLeft = document.querySelector(spaceId).offsetLeft; // 传入的存放视频区域距离浏览器左侧的距离,iframe另计算; this.spaceStartOffsetTop = document.querySelector(spaceId).offsetTop; // //传入的存放视频区域距离浏览器顶部的距离,iframe另计算; this.space = document.querySelector(spaceId); this.websocket = websocket; // 初始化websocket this.display = true; // 防止切换页面视频闪烁 this.iframetoWinX = 0; // iframe距离浏览器左边的距离 this.iframetoWinY = 0; // iframe距离浏览器顶部的距离 this.width = 0; // 实时存放视频区域宽度 this.height = 0; // 实存放视频区域高度 this.posX = 0; // 实时存放视频区域距离浏览器左边的距离 this.posY = 0; // 实时存放视频区域距离浏览器顶部的距离 this.scale = false; // 是否开始伸缩网页 this.defaults = { // 默认配置,可以通过option覆盖 protocol: defaultConfig.protocol, // 协议 letLoginIp: defaultConfig.loginIp, // 环境配置 letPort: defaultConfig.port, // 端口配置 letUserCode: localStorage.getItem("userId"), // 用户code wsUri: "ws://localhost:1234", token: localStorage.getItem("DAHUA_token"), // token getVersion: null, // option里面的获取版本信息的回调函数通知 loginSuccess: null, // 登陆成功会调通知 errorInfo: null, // 异常回调通知 isDefaultShow: true, // 是否默认显示视频 onCreateVideoSuccess: false // 客户端被拉起通知 }; this.startCoinRegionPOX = 0; // 默认menu菜单距离浏览器左边的距离 this.startCoinRegionPOY = 0; // 默认menu菜单距离浏览器顶部的距离 this.zoom = 1; // 默认伸缩;实时存放网页伸缩倍数 this.ifmToTop = 0; // iframe距离区域的距离 this.menuWidth1 = 0; // 实时菜单宽度 this.menuHeight1 = 0; // 实时菜单高度 this.settings = Object.assign({}, this.defaults, options); // 覆盖默认配置操作 this.websocketOnerror = false; this.ServerVersion = 8888888; // 模拟服务器版本号 this.ClientLocalVersion = 0; // 获取本地版本号 this._toolHeight = 0; // 顶部高度 this.status = true; // 记录显示隐藏 this.status = document.querySelector(spaceId).clientHeight !== 0; } // 初始化 init() { this.calcTools(); this.initClientPanel(); this.winMaxMinOpt(); window.addEventListener("resize", () => { this.resize(); }); window.onunload = () => { this.closeClient(); }; } // webSocket交互 webSocketSend(data) { if (this.websocket == null) { return; } if (this.websocket.readyState === 1) { this.websocket.send(data); } else { setTimeout(() => { this.webSocketSend(data); }, 1000); } } // 检测浏览器的缩放状态实现代码 detectZoom() { var ratio = 0; var screen = window.screen; var ua = navigator.userAgent.toLowerCase(); if (window.devicePixelRatio !== undefined) { ratio = window.devicePixelRatio; } else if (~ua.indexOf("msie")) { if (screen.deviceXDPI && screen.logicalXDPI) { ratio = screen.deviceXDPI / screen.logicalXDPI; } } else if ( window.outerWidth !== undefined && window.innerWidth !== undefined ) { ratio = window.outerWidth / window.innerWidth; } if (ratio) { ratio = Math.round(ratio * 100); } return ratio; } // 实时传递给客户端的位置大小 dragResize(width, height, posX, posY) { // 实时存储目前视频的大小位置; this.width = width; this.height = height; this.posX = posX; this.posY = posY; const params = { loginIp: this.settings.letLoginIp, method: "adjustSizePosition", params: { width: width, height: height, posX: this.posX, posY: this.posY, handleName: this.handleName }, userCode: this.settings.letUserCode, socketCode: this.socketCode }; this.webSocketSend(JSON.stringify(params)); } // 设置菜单遮挡问题 setCoinRegion(flag, dorpDownIdArr) { const isEmbed = flag; let menu; let menuLeftX = 0; let menuLeftY = 0; const arr = []; this.zoom = this.detectZoom() / 100; // 910add if (flag === true) { // const obj = {}; dorpDownIdArr.map((item, index) => { arr.push({}); // obj[index] = document.querySelector(v); menu = document.querySelector(item); // 菜单宽高 arr[index]["width"] = Math.round(menu.clientWidth * this.zoom); arr[index]["height"] = Math.round( menu.clientHeight * this.zoom ); // 菜单左上角相对浏览器左上角的坐标 // 菜单左上角相对浏览器左上角的坐标 menuLeftX = Math.round( menu.getBoundingClientRect().left * this.zoom - 2 ); menuLeftY = Math.round( menu.getBoundingClientRect().top * this.zoom + this._toolHeight ); arr[index]["posX"] = Math.round( menuLeftX + this.iframetoWinX * this.zoom ); arr[index]["posY"] = Math.round( menuLeftY + this.iframetoWinY * this.zoom ); }); /* Array.from(arguments).splice(1, Array.from(arguments).length - 1).forEach((v, index) => { arr.push({}); obj[index] = document.querySelector(v); menu = document.querySelector(dorpDownId); // 菜单宽高 arr[index]["width"] = Math.round(obj[index].clientWidth * _this.zoom); arr[index]["height"] = Math.round(obj[index].clientHeight * _this.zoom); // 菜单左上角相对浏览器左上角的坐标 menuLeftX = Math.round(obj[index].getBoundingClientRect().left* _this.zoom - 2); menuLeftY = Math.round(obj[index].getBoundingClientRect().top* _this.zoom + _this._toolHeight); arr[index]["posX"] = Math.round(menuLeftX + _this.iframetoWinX * _this.zoom); if (_this.zoom == 1) { //正常比例 arr[index]["posY"] = Math.round(menuLeftY + _this.iframetoWinY * _this.zoom); } else { //缩放比例 if (menu) { arr[index]["posY"] = Math.round(obj[index].getBoundingClientRect().top * _this.zoom + _this.ifmToTop * _this.zoom +_this._toolHeight); //console.log(_this.startCoinRegionPOY,menu.getBoundingClientRect().top*_this.zoom,_this.ifmToTop,Math.round(window.parent.outerHeight - (window.parent.innerHeight)*_this.zoom),_this.zoom); } } }) */ } // console.log(arr); const params = { loginIp: this.settings.letLoginIp, method: "setCoinRegion", params: { bCoincide: isEmbed, region: arr, handleName: this.handleName }, userCode: this.settings.letUserCode, socketCode: this.socketCode }; this.webSocketSend(JSON.stringify(params)); } // 计算顶部距离,网页伸缩不变,这个针对不同分辨率的电脑,如果不准,第三方自己修改,只提供如下几种适配电脑。 calcTools() { // const toolh = Math.round(window.outerHeight - (window.innerHeight) * this.detectZoom() / 100); // this._toolHeight = toolh < 0 ? 80 : toolh; // this.zoom = this.detectZoom() / 100; this.zoom = this.detectZoom() / 100; // console.log(this.zoom); if (this.zoom === 0.67) { // 现场笔记本 this._toolHeight = 80; } else if (this.zoom === 1.5) { this._toolHeight = 110; } else if (this.zoom === 3) { this._toolHeight = 232; } else { const toolh = Math.round( window.outerHeight - (window.innerHeight * this.detectZoom()) / 100 ); this._toolHeight = toolh < 0 ? 90 : toolh; } } // 网页变操作化大小 resize() { // console.log(33333); console.log(this.status); console.log(this.vModeObj.embedVideoMode); // if (!this.status || !this.vModeObj.embedVideoMode) { // console.log('false'); // return false; // } const calcDomWidth = this.space.clientWidth || this.space.getBoundingClientRect().width; const calcDomheight = this.space.clientHeight || this.space.getBoundingClientRect().height; const zoom = this.detectZoom() / 100; const realClientWidth = Math.round(calcDomWidth * zoom); const realClientHeight = Math.round(calcDomheight * zoom); console.log("zoom---_toolHeight---", zoom, this._toolHeight); // 防止初始化后设置隐藏hide后拖动浏览器再show显示在左上方问题 if (this.space.clientWidth === 0 && this.space.clientHeight === 0) { return; } if (zoom === 1) { // 默认伸缩状态 // posX:距离浏览器左顶点横轴距离;posY:距离浏览器左顶点纵轴距离 let posX = this.space.getBoundingClientRect().left; let posY; if (window.outerWidth === window.innerWidth) { // 普通浏览器最大化状态 if (this.fullToolH == null) { // 为空时才计算,避免上下拖动改变浏览器大小事,视频窗口抖动 this.fullToolL = (window.outerWidth - window.innerWidth) / 2; // _this.fullToolH = window.outerHeight - window.innerHeight - _this.fullToolL + 10; this.fullToolH = this._toolHeight; } posY = this.space.getBoundingClientRect().top + this.fullToolH; } else if (window.outerWidth - window.innerWidth < 0) { // F11全屏窗口计算 posX = this.space.getBoundingClientRect().left; posY = this.space.getBoundingClientRect().top; } else { // 浏览器非最大化状态 if (this.toolH == null) { this.toolL = (window.outerWidth - window.innerWidth) / 2; this.toolH = window.outerHeight - window.innerHeight - this.toolL; } posX = this.space.getBoundingClientRect().left; posY = this.space.getBoundingClientRect().top + this.toolH + 0; } posX = Math.round(posX); posY = Math.round(posY); this.dragResize(realClientWidth, realClientHeight, posX, posY); console.log( "dragResize1-->", realClientWidth, realClientHeight, posX, posY ); } else { if ( window.outerHeight - window.innerHeight === 288 || window.outerWidth - window.innerWidth < 0 ) { // 最大化 const longW = Math.round( this.space.getBoundingClientRect().left * zoom ); const longH = Math.round( this.space.getBoundingClientRect().top * zoom ); this.dragResize( realClientWidth, realClientHeight, longW, longH ); console.log( "最大化dragResize2-->", realClientWidth, realClientHeight, longW, longH ); } else { const longW = Math.round( this.space.getBoundingClientRect().left * zoom ); const longH = Math.round( this.space.getBoundingClientRect().top * zoom + this._toolHeight ); this.dragResize( realClientWidth, realClientHeight, longW, longH ); console.log( "dragResize2-->", realClientWidth, realClientHeight, longW, longH ); } } } // 创建视频窗口 createVideoDialog(obj) { console.log(obj); const { rows = 2, cols = 2, wndSpaceing = 0, embedVideoMode = true, playerCtrlBarEnable = false, displayMode = 0, playMode = 0, playParams = {}, webControlExpend = false } = obj; let playParamsObj = null; playMode === 0 ? (playParamsObj = {}) : (playParamsObj = playParams); const params = JSON.stringify({ loginIp: this.settings.letLoginIp, userCode: this.settings.letUserCode, socketCode: this.socketCode, method: "CreateVideoDialog", params: { handleName: this.handleName, rows: rows, cols: cols, wndSpaceing: wndSpaceing, // 视频播放窗口间隔,默认为0 embedVideoMode: embedVideoMode, // 视频窗口是否为嵌入式。true:嵌入式(列表框云台和标题栏不展示),false:弹出式(展示列表框云台和标题栏) playerCtrlBarEnable: playerCtrlBarEnable, // 视频窗口上的鼠标云台是否使能。true:展示,false:不展示 displayMode: displayMode, // 窗口显示模式,用于播放控制栏0:视频监控,显示播放控制栏; 1:轮播,隐藏播放控制栏 playMode: playMode, // playMode:播放模式,0: 普通模式,1:轮播模式,默认为普通播放模式 playParams: playParamsObj, // playMode=0,playParams为空;playMode=1,playParams格式如下:// 轮播时间间隔,单位秒,默认为5s webControlExpend: webControlExpend } }); console.log(params); this.webSocketSend(params); } //初始化窗口 initClientPanel() { this.createVideoDialog(this.vModeObj); } // 实时预览视频 realTimeVideo( arr = [ { channelId: "" } ] ) { const params = JSON.stringify({ loginIp: this.settings.letLoginIp, method: "openVideo", params: { array: arr, // [{"channelId": channelId}] handleName: this.handleName }, userCode: this.settings.letUserCode, socketCode: this.socketCode }); this.webSocketSend(params); this.winMaxMinOpt(); } // 录像回放 //paramsArr传开始时间,结束时间,通道号 playBack(paramsArr) { this.resize(); const params = JSON.stringify({ loginIp: this.settings.letLoginIp, method: "openRecord", params: { array: paramsArr, // [{"beginTime": "2019-12-27 00:00:00","channelId": "mA2I9l1kA1BOPTAPHT74P8","endTime": "2019-12-27 23:59:59"}] handleName: this.handleName }, userCode: this.settings.letUserCode, socketCode: this.socketCode }); this.webSocketSend(params); this.winMaxMinOpt(); setTimeout(() => { this.resize(); }, 1000); } // 关闭客户端 closeClient() { const params = { loginIp: this.settings.letLoginIp, method: "logout", userCode: this.settings.letUserCode, socketCode: this.socketCode }; this.webSocketSend(JSON.stringify(params)); this.stopWebSocket(); this.websocket = null; } // debug(message) { // 客户端调试返回信息操作 // debugTextArea.value += message + "\n\n"; // debugTextArea.scrollTop = debugTextArea.scrollHeight; // } sendMessage() { const msg = document.getElementById("inputText").value; const strToSend = msg; if (this.websocket != null) { document.getElementById("inputText").value = ""; this.webSocketSend(strToSend); } } stopWebSocket() { if (this.websocket) { this.websocket.close(); } this.websocket = null; } // 客户端显示隐藏操作; showBrower(flag) { const params = { loginIp: this.settings.letLoginIp, method: "whetherShowVideoWnd", params: { bShow: flag, handleName: this.handleName }, userCode: this.settings.letUserCode, socketCode: this.socketCode }; this.display = flag; this.status = flag; console.log(flag); this.resize(); // 隐藏时候不走resize,显示时候感知下位置,但是,这不能加延时,否则切换标签页有问题。 this.webSocketSend(JSON.stringify(params)); } // 客户端-释放窗口 destroyVideoDialog() { const params = { loginIp: this.settings.letLoginIp, method: "DestroyVideoDialog", params: { handleName: this.handleName }, userCode: this.settings.letUserCode, socketCode: this.socketCode }; this.webSocketSend(JSON.stringify(params)); } // 视频置顶操作 setVideoWndOnTop(flag) { const params = { loginIp: this.settings.letLoginIp, method: "setVideoWndOnTop", params: { bOnTop: flag, handleName: this.handleName }, userCode: this.settings.letUserCode, socketCode: this.socketCode }; this.webSocketSend(JSON.stringify(params)); } // 最大化最小化操作; winMaxMinOpt() { if (document.addEventListener) { // debugger; document.addEventListener("webkitvisibilitychange", () => { // debugger; if (document.webkitVisibilityState === "hidden") { // 最小化 const temp = this.status; this.showBrower(false); this.status = temp; console.log("hidden"); } else if (document.webkitVisibilityState === "visible") { // 最大化 // 延时的目的:最大化的瞬间 走resize中的window.outerWidth - window.innerWidth < 0这个条件,缺少浏览器顶部栏的高度,导致高度上移 console.log("visible"); setTimeout(() => { this.showBrower(this.status); }, 200); } }); } } // 关闭所有视频 closeAllVideo() { const params = JSON.stringify({ loginIp: this.settings.letLoginIp, method: "closeVideo", userCode: this.settings.letUserCode, params: { handleName: this.handleName }, socketCode: this.socketCode }); this.webSocketSend(params); } // 拉app视频 openAppVideo(paramsArr) { const params = JSON.stringify({ loginIp: this.settings.letLoginIp, method: "openAppVideo", params: { handleName: this.handleName, array: paramsArr }, userCode: this.settings.letUserCode, socketCode: this.socketCode }); this.webSocketSend(params); } // 设置窗口分割数 setDesignDivision(rows, cols) { const params = JSON.stringify({ loginIp: this.settings.letLoginIp, method: "SetDesignDivision", userCode: this.settings.letUserCode, params: { handleName: this.handleName, rows: Number(rows), cols: Number(cols) }, socketCode: this.socketCode }); this.webSocketSend(params); } // 设置视频双击后位置大小 setDesignDivision(obj) { const { width = "0", height = "0", posX = "0", posY = "0" } = obj; const params = JSON.stringify({ loginIp: this.settings.letLoginIp, method: "expendVideoCtrl", userCode: this.settings.letUserCode, params: { handleName: this.handleName, expend: true, width: width, height: height, posX: posX, posY: posY }, socketCode: this.socketCode }); this.webSocketSend(params); } // 通用方法第三方传方法名和参数体 commonUse(method, paramsObj) { const params = JSON.stringify({ loginIp: this.settings.letLoginIp, method: method, userCode: this.settings.letUserCode, params: paramsObj, socketCode: this.socketCode }); this.webSocketSend(params); } } window.VideoPlay = VideoPlay;