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; // if(!isLogin) { // alert('请先登录再预览!'); // return; // } // let curChannel = channel + 1; //无插件通道号从1开始 // let stream = $stream.value - 0 || 0; // let firstTime = 0; // let ip = $ip.value; // let port = $port.value - 0; // let username = $user.value; // let password = $password.value; 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 切换码流 */ const onChangeStream = () => { onPreview(false, null, null, true); }; /** * @description 开启音频 */ const onTurnOnSound = () => { let vol = $volume.value - 0; if (playerInstance[WndIndex]) { playerInstance[WndIndex].setAudioVolume(vol); } }; /** * @description 关闭音频 */ const onTurnSoundOff = () => { if (playerInstance[WndIndex]) { playerInstance[WndIndex].setAudioVolume(0); } }; /** * @description 开启对讲 */ const onStartTalk = () => { let talkPlayer = null; let ip = $ip.value; let port = $port.value - 0; let username = $user.value; let password = $password.value; let curChannel = channel + 1; //无插件通道号从1开始 let rtspURL = "rtsp://" + "221.214.127.18" + ":" + "8200" + "/cam/realmonitor?channel=" + curChannel + "&subtype=0&proto=Private3"; let optionsAudio = { wsURL: "ws://" + "221.214.127.18" + ":" + "8200" + "/rtspoverwebsocket", rtspURL: rtspURL, username: "admin", password: "pyss2017", isTalkService: true, isPrivateProtocol: false, realm: RPC.realm, }; talkPlayer = new PlayerControl(optionsAudio); talkPlayer.talk("on"); talkInstance[WndIndex] = talkPlayer; }; /** * @description 关闭对讲 */ const onStopTalk = () => { if (talkInstance[WndIndex]) { talkInstance[WndIndex].talk("off"); talkInstance[WndIndex] = null; } }; /** * @description 抓图 */ const onSnap = () => { if (playerInstance[WndIndex]) { playerInstance[WndIndex].capture("test"); } }; /** * @description 针对直播的,开始本地下载 */ const onStartRecord = () => { let recordPlayer = null; let ip = $ip.value; let port = $port.value - 0; let username = $user.value; let password = $password.value; let stream = $stream.value - 0 || 0; let rtspURL = "rtsp://" + "221.214.127.18" + ":" + "8200" + "/cam/realmonitor?channel=" + curChannel + "&subtype=0&proto=Private3"; let optionsAudio = { wsURL: "ws://" + "221.214.127.18" + ":" + "8200" + "/rtspoverwebsocket", rtspURL: rtspURL, username: "admin", password: "pyss2017", isTalkService: true, isPrivateProtocol: false, realm: RPC.realm, }; recordPlayer = new PlayerControl(optionsAudio); recordPlayer.startRecord(true); recordInstance[WndIndex] = recordPlayer; }; /** * @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; } /** * @description 获取全屏状态 */ function getFull() { return ( window.top.document.mozFullScreen || window.top.document.webkitIsFullScreen || window.top.document.msFullscreenElement ); } /** * @description 全屏状态改变的回调事件 */ function fullscreenchange() { if (getFull()) { return; } else { exitfullScreen(); } } /** * @description 设置全屏 */ function setfullScreen() { let docElm = window.top.document.documentElement; if (docElm.requestFullScreen) { docElm.requestFullScreen(); } else if (docElm.mozRequestFullScreen) { docElm.mozRequestFullScreen(); } else if (docElm.webkitRequestFullScreen) { docElm.webkitRequestFullScreen(); } else if (docElm.msRequestFullscreen) { docElm.msRequestFullscreen(); } handleFullscreen(true); } /** * @description 退出全屏 */ function exitfullScreen() { let docElm = window.top.document.documentElement; if (docElm.exitFullscreen) { docElm.exitFullscreen(); } else if (docElm.mozCancelFullScreen) { docElm.mozCancelFullScreen(); } else if (docElm.webkitCancelFullScreen) { docElm.webkitCancelFullScreen(); } else if (docElm.msExitFullscreen) { docElm.msExitFullscreen(); } handleFullscreen(false); } /** * @description 处理全屏开关时的窗口大小 * @param {boolean} bool 是否要全屏 */ function handleFullscreen(bool) { if (bool) { let wrap = { position: "absolute", left: 0, top: 0, width: window.screen.width + "px", height: window.screen.height + "px", overflow: "visible", }; setStyle($video_wrap, wrap); } else { let wrap = { position: "relative", overflow: "hidden", width: "500px", height: "300px", }; setStyle($video_wrap, wrap); } } /** * @description ptz云台事件 * @param {string} type 云台事件类型 * @param {boolean} isStop 是否停止相应事件 */ window.onHandlePTZ = function (type, isStop) { let stepVal = $("#h5_ptz_step").value - 0; let arg2 = 0; let arg2Arr = ["LeftUp", "RightUp", "LeftDown", "RightDown"]; let presetArr = ["GotoPreset", "SetPreset", "ClearPreset"]; let presetNum = $("#h5_preset").value - 0; if (arg2Arr.indexOf(type) > -1) { arg2 = stepVal; } if (!isStop) { if (presetArr.indexOf(type) > -1) { /** * RPC.PTZManager 云台相关 * @param {string} 方法 * @param {number} channel 通道 * @param {object} 参数集合 */ RPC.PTZManager("start", channel, { code: type, arg1: presetNum, arg2: 0, arg3: 0, }); } else { RPC.PTZManager("start", channel, { code: type, arg1: stepVal, arg2: arg2, arg3: 0, }); } } else { RPC.PTZManager("stop", channel, { code: type, arg1: stepVal, arg2: arg2, arg3: 0, }); } }; //进入页面自动初始化 init();