let qxToken; let qxUrl; let tyToken; let flvPlayer; let remoteId; let videoObject = { //设备编码 devCode: '', //远程录像ID remoteId: '', //播放状态 playState: false, //视频播放通道 videoType: '', recordVideoState: false } let puId; let tCode; function setParams(puid, tcode) { puId = puid; tCode = tcode; initVideo(); } function initVideo() { var passWay = localStorage.getItem("passWay"); if (passWay == null || passWay == '') { passWay = 'to-2'; } try { if (passWay == 'to-1') { getTYConnect(); } } catch (e) { console.error(e.message) } try { getQXConnect(); } catch (e) { console.error(e.message) } window.videos = videos = new VideoObj("videoDemo", 1, ty.connParams.address, ty.connParams.port, tyToken, 'video', 'callBack', 'false', ty.connParams.ak);//创建实例对象 } /** * @param {Object} eventContext 回调函数 * @param {Object} eventType */ window.callBack = function (eventType, eventContext) { switch (eventType) { case "104": //全屏 window.videos.fullScreen() break; case "105": //退出全屏 window.videos.exitScreen(); break; default: console.log("这是回调函数!!!") break; } } /** * 创建清新平台连接 */ function getQXConnect() { var passWay = localStorage.getItem("passWay"); if (passWay == null || passWay == '') { passWay = 'to-2'; } let params = { "address": _cf.connParams.address, "port": _cf.connParams.port, "user": _cf.connParams.user, "password": _cf.connParams.password, "epid": _cf.connParams.epid, "fixaddr": _cf.connParams.bfix } if (passWay == 'to-2' || passWay == 'to-4') { posts(_cf.q2http_urlN, 'login', params, function (rv) { let result = { errcode: -1, token: '' } let respJSON = JSON.parse(rv.responseText); if (respJSON.hasOwnProperty('errcode')) { result.errcode = respJSON.errcode; } if (respJSON.hasOwnProperty('token')) { result.token = respJSON.token; result.errcode = 0; if (!isEmpty(result.token)) { qxUrl = _cf.q2http_urlN; qxToken = result.token; QXPlayVideo(puId, '0', 'videoPlayer1'); } } }); } if (passWay == 'to-2' || passWay == 'to-3') { posts(_cf.q2http_url, 'login', params, function (rv) { let result = { errcode: -1, token: '' } let respJSON = JSON.parse(rv.responseText); if (respJSON.hasOwnProperty('errcode')) { result.errcode = respJSON.errcode; } if (respJSON.hasOwnProperty('token')) { result.token = respJSON.token; result.errcode = 0; if (!isEmpty(result.token)) { qxUrl = _cf.q2http_url; qxToken = result.token; QXPlayVideo(puId, '0', 'videoPlayer1'); } } }); } } /** * 统一视频平台获取token */ function getTYConnect() { var ak = ty.connParams.ak; var sk = ty.connParams.sk; let params = { ak, sk }; let url = ty.basePath + "uvp-backend-common/api/v1/authorization?timestamp=" + new Date().getTime(); $.ajax({ async: false, data: JSON.stringify(params), type: "POST", contentType: 'application/json', dataType: "json", url: url, success: function (result) { tyToken = result.resultValue.token; TYPlayVideo(1, devCode, "") } }) } /** * 清新播放视频 * @param puId * @param idx * @param dom 窗口id */ function QXPlayVideo(puId, idx, dom) { //播视频接口 destoryVideo(flvPlayer); let url = qxUrl + "stream.flv?puid=" + puId + "&idx=" + idx + "&stream=0&token=" + qxToken; console.log(url); if (flvjs.isSupported()) { let videoElement = document.getElementById(dom); if (videoElement) { flvPlayer = flvjs.createPlayer({ type: 'flv', // => 媒体类型 flv 或 mp4,m3u8 isLive: true, // => 是否为直播流 hasAudio: false, // => 是否开启声音 url: url, // => 视频流地址 stashInitialSize: 128 // 减少首桢显示等待时长 }, { enableWorker: false, //不启用分离线程 enableStashBuffer: false, //关闭IO隐藏缓冲区 reuseRedirectedURL: true, //重用301/302重定向url,用于随后的请求,如查找、重新连接等。 autoCleanupSourceBuffer: true, //自动清除缓存 fixAudioTimestampGap: false//false才会音视频同步 }); flvPlayer.attachMediaElement(videoElement); flvPlayer.load(); flvPlayer.on(flvjs.Events.ERROR, (errorType, errorDetail, errorInfo) => { if (flvPlayer) { //播放失败销毁窗口 destoryVideo(flvPlayer); videoObject.playState = false; } }); flvPlayer.on(flvjs.Events.SCRIPTDATA_ARRIVED, (errorType, errorDetail, errorInfo) => { if (flvPlayer) { videoObject.playState = true; $('.noVideoMask').css('background-image', 'none') //视频断流、延迟处理 $('#' + dom).attr("ontimeupdate", "progress(event)") } }); // 【重要事件监听】http请求建立好后,该事件会一直监听flvjs实例 flvPlayer.on(flvjs.Events.STATISTICS_INFO, (res) => { if (this.leaveRouter || this.changeLampPost) { // 离开路由或切换设备 // 销毁实例 destoryVideo(flvPlayer); videoObject.playState = false; } }); flvPlayer.play(); } } } /** * 播放视频 * @param {Object} winNum * @param {Object} devCode * @param {Object} devName */ function TYPlayVideo(winNum, devCode, devName) { videos.closeAllVideo(); /** * 需判断所选视频是否正在播放 * 关闭视频方法 * videos.closeAllVideo(); */ videoObject.playState = true; videos.videoPlay(winNum, 1, devCode, '', devName, 1); } /** * post 请求 * @param router * @param params * @param callback */ function requestPost(router, params, callback) { $.ajax({ type: 'post', url: qxUrl + router, data: params, traditional: true, dataType: 'json', async: true, complete: function (rv) { if (typeof callback == 'function') callback(rv) } }) } /** * post 请求 * @param url * @param router * @param params * @param callback */ function posts(url, router, params, callback) { $.ajax({ type: 'post', url: url + router, data: params, traditional: true, dataType: 'json', complete: function (rv) { if (typeof callback == 'function') callback(rv) } }) } /** * 远程录像/抓拍 * @param puid 球机puid * @param type 操作类型 * @param typeBall 平台类型 */ function remoteVideo(puid, type) { //清晰 let params = { idx: 0, puid: puid, type: type, duration: 5 } requestPost("CSS/C_CSS_StartManualStorage" + "?token=" + qxToken, params, function (data) { if (data.responseJSON.Error === '0') { if (type === 0) { layer.msg("开始录像成功", {icon: 1}); videoObject.remoteId = data.responseJSON.Param.ID } else { layer.msg("抓拍成功", {icon: 1}); setTimeout(function () { stopRemote(data.responseJSON.Param.ID, 1) }, 3000); } } } ) } /** * * @param id 流播放ID * @param type * @param typeBall */ function stopRemote(id, type) { //清晰 let params = { id: id } requestPost("CSS/C_CSS_StopManualStorage" + "?token=" + qxToken, params, function (data) { if (!isEmpty(data)) { if (type === 0) { layer.msg("停止录像成功", {icon: 1}); videoObject.remoteId = null; } } }); } /** * 平台操作 * @param puid * @param url */ function qxControl(puid, url) { let params = { puid: puid, idx: 0 } requestPost(url + '?token=' + qxToken, params, rv => { }) } /** * 球机旋转 * @param option * @param puid * @returns {Promise} */ async function turnControl(option, puid) { let params = { puid: puid, idx: 0, motion: option }; if (option != null) { requestPost('PTZ/C_PTZ_Turn?token=' + qxToken, params) } } /** * 销毁断流方法 * @param flvPlayer */ function destoryVideo(flvPlayer) { if (!isEmpty(flvPlayer)) { //flvPlayer.pause(); flvPlayer.unload(); flvPlayer.detachMediaElement(); //flvPlayer.destroy(); flvPlayer = null; } } /** * 录制视频 */ function recordVideo() { let video = $("#videoPlayer1")[0]; let encodeType = "video/webm;codecs=vp9"; let chunks = []; //创建MediaRecorder,设置媒体参数 let stream = video.captureStream(); let start = true; let recorder = new MediaRecorder(stream, { mimeType: encodeType }); //收集录制数据 recorder.ondataavailable = e => { chunks.push(e.data); }; $('#videoLocal')[0].onclick = function () { if (start) { videoObject.recordVideoState = true; layer.msg("开启本地录像", {icon: 0}); chunks = []; recorder.start(10); $(this).attr("src", "../../img/video/videoLocal-select.png"); start = false; } else { layer.msg("关闭本地录像", {icon: 0}); videoObject.recordVideoState = false; recorder.stop(); download(); $(this).attr("src", "../../img/video/videoLocal.png"); start = true; } } //下载录制内容 function download() { let blob = new Blob(chunks, {type: 'video/webm'}); let file = new window.File([blob], new Date().getTime() + ".webm", {type: 'video/webm'}) console.log(file); let formData = new FormData(); formData.append("multipartFile", file) let loadingMsg = layer.msg('视频加载中,请稍候...', {icon: 16, scrollbar: false, time: 0}); $.ajax({ url: dataUrl + 'system/sys/video/webmToMp4?token=' + token, type: 'POST', headers: { "encrypt": sm3(JSON.stringify(formData)) }, data: formData, dataType: 'json', processData: false,// ⑧告诉jQuery不要去处理发送的数据 contentType: false, // ⑨告诉jQuery不要去设置Content-Type请求头 beforeSend: function () { }, success: function (result) { if (result.code === 200) { layer.close(loadingMsg); uploadRectFile(result.data); } else { layer.msg('视频下载发生异常,请稍后重试', {icon: 16, scrollbar: false, time: 2000}); } }, error: function (result) { } }); } } /** * 本地抓拍 */ function screenshot() { let video = $("#videoPlayer1")[0]; let canvas = $('#canvasPlayer1')[0]; let ctx = canvas.getContext('2d'); let H = window.innerHeight; let W = window.innerWidth; const pixelRatio = window.devicePixelRatio || 1; const backingStoreRatio = ctx.webkitBackingStorePixelRatio || ctx.mozBackingStorePixelRatio || ctx.msBackingStorePixelRatio || ctx.oBackingStorePixelRatio || ctx.backingStorePixelRatio || 1; const ratio = pixelRatio / backingStoreRatio; canvas.width = $(video).width() * ratio; canvas.height = $(video).height() * ratio; canvas.style.width = W + 'px'; canvas.style.height = H + 'px'; ctx.scale(ratio, ratio); ctx.drawImage(video, 0, 0, $(video).width(), $(video).height()); // 将video中的数据绘制到canvas里 let image = canvas.toDataURL('image/jpg').replace('image/jpg', 'image/octet-stream'); saveAs(image, new Date().getTime() + '.png' || new Date().getTime() + '.png'); } /** * 播放延迟处理 * @param e */ function progress(e) { let bf = e.srcElement.buffered; let currentTime = e.srcElement.currentTime; if (bf.length > 0) { let end = bf.end(0); if (end - currentTime > 1.5) { e.srcElement.currentTime = end - 0.1; } } } /** * 球机页面双击全屏 * @param t */ function ballScreenBig(t) { console.log(t); let div = $('.noVideoMask')[0]; let fullscreenElement = document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement; if (fullscreenElement) { if (document.exitFullscreen) { document.exitFullscreen(); } else if (document.mozCancelFullScreen) { document.mozCancelFullScreen(); } else if (document.webkitExitFullscreen) { document.webkitExitFullscreen(); } } else { if (div.requestFullscreen) { div.requestFullscreen(); } else if (div.msRequestFullscreen) { div = document.body; div.msRequestFullscreen(); } else if (div.mozRequestFullScreen) { div.mozRequestFullScreen(); } else if (div.webkitRequestFullScreen) { div.webkitRequestFullScreen(); } } }