let $ip, $port, $user, $password, $loginState, $stream, $volume, $canvas, //canvas播放视频DOM $video, //video播放视频DOM $canvas_ivs, //canvas绘图DOM $video_wrap, //视频外层Wrap $videoLoading, //“加载中...”提示 WndIndex = 0, //宫格窗口Id WebCaps = null; //webCapsConfig文件转存变量 let isLogin = false; //是否登录 let channel = 0; //当前通道 let curPage = 1; //视频下载列表的当前页 let totalPage = 1; //视频下载列表的总页数 let recordArr = []; //视频文件数组 let canvasSon = null; //canvas绘图实例 let playerInstance = []; //播放|回放实例数组 let recordInstance = []; //录像下载实例数组 let talkInstance = []; //对讲实例数组 let ivsInstance = []; //canvas绘图实例数组 let cutInstance = []; //视频裁剪实例数组 let onlineChannel = []; //当前成功拉流的视频通道数组 let isCuting = false; //是否正在进行视频裁剪 let downList = []; //勾选的视频下载列表 let downItemIndex = 0; //视频下载索引 let canvasParam = { //canvas绘图默认传参 strokeColor: "#FF0000", title: "", resizeEnable: false, moveEnable: false, closeEnable: true, array: true, showSize: false, selectType: "inSide", disappear: true, selected: false, }; const lINENUMBER = 16; //回放列表每页显示录像条数 let curEnlargeWnd = 0; /** * @description 初始化 */ const init = () => { let videoStr = ""; for (var i = 0; i < 16; i++) { videoStr += '
'; } document.querySelector(".h5-play-wrap").innerHTML = videoStr; document.querySelectorAll(".h5-play-wrap div").forEach((item, index) => { item.addEventListener("click", function (event) { let _wndIndex = event.target.parentNode.getAttribute("wnd-index") - 0; if ( !(playerInstance[_wndIndex] && playerInstance[_wndIndex].isPlayback) ) { channel = event.target.parentNode.getAttribute("channel") - 0; document.querySelectorAll("#h5_channel_list li").forEach((item) => { item.classList.remove("fn-fontRed"); }); } document .querySelectorAll(".h5-play-wrap div") .forEach(function (item, index) { if (index === _wndIndex) { item.style.borderColor = "rgb(255, 204, 0)"; if ( !( playerInstance[_wndIndex] && playerInstance[_wndIndex].isPlayback ) ) { if (onlineChannel.indexOf(channel) > -1) { document .querySelector( '#h5_channel_list li[channel="' + channel + '"]' ) .classList.add("fn-fontRed"); } } WndIndex = _wndIndex; setVideoDom(); } else { item.style.borderColor = "rgb(125, 125, 125)"; } }); }); }); $ip = $("#h5_ip"); $port = $("#h5_port"); $user = $("#h5_user"); $password = $("#h5_password"); $loginState = $("#h5_loginState"); $stream = $("#h5_stream"); $volume = $("#h5_volume"); $video_wrap = document.querySelector(".h5-play-wrap"); setVideoDom(); let inputArr = document.querySelectorAll("input[btn-for]"); for (let node of inputArr) { node.addEventListener("click", bindClickEvent); } let selArr = document.querySelectorAll("select[sel-for]"); for (let node of selArr) { node.addEventListener("change", bindChangeEvent); } [ "fullscreenchange", "webkitfullscreenchange", "mozfullscreenchange", "msfullscreenchange", ].forEach((item, index) => { document.addEventListener(item, fullscreenchange, false); }); onPreview(false); }; /** * @description 切换宫格时重新设置当前视频dom */ const setVideoDom = () => { $canvas = $("#h5_canvas_" + WndIndex); $video = $("#h5_video_" + WndIndex); $canvas_ivs = $("#h5_ivs_" + WndIndex); $videoLoading = $("#h5_loading_" + WndIndex); }; /** /** * @description 预览 * @param {boolean} isPlayback 是否是回放 * @param {string} url 回放视频的url * @param {number} playbackIndex 回放视频的索引 * @param {boolean} isChangeStream 是否是切换码流导致的重新拉流 */ const onPreview = (isPlayback, url, playbackIndex, isChangeStream) => { if ( playerInstance[WndIndex] && onlineChannel.indexOf(channel) > -1 && !isChangeStream ) { alert("通道" + (channel + 1) + "已存在!"); return; } onStopPreview(); var player = null let options = { wsURL: "ws://" + "221.214.127.18" + ":" + "8200" + "/rtspoverwebsocket", rtspURL: "rtsp://" + "221.214.127.18" + ":" + "8200" + "/cam/realmonitor?channel=1" + "&subtype=0" + "&proto=Private3", username: "admin", password: "pyss2017", lessRateCanvas: true, playback: isPlayback, isPrivateProtocol: false, realm: RPC.realm, //设备登录返回的realm playbackIndex: playbackIndex, }; player = new PlayerControl(options); player.on("MSEResolutionChanged", function (e) { console.log(e); }); player.on("PlayStart", function (e) { console.log(e); $videoLoading.style.display = "none"; let curWndType = document.querySelector("[sel-for=onChangeWdnNum]").value - 0; if (!player.isPlayback) { onlineChannel.push(channel); updateChannelList(); // if(curWndType !== 1) { // clickNextWnd(); // } } }); player.on("GetFrameRate", function (e) { console.log("GetFrameRate: " + e); }); player.on("FrameTypeChange", function (e) { console.log("FrameTypeChange: " + e); }); player.on("Error", function (e) { //console.log('Error: ' + JSON.stringify(e)) }); player.on("IvsDraw", function (e) { //console.log('IvsDraw: ' + JSON.stringify(e)) }); player.on("WorkerReady", function () { player.connect(); }); player.init($canvas, $video); $canvas.parentNode.setAttribute("channel", channel); $videoLoading.style.display = ""; }; /** * @description 更新通道列表 */ const updateChannelList = () => { document.querySelectorAll("#h5_channel_list li").forEach((item) => { item.classList.remove("fn-fontBlue"); item.classList.remove("fn-fontRed"); if (onlineChannel.indexOf(item.getAttribute("channel") - 0) > -1) { item.classList.add("fn-fontBlue"); } }); }; /** * @description 停止预览 */ const onStopPreview = () => { if (playerInstance[WndIndex]) { playerInstance[WndIndex].stop(); playerInstance[WndIndex].close(); playerInstance[WndIndex] = null; let _index = onlineChannel.indexOf(channel); onlineChannel.splice(_index, 1); updateChannelList(); let dom = $canvas; if (dom.style.display === "none") { dom = $video; } dom.style.display = "none"; if (talkInstance[WndIndex]) { talkInstance[WndIndex].talk("off"); talkInstance[WndIndex] = null; } if (recordInstance[WndIndex]) { recordInstance[WndIndex].startRecord(false); recordInstance[WndIndex] = null; } } }; /** * @description 自定义选择器 * @param {string} str dom元素 */ function $(str) { if (str.charAt(0) == "#") { return document.getElementById(str.substring(1)); } else if (str.charAt(0) == ".") { return document.getElementsByClassName(str.substring(1)); } else { return document.getElementsByTagName(str); } } /** * @description 设置样式 * @param {object} obj dom元素 * @param {*} json css样式 */ function setStyle(obj, json) { for (let i in json) { obj.style[i] = json[i]; } } /** * @description 绑定click事件 * @param {object} event event对象 */ function bindClickEvent(event) { let $el = event.target, method = $el.getAttribute("btn-for"), disabled = $el.getAttribute("disabled"); if (!disabled) { eval(method + "()"); } } /** * @description 绑定change事件 * @param {object} event event对象 */ function bindChangeEvent(event) { let $el = event.target, method = $el.getAttribute("sel-for"), disabled = $el.getAttribute("disabled"); if (!disabled) { eval(method + "()"); } } /** * @description 设置登录状态 * @param {boolean} bool 设备是否已经登录 */ function setLoginState(bool) { isLogin = bool; } /** * @description 转换数据坐标 * @param {*} x1 左上角x坐标 * @param {*} y1 左上角y坐标 * @param {*} x2 右下角x坐标 * @param {*} y2 右下角y坐标 * @param {*} width 宫格宽 * @param {*} height 宫格高 */ function zoomArea(x1, y1, x2, y2, width, height) { // 小框区域的数据 let rectArea = { width: x2 - x1, height: y2 - y1, centerX: (x1 + x2) / 2, // 圆心坐标 centerY: (y1 + y2) / 2, }; // 放大比例,控件放大倍数上限是20 let scale = Math.min(width / rectArea.width, height / rectArea.height, 20); // 原始窗口信息 let sourceWin = { width: width, height: height, centerX: width / 2, centerY: height / 2, }; // 放大后的窗口区域 let bigWinArea = { width: width * scale, height: height * scale, left: sourceWin.centerX - rectArea.centerX * scale, top: sourceWin.centerY - rectArea.centerY * scale, }; // 数据矫正 if (bigWinArea.left > 0) { bigWinArea.left = 0; } if (bigWinArea.left < sourceWin.width - bigWinArea.width) { bigWinArea.left = sourceWin.width - bigWinArea.width; } if (bigWinArea.top > 0) { bigWinArea.top = 0; } if (bigWinArea.top < sourceWin.height - bigWinArea.height) { bigWinArea.top = sourceWin.height - bigWinArea.height; } return bigWinArea; } init();