1605 lines
54 KiB
JavaScript
1605 lines
54 KiB
JavaScript
/*
|
||
* 本文件仅供demo使用
|
||
*/
|
||
|
||
//webpack中引用此代码块,格式不要随意改动
|
||
//开发模式需要import,打包给3.0的变成了全局变量,不需要
|
||
var playerIndex = 0
|
||
|
||
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 += '<div wnd-index="' + i + '" style="float: left; background-color: #000; position: relative; width: 100%; height: 100%;overflow:hidden;border:1px solid rgb(125,125,125)"><canvas id="h5_canvas_' + i + '" style="width:100%;height:100%;"></canvas><p id="h5_loading_' + i + '" class="video_loading" style="display:none">加载中...</p><video id="h5_video_' + i + '" style="display: none;width:100%;height:100%;position:absolute;top:0;left:0"></video><canvas id="h5_ivs_' + i + '" style="position: absolute;left: 0;top: 0;width: 100%;height: 100%;" width="500" height="300"></canvas></div>';
|
||
}
|
||
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 = {
|
||
value:atob('MTkyLjE2OC4xMC4xMDg=')
|
||
};
|
||
$port = $('#h5_port');
|
||
// $user = $('#h5_user');
|
||
// $password = $('#h5_password');
|
||
$user = {
|
||
value:atob('YWRtaW4=')
|
||
};
|
||
$password = {
|
||
value:atob('YWYxMjM0NTYh')
|
||
};
|
||
$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);
|
||
}
|
||
|
||
$volume.addEventListener('input', function (event) {
|
||
let vol = event.target.value - 0;
|
||
$('#h5_volume_value').innerText = vol;
|
||
});
|
||
$volume.addEventListener('change', function (event) {
|
||
let vol = event.target.value - 0;
|
||
if (playerInstance[WndIndex]) {
|
||
playerInstance[WndIndex].setAudioVolume(vol);
|
||
}
|
||
});
|
||
$('#h5_first').addEventListener('click', function () {
|
||
if (curPage != 1) {
|
||
curPage = 1;
|
||
updateTable();
|
||
}
|
||
});
|
||
$('#h5_pre').addEventListener('click', function () {
|
||
if (curPage > 1) {
|
||
curPage = curPage - 1;
|
||
updateTable();
|
||
}
|
||
});
|
||
$('#h5_next').addEventListener('click', function () {
|
||
if (curPage < totalPage) {
|
||
curPage = curPage + 1;
|
||
updateTable();
|
||
}
|
||
});
|
||
$('#h5_last').addEventListener('click', function () {
|
||
if (curPage != totalPage) {
|
||
curPage = totalPage;
|
||
updateTable();
|
||
}
|
||
});
|
||
$('#h5_goPage').addEventListener('click', function () {
|
||
let val = $('#h5_goNumber').value - 0;
|
||
if (curPage != val) {
|
||
curPage = val;
|
||
updateTable();
|
||
}
|
||
});
|
||
['fullscreenchange', 'webkitfullscreenchange', 'mozfullscreenchange', 'msfullscreenchange'].forEach((item, index) => {
|
||
document.addEventListener(item, fullscreenchange, false);
|
||
});
|
||
}
|
||
/**
|
||
* @description 切换宫格时重新设置当前视频dom
|
||
*/
|
||
const setVideoDom = () => {
|
||
$canvas = $('#h5_canvas_' + WndIndex);
|
||
$video = $('#h5_video_' + WndIndex);
|
||
$canvas_ivs = $('#h5_ivs_' + WndIndex);
|
||
$videoLoading = $('#h5_loading_' + WndIndex);
|
||
}
|
||
/**
|
||
* @description 登录
|
||
*/
|
||
const onLogin = (id, playerStartTime, playerEndTime) => {
|
||
|
||
playerInstance.forEach(item => {
|
||
if (item) {
|
||
item.close();
|
||
item = null;
|
||
}
|
||
});
|
||
talkInstance.forEach(item => {
|
||
if (item) {
|
||
item.talk('off');
|
||
item = null;
|
||
}
|
||
});
|
||
recordInstance.forEach(item => {
|
||
if (item) {
|
||
item.startRecord(false);
|
||
item = null;
|
||
}
|
||
});
|
||
$('#h5_channel_list').innerHTML = '';
|
||
$('#h5_playback_channel').options.length = 0;
|
||
onlineChannel = [];
|
||
|
||
let ip = $ip.value;
|
||
let port = $port.value;
|
||
let target = ip + ':' + port;
|
||
setIP(target);
|
||
|
||
$loginState.innerHTML = '未登录';
|
||
$loginState.style.color = 'red';
|
||
/**
|
||
* RPC.login 登录
|
||
* @param {string} $user.value 用户名
|
||
* @param {string} $password.value 密码
|
||
* @param {boolean} true 是否httpOnly,默认false
|
||
* @returns {Promise}
|
||
*/
|
||
|
||
RPC.login($user.value, $password.value, false).then((res) => {
|
||
console.info('登录成功');
|
||
/**
|
||
* RPC.keepAlive 保活
|
||
*/
|
||
RPC.keepAlive(300, 60000, _getSession(), target);
|
||
const browser = BrowserType();
|
||
if (browser.includes('ie')) {
|
||
window.onunload = () => {
|
||
ajax({
|
||
url: 'global.logout'
|
||
});
|
||
};
|
||
} else if (browser.includes('chrome')) {
|
||
const params = {
|
||
method: 'global.logout',
|
||
params: null,
|
||
id: 10000,
|
||
session: _getSession()
|
||
};
|
||
pubsub.subscribe('onbeforeunload', () => {
|
||
navigator.sendBeacon('/RPC2', JSON.stringify(params));
|
||
});
|
||
} else {
|
||
pubsub.subscribe('onbeforeunload', () => {
|
||
ajax({
|
||
url: 'global.logout'
|
||
});
|
||
});
|
||
}
|
||
$loginState.style.color = 'green';
|
||
$loginState.innerHTML = '已登录';
|
||
// 查询对应编号的回放视频
|
||
onSearchRecord(id, playerStartTime, playerEndTime)
|
||
|
||
setLoginState(true);
|
||
afterLogin();
|
||
}).catch((err) => {
|
||
|
||
});
|
||
}
|
||
/**
|
||
* @description 登录之后调用,获取设备能力,获取通道、码流
|
||
*/
|
||
const afterLogin = () => {
|
||
$('#h5_playback_channel').options.length = 0;
|
||
$('#h5_channel_list').innerHTML = '';
|
||
/**
|
||
* RPC.getUrlData 获取设备上的文件
|
||
* @param {string} 文件路径
|
||
* @returns {Promise}
|
||
*/
|
||
RPC.getUrlData(`/web_caps/webCapsConfig?version=2.400&${new Date().getTime()}`).then(json => {
|
||
WebCaps = json;
|
||
if (WebCaps.deviceType.indexOf('SD') > -1 || WebCaps.deviceType.indexOf('IPC') > -1) {
|
||
/**
|
||
* RPC.DevVideoInput.getCollect 获取模拟输入通道数
|
||
* @returns {Promise}
|
||
*/
|
||
RPC.DevVideoInput.getCollect().then(function (params) {
|
||
let channelNum = params.channels;
|
||
for (let i = 0; i < channelNum; i++) {
|
||
let li = document.createElement('li');
|
||
li.innerHTML = 'D' + (i + 1);
|
||
li.setAttribute('channel', i);
|
||
li.style.width = '140px';
|
||
$('#h5_channel_list').appendChild(li);
|
||
$('#h5_playback_channel').options.add(new Option(i + 1, i));
|
||
}
|
||
document.querySelectorAll('#h5_channel_list li').forEach(item => {
|
||
item.addEventListener('click', function (event) {
|
||
event.stopPropagation();
|
||
let $el = event.target;
|
||
channel = $el.getAttribute('channel') - 0;
|
||
if (onlineChannel.indexOf(channel) > -1 && (channel != $canvas.parentNode.getAttribute('channel') - 0)) {
|
||
return;
|
||
}
|
||
if ($el.className.indexOf('fn-fontBlue') > -1 || $el.className.indexOf('fn-fontRed') > -1) {
|
||
onStopPreview();
|
||
} else {
|
||
onPreview(false);
|
||
}
|
||
});
|
||
});
|
||
});
|
||
}
|
||
}).catch(() => {
|
||
/**
|
||
* RPC.LogicDeviceManager.getCameraAll 获取所有用户可用视频源
|
||
* @returns {Promise}
|
||
*/
|
||
RPC.LogicDeviceManager.getCameraAll().then(function (params) {
|
||
let channelList = params.camera.filter(item => item.Enable === true);
|
||
//预览,在线通道列表
|
||
let channelArr = channelList.map(item => {
|
||
let _name;
|
||
item.DeviceInfo.VideoInputs.map(value => {
|
||
if (value && value.Enable) {
|
||
_name = value.Name;
|
||
}
|
||
});
|
||
return item.UniqueChannel + ';' + _name;
|
||
});
|
||
// 回放,全部通道列表
|
||
let allArr = params.camera.map(item => {
|
||
let _name;
|
||
if (item.DeviceInfo && item.DeviceInfo.VideoInputs) {
|
||
item.DeviceInfo.VideoInputs.map(value => {
|
||
_name = value && value.Name;
|
||
});
|
||
return item.UniqueChannel + ';D' + (item.UniqueChannel + 1) + ' ' + _name;
|
||
}
|
||
});
|
||
allArr.forEach((item) => {
|
||
if (item) {
|
||
let _item = item.split(';');
|
||
let _chan = _item[0] - 0;
|
||
let name = _item[1];
|
||
if (name) {
|
||
$('#h5_playback_channel').options.add(new Option(name, _chan));
|
||
}
|
||
}
|
||
});
|
||
|
||
channelArr.forEach((item) => {
|
||
let _item = item.split(';');
|
||
let _chan = _item[0] - 0;
|
||
let name = _item[1];
|
||
let li = document.createElement('li');
|
||
li.innerHTML = 'D' + (_chan + 1) + ' ' + name;
|
||
li.setAttribute('channel', _chan);
|
||
$('#h5_channel_list').appendChild(li);
|
||
});
|
||
document.querySelectorAll('#h5_channel_list li').forEach(item => {
|
||
item.addEventListener('click', function (event) {
|
||
event.stopPropagation();
|
||
let $el = event.target;
|
||
channel = $el.getAttribute('channel') - 0;
|
||
if (onlineChannel.indexOf(channel) > -1 && (channel != $canvas.parentNode.getAttribute('channel') - 0)) {
|
||
return;
|
||
}
|
||
if ($el.className.indexOf('fn-fontBlue') > -1 || $el.className.indexOf('fn-fontRed') > -1) {
|
||
onStopPreview();
|
||
} else {
|
||
onPreview(false);
|
||
}
|
||
});
|
||
});
|
||
});
|
||
});
|
||
|
||
$stream.options.length = 0;
|
||
/**
|
||
* RPC.MagicBox.getProductDefinition 获取产品定义
|
||
* @param {string} 'MaxExtraStream' 定义名称
|
||
* @returns {Promise}
|
||
*/
|
||
RPC.MagicBox.getProductDefinition('MaxExtraStream').then(function (params) {
|
||
let maxExtra = params.definition;
|
||
$stream.options.add(new Option('主码流', 0));
|
||
if (maxExtra > 1) {
|
||
for (let i = 1; i <= maxExtra; i++) {
|
||
$stream.options.add(new Option('辅码流' + i, i));
|
||
}
|
||
} else {
|
||
$stream.options.add(new Option('辅码流', 1));
|
||
}
|
||
});
|
||
|
||
let curDate = new Date();
|
||
let dateString = curDate.toLocaleDateString();
|
||
let dateSplit = dateString.split('/');
|
||
let month = dateSplit[1] - 0;
|
||
if (month < 10) {
|
||
dateSplit[1] = '0' + month;
|
||
}
|
||
let day = dateSplit[2] - 0;
|
||
if (day < 10) {
|
||
dateSplit[2] = '0' + day;
|
||
}
|
||
let date = dateSplit.join('-');
|
||
|
||
}
|
||
/**
|
||
* @description 注销
|
||
*/
|
||
const onLogout = () => {
|
||
/**
|
||
* RPC.Global.logout 注销接口
|
||
* @returns {Promise}
|
||
*/
|
||
RPC.Global.logout().then(function () {
|
||
$loginState.style.color = 'red';
|
||
$loginState.innerHTML = '未登录';
|
||
setLoginState(false);
|
||
playerInstance.forEach(item => {
|
||
if (item) {
|
||
item.stop();
|
||
item.close();
|
||
item = null;
|
||
}
|
||
});
|
||
cutInstance.forEach(item => {
|
||
if (item) {
|
||
item.stop();
|
||
item.close();
|
||
item = null;
|
||
}
|
||
});
|
||
talkInstance.forEach(item => {
|
||
if (item) {
|
||
item.talk('off');
|
||
item = null;
|
||
}
|
||
});
|
||
recordInstance.forEach(item => {
|
||
if (item) {
|
||
item.startRecord(false);
|
||
item = null;
|
||
}
|
||
});
|
||
$('#h5_channel_list').innerHTML = '';
|
||
$('#h5_playback_channel').options.length = 0;
|
||
document.querySelectorAll('[id^=h5_canvas_]').forEach(item => {
|
||
if (item.style.display === '') {
|
||
item.style.display = 'none';
|
||
}
|
||
});
|
||
document.querySelectorAll('[id^=h5_video_]').forEach(item => {
|
||
if (item.style.display === '') {
|
||
item.style.display = 'none';
|
||
}
|
||
});
|
||
});
|
||
}
|
||
/**
|
||
* @description 点击下一个宫格,在当前宫格成功拉流后,自动选中下一个宫格
|
||
*/
|
||
const clickNextWnd = () => {
|
||
let curWndType = document.querySelector('[sel-for=onChangeWdnNum]').value - 0;
|
||
if (curWndType === 2 && WndIndex === 3 || curWndType === 3 && WndIndex === 8 || curWndType === 4 && WndIndex === 15) {
|
||
document.querySelector('#h5_ivs_0').click();
|
||
} else {
|
||
document.querySelector('#h5_ivs_' + (WndIndex + 1)).click();
|
||
}
|
||
}
|
||
/**
|
||
* @description 预览
|
||
* @param {boolean} isPlayback 是否是回放
|
||
* @param {string} url 回放视频的url
|
||
* @param {number} playbackIndex 回放视频的索引
|
||
* @param {boolean} isChangeStream 是否是切换码流导致的重新拉流
|
||
* @param playerStartTime 开始时间戳
|
||
* @param playerEndTime 结束时间戳
|
||
*/
|
||
const onPreview = (isPlayback, url, playbackIndex, isChangeStream, playerStartTime,playerEndTime) => {
|
||
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://' + ip + ':' + port + '/rtspoverwebsocket',
|
||
rtspURL: !isPlayback ?
|
||
'rtsp://' + ip + ':' + port + '/cam/realmonitor?channel=' + curChannel + '&subtype=' + stream + '&proto=Private3' :
|
||
'rtsp://' + ip + ':' + port + '/' + url,
|
||
username: username,
|
||
password: password,
|
||
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) {
|
||
$videoLoading.style.display = 'none';
|
||
let curWndType = document.querySelector('[sel-for=onChangeWdnNum]').value - 0;
|
||
if (!player.isPlayback) {
|
||
onlineChannel.push(channel);
|
||
updateChannelList();
|
||
// if(curWndType !== 1) {
|
||
// clickNextWnd();
|
||
// }
|
||
}
|
||
if(player.isPlayback){
|
||
// 跳转指定时间播放
|
||
if(playerStartTime>15){
|
||
playerStartTime = playerStartTime - 15
|
||
}else{
|
||
playerStartTime = 0
|
||
}
|
||
player.playByTime(playerStartTime)
|
||
}
|
||
});
|
||
player.on('DecodeStart', function (e) {
|
||
console.log('DecodeStart',e)
|
||
if (e.decodeMode === 'video') {
|
||
$video.style.display = '';
|
||
$canvas.style.display = 'none';
|
||
} else {
|
||
$video.style.display = 'none';
|
||
$canvas.style.display = '';
|
||
}
|
||
canvasSon = new PluginCanvasES6();
|
||
|
||
canvasSon.init($canvas_ivs, function (data) {
|
||
rebackActivateLocalEnlarging(data);
|
||
});
|
||
canvasSon.addChangeShapeEvent();
|
||
playerInstance[WndIndex] = player;
|
||
ivsInstance[WndIndex] = canvasSon;
|
||
});
|
||
player.on('UpdateCanvas', function (e) {
|
||
// console.log('UpdateCanvas',e)
|
||
if (player.isPlayback) {
|
||
let playbackIndex = player.playbackIndex;
|
||
if (firstTime === 0) {
|
||
firstTime = e.timestamp;
|
||
}
|
||
//const _left = e.timestamp - new Date(recordArr[playbackIndex].StartTime).getTime()/1000;
|
||
$('#h5_curTime_' + playbackIndex % lINENUMBER).innerText = e.timestamp - firstTime;
|
||
}
|
||
});
|
||
player.on('GetTotalTime', function (e) {
|
||
let playbackIndex = player.playbackIndex % lINENUMBER;
|
||
$('#h5_totalTime_' + playbackIndex).innerText = e;
|
||
});
|
||
player.on('GetFrameRate', function (e) {
|
||
console.log('GetFrameRate: ' + e)
|
||
});
|
||
player.on('FrameTypeChange', function (e) {
|
||
console.log('FrameTypeChange: ' + e)
|
||
});
|
||
player.on('IvsDraw', function (e) {
|
||
console.log('IvsDraw: ' + JSON.stringify(e))
|
||
});
|
||
player.on('WorkerReady', function () {
|
||
console.log('WorkerReady')
|
||
player.connect();
|
||
});
|
||
player.on('FileOver', function () {
|
||
console.log('播放完成');
|
||
// if (playerIndex < recordArr.length - 1) {
|
||
// // 依次播放所有视频
|
||
// playerIndex++
|
||
// playerFun(playerIndex, 0, playerEndTime)
|
||
// }
|
||
})
|
||
player.on('UpdateTimeStamp', function (e) {
|
||
if(window.parent.onDhTimeUpdate){
|
||
window.parent.onDhTimeUpdate(e.timestamp)
|
||
}
|
||
if (e.timestamp > playerEndTime) {
|
||
console.log('UpdateTimeStamp-timestamp',e);
|
||
console.log('UpdateTimeStamp-playerEndTime',playerEndTime);
|
||
playerIndex = 0
|
||
onStopPreview()
|
||
// 加载下一个视频
|
||
if(window.parent.nextPlayer){
|
||
window.parent.nextPlayer(true)
|
||
}
|
||
}
|
||
|
||
})
|
||
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://' + ip + ':' + port + '/cam/realmonitor?channel=' + curChannel + '&subtype=5&proto=Private3';
|
||
let optionsAudio = {
|
||
wsURL: 'ws://' + ip + ':' + port + '/rtspoverwebsocket',
|
||
rtspURL: rtspURL,
|
||
username: username,
|
||
password: password,
|
||
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://' + ip + ':' + port + '/cam/realmonitor?channel=' + (channel + 1) + '&subtype=' + stream + '&proto=Private3';
|
||
let optionsRecord = {
|
||
wsURL: 'ws://' + ip + ':' + port + '/rtspoverwebsocket',
|
||
rtspURL: rtspURL,
|
||
username: username,
|
||
password: password,
|
||
isPrivateProtocol: false,
|
||
realm: RPC.realm
|
||
}
|
||
recordPlayer = new PlayerControl(optionsRecord);
|
||
recordPlayer.startRecord(true);
|
||
recordInstance[WndIndex] = recordPlayer;
|
||
}
|
||
/**
|
||
* @description 针对直播的,停止本地下载
|
||
*/
|
||
const onStopRecord = () => {
|
||
if (recordInstance[WndIndex]) {
|
||
recordInstance[WndIndex].startRecord(false);
|
||
recordInstance[WndIndex] = null;
|
||
}
|
||
}
|
||
/**
|
||
* @description 针对回放视频的,视频裁剪
|
||
*/
|
||
const onStartCut = () => {
|
||
let _cutIndex = document.querySelector('[btn-for=onStartCut]').getAttribute('cutIndex') - 0;
|
||
_cutIndex = _cutIndex + ((curPage - 1) * lINENUMBER);
|
||
let cutPlayer = null;
|
||
let ip = $ip.value;
|
||
let port = $port.value - 0;
|
||
let username = $user.value;
|
||
let password = $password.value;
|
||
let url = recordArr[_cutIndex].FilePath;
|
||
let _rtspURL = 'rtsp://' + ip + ':' + port + '/' + url;
|
||
let cutStartTime = $('#h5_cutStartTime').value;
|
||
let s = new Date(cutStartTime.replace('T', ' ')).getTime();
|
||
let startTime = new Date(recordArr[_cutIndex].StartTime).getTime();
|
||
let range1 = (s - startTime) / 1000;
|
||
let firstTime = 0;
|
||
let optionsRecord = {
|
||
wsURL: 'ws://' + ip + ':' + port + '/rtspoverwebsocket',
|
||
rtspURL: _rtspURL,
|
||
username: username,
|
||
password: password,
|
||
isPrivateProtocol: false, //是否私有协议,默认false
|
||
realm: RPC.realm, //登录返回的设备Realm值
|
||
speed: 16, //倍速拉流,16倍速
|
||
playback: true, //是都回放
|
||
isDownLoad: true,
|
||
range: range1 //视频裁剪时间与视频的StartTime时间差值
|
||
}
|
||
cutPlayer = new PlayerControl(optionsRecord);
|
||
cutPlayer.on('FileOver', function () {
|
||
console.log('File Over');
|
||
cutPlayer.startCut(false);
|
||
isCuting = false;
|
||
$('#h5_cut_process').innerText = '100%';
|
||
});
|
||
cutPlayer.on('UpdateTimeStamp', function (e) {
|
||
let cutStartTime1 = $('#h5_cutStartTime').value;
|
||
let cutEndTime1 = $('#h5_cutEndTime').value;
|
||
if (firstTime === 0) {
|
||
firstTime = e.timestamp;
|
||
}
|
||
let s1 = new Date(cutStartTime1.replace('T', ' ')).getTime() / 1000;
|
||
let e1 = new Date(cutEndTime1.replace('T', ' ')).getTime() / 1000;
|
||
let process = parseInt(((e.timestamp - firstTime) / (e1 - s1)) * 100);
|
||
// console.log(new Date(e.timestamp * 1000));
|
||
$('#h5_cut_process').innerText = (process > 100 ? 100 : process) + '%';
|
||
if ((e.timestamp >= s1) && !isCuting) {
|
||
cutPlayer.startCut(true);
|
||
isCuting = true;
|
||
}
|
||
if ((e.timestamp >= e1) && isCuting) {
|
||
cutPlayer.startCut(false);
|
||
isCuting = false;
|
||
$('#h5_cut_process').innerText = '100%';
|
||
}
|
||
});
|
||
cutPlayer.init($canvas, $video);
|
||
cutPlayer.connect(true);
|
||
cutInstance[WndIndex] = cutPlayer;
|
||
}
|
||
/**
|
||
* @description 开始下载录像
|
||
* @param {object} item 录像信息
|
||
*/
|
||
const onStartNVRDownload = (item) => {
|
||
let _cutIndex;
|
||
if (item) {
|
||
_cutIndex = item.selfCheckIndex;
|
||
}
|
||
let firstTime = 0;
|
||
let cutPlayer = null;
|
||
let ip = $ip.value;
|
||
let port = $port.value - 0;
|
||
let username = $user.value;
|
||
let password = $password.value;
|
||
let url = recordArr[_cutIndex].FilePath;
|
||
let _rtspURL = 'rtsp://' + ip + ':' + port + '/' + url;
|
||
let optionsRecord = {
|
||
wsURL: 'ws://' + ip + ':' + port + '/rtspoverwebsocket',
|
||
rtspURL: _rtspURL,
|
||
username: username,
|
||
password: password,
|
||
isPrivateProtocol: false,
|
||
realm: RPC.realm,
|
||
speed: 16,
|
||
playback: true,
|
||
isDownLoad: true
|
||
}
|
||
|
||
cutPlayer = new PlayerControl(optionsRecord);
|
||
|
||
cutPlayer.on('FileOver', function () {
|
||
console.log('File Over');
|
||
cutPlayer.startCut(false);
|
||
isCuting = false;
|
||
$('#h5_down_process').innerText = '100%';
|
||
downItemIndex++;
|
||
if (downList[downItemIndex]) {
|
||
onStartNVRDownload(downList[downItemIndex]);
|
||
}
|
||
});
|
||
cutPlayer.on('UpdateTimeStamp', function (e) {
|
||
let s1 = new Date(item.StartTime).getTime() / 1000;
|
||
let e1 = new Date(item.EndTime).getTime() / 1000;
|
||
if (firstTime === 0) {
|
||
firstTime = e.timestamp;
|
||
}
|
||
let process = parseInt(((e.timestamp - firstTime) / (e1 - s1)) * 100);
|
||
$('#h5_down_process').innerText = (process > 100 ? 100 : process) + '%';
|
||
if ((e.timestamp >= firstTime) && !isCuting) {
|
||
cutPlayer.startCut(true);
|
||
isCuting = true;
|
||
}
|
||
if ((e.timestamp >= e1 || process >= 100) && isCuting) {
|
||
cutPlayer.startCut(false);
|
||
isCuting = false;
|
||
$('#h5_down_process').innerText = '100%';
|
||
downItemIndex++;
|
||
if (downList[downItemIndex]) {
|
||
onStartNVRDownload(downList[downItemIndex]);
|
||
}
|
||
}
|
||
});
|
||
cutPlayer.init($canvas, $video);
|
||
cutPlayer.connect(true);
|
||
cutInstance[WndIndex] = cutPlayer;
|
||
}
|
||
const stopDownLoad = () => {
|
||
cutInstance.forEach(item => {
|
||
if (item) {
|
||
isCuting = false;
|
||
item.stop();
|
||
item.close();
|
||
item.startCut(false, true);
|
||
}
|
||
});
|
||
|
||
}
|
||
/**
|
||
* @description 开启电子放大
|
||
*/
|
||
const onStartEnlarge = () => {
|
||
if (ivsInstance[WndIndex]) {
|
||
ivsInstance[WndIndex].setRegionNum('rect', 1);
|
||
let param = { ...canvasParam };
|
||
ivsInstance[WndIndex].drawStart('rect', param);
|
||
curEnlargeWnd = WndIndex;
|
||
}
|
||
}
|
||
/**
|
||
* @description 开启区域放大
|
||
*/
|
||
const onStartGridEnlarge = () => {
|
||
document.querySelectorAll('[wnd-index]').forEach((item, index) => {
|
||
if (index === WndIndex) {
|
||
document.querySelector('[wnd-index="' + WndIndex + '"]').style.width = '500px';
|
||
document.querySelector('[wnd-index="' + WndIndex + '"]').style.height = '300px';
|
||
} else {
|
||
item.style.display = 'none';
|
||
}
|
||
});
|
||
}
|
||
/**
|
||
* @description 关闭区域放大
|
||
*/
|
||
const onCloseGridEnlarge = () => {
|
||
document.querySelectorAll('[wnd-index]').forEach((item, index) => {
|
||
item.style.display = '';
|
||
});
|
||
onChangeWdnNum();
|
||
}
|
||
/**
|
||
* @description 关闭电子放大
|
||
*/
|
||
const onStopEnlarge = () => {
|
||
if (curEnlargeWnd != WndIndex) return;
|
||
let dom = $canvas;
|
||
if (dom.style.display === 'none') {
|
||
dom = $video;
|
||
}
|
||
dom.style.width = '100%';
|
||
dom.style.height = '100%';
|
||
dom.style.left = 0;
|
||
dom.style.top = 0;
|
||
dom.style.position = 'static';
|
||
}
|
||
/**
|
||
* @description 绘制电子放大后的回调函数
|
||
* @param {object} data 矩形框的坐标信息
|
||
*/
|
||
const rebackActivateLocalEnlarging = data => {
|
||
if (curEnlargeWnd != WndIndex) return;
|
||
let pos = data.data;
|
||
let newData;
|
||
if (pos[0][0] === pos[1][0]) {
|
||
// return false;
|
||
} else {
|
||
newData = {
|
||
left: pos[0][0],
|
||
top: pos[0][1],
|
||
right: pos[1][0],
|
||
bottom: pos[1][1]
|
||
}
|
||
}
|
||
let dom = $canvas;
|
||
if (dom.style.display === 'none') {
|
||
dom = $video;
|
||
}
|
||
// 倒着画
|
||
if (newData.right < newData.left) {
|
||
let tmp = newData.left;
|
||
newData.left = newData.right;
|
||
newData.right = tmp;
|
||
}
|
||
|
||
if (newData.bottom < newData.top) {
|
||
let tmp = newData.top;
|
||
newData.top = newData.bottom;
|
||
newData.bottom = tmp;
|
||
}
|
||
|
||
let scaleW = $video_wrap.childNodes[0].clientWidth / 8191;
|
||
let scaleH = $video_wrap.childNodes[0].clientHeight / 8191;
|
||
|
||
let result = zoomArea(newData.left * scaleW, newData.top * scaleH, newData.right * scaleW, newData.bottom * scaleH, $video_wrap.childNodes[0].clientWidth, $video_wrap.childNodes[0].clientHeight);
|
||
dom.style.width = result.width + 'px';
|
||
dom.style.height = result.height + 'px';
|
||
dom.style.left = result.left + 'px';
|
||
dom.style.top = result.top + 'px';
|
||
dom.style.position = 'absolute';
|
||
ivsInstance[WndIndex].removeShapeDrawEvent();
|
||
}
|
||
/**
|
||
* @description 设置全屏
|
||
*/
|
||
const onSetFull = () => {
|
||
if (getFull()) {
|
||
exitfullScreen();
|
||
} else {
|
||
setfullScreen();
|
||
}
|
||
}
|
||
/**
|
||
* @description 查询录像
|
||
*/
|
||
const onSearchRecord = async (id, playerStartTime, playerEndTime) => {
|
||
let allRecords = [];
|
||
let recordNums = 0;
|
||
let playChannel = id;
|
||
|
||
const getMediaFile = (params) => {
|
||
return new Promise((resolve, reject) => {
|
||
/**
|
||
* RPC.MediaFileFind.instance 创建媒体文件查找实例
|
||
* @returns {Promise}
|
||
*/
|
||
RPC.MediaFileFind.instance().then(json => {
|
||
let queryId = json.result;
|
||
/**
|
||
* RPC.MediaFileFind.findFile 设置查找条件,并判断是否存在文件
|
||
* @param {number} queryId 实例id
|
||
* @param {object} params condition参数
|
||
* @returns {Promise}
|
||
*/
|
||
RPC.MediaFileFind.findFile(queryId, params).then(() => {
|
||
findNextFile(queryId).then(() => {
|
||
resolve(true);
|
||
}).catch((err) => {
|
||
reject(err);
|
||
});
|
||
}).catch((err) => {
|
||
reject(err);
|
||
});
|
||
}).catch((err) => {
|
||
reject(err);
|
||
});
|
||
});
|
||
}
|
||
const findNextFile = (queryId) => {
|
||
return new Promise((resolve, reject) => {
|
||
/**
|
||
* RPC.MediaFileFind.findNextFile 在指定条件基础上查询文件信息
|
||
* @param {number} queryId 实例
|
||
* @param {object} 需要查找的数目
|
||
* @returns {Promise}
|
||
*/
|
||
RPC.MediaFileFind.findNextFile(queryId, { 'count': 100 }).then(data => {
|
||
if (Number.isInteger(data.found)) {
|
||
recordNums = recordNums + data.found;
|
||
allRecords = allRecords.concat([...data.infos]);
|
||
if (data.found === 100) {
|
||
findNextFile(queryId).then(() => {
|
||
resolve(true);
|
||
}).catch((err) => {
|
||
reject(err);
|
||
});
|
||
} else {
|
||
recordArr = [...allRecords];
|
||
console.log(recordArr);
|
||
updateInfos(recordArr.slice(0, lINENUMBER));
|
||
updatePages();
|
||
stopFind(queryId);
|
||
resolve(true);
|
||
}
|
||
} else {
|
||
stopFind(queryId);
|
||
resolve(true);
|
||
}
|
||
}).catch((err) => {
|
||
reject(err);
|
||
stopFind(queryId);
|
||
});
|
||
|
||
})
|
||
}
|
||
const stopFind = object => {
|
||
return new Promise((resolve, reject) => {
|
||
/**
|
||
* PC.MediaFileFind.close 结束查询
|
||
* @param {number} object 媒体文件查找实例ID
|
||
* @returns {Promise}
|
||
*/
|
||
RPC.MediaFileFind.close(object).then(() => {
|
||
/**
|
||
* PC.MediaFileFind.destroy 销毁媒体文件查找实例
|
||
* @param {number} object 媒体文件查找实例ID
|
||
*/
|
||
RPC.MediaFileFind.destroy(object);
|
||
resolve(true);
|
||
}).catch(() => {
|
||
reject();
|
||
}).finally(() => {
|
||
});
|
||
})
|
||
}
|
||
const updateInfos = (infos) => {
|
||
let table = document.querySelector('#h5_table tbody');
|
||
table.innerHTML = '';
|
||
for (let i = 0; i < infos.length; i++) {
|
||
let time = infos[i].StartTime + ' - ' + infos[i].EndTime; //<input type="button" class="h5-button" btn-for="onGoTime" value="GO!">
|
||
let size = Math.round(infos[i].Length / 1024);
|
||
let newRow = table.insertRow(-1);
|
||
newRow.innerHTML = `<td><input type="checkbox" id="h5_check_${i}"></td><td>${i + 1}</td><td>${time}</td><td>${size}</td><td><span id="h5_curTime_${i}">--</span><span>/</span><span id="h5_totalTime_${i}">--</span><input type="text" id="h5_goTime_${i}" style="width: 50px;"><input type="button" class="h5-button" id="h5_button_go_${i}" value="GO!"></td>`;
|
||
}
|
||
document.querySelectorAll('[id^=h5_button_go_]').forEach(item => {
|
||
item.addEventListener('click', function (event) {
|
||
let id = item.getAttribute('id').split('_')[3] - 0;
|
||
onGoTime(id);
|
||
});
|
||
});
|
||
|
||
document.querySelectorAll('[id^=h5_check_]').forEach(function (item) {
|
||
item.addEventListener('click', function (event) {
|
||
event.stopPropagation();
|
||
if (event.target.checked) {
|
||
//渲染裁剪时间
|
||
let _index = event.target.getAttribute('id').split('_')[2] - 0;
|
||
let startTime = recordArr[_index + lINENUMBER * (curPage - 1)].StartTime.split(' ').join('T');
|
||
let endTime = recordArr[_index + lINENUMBER * (curPage - 1)].EndTime.split(' ').join('T');
|
||
if (startTime.split(':')[2] === '00') {
|
||
startTime = startTime.substr(0, startTime.length - 3);
|
||
}
|
||
if (endTime.split(':')[2] === '00') {
|
||
endTime = endTime.substr(0, endTime.length - 3);
|
||
}
|
||
$('#h5_cutStartTime').value = startTime;
|
||
$('#h5_cutEndTime').value = endTime;
|
||
document.querySelector('[btn-for=onStartCut]').setAttribute('cutIndex', _index);
|
||
}
|
||
});
|
||
});
|
||
|
||
document.querySelectorAll('#h5_table tbody tr').forEach(function (item) {
|
||
item.addEventListener('dblclick', function (event) {
|
||
event.stopPropagation();
|
||
if (event.target.nodeName === 'TD') {
|
||
event.target.style.color = 'blue';
|
||
let dom = event.target.parentNode.childNodes[1];
|
||
let value = dom.innerText - 1;
|
||
let url = recordArr[value].FilePath;
|
||
onStopPreview();
|
||
onPreview(true, url, value);
|
||
}
|
||
});
|
||
|
||
});
|
||
playerFun(playerIndex, playerStartTime, playerEndTime)
|
||
}
|
||
const updatePages = () => {
|
||
totalPage = Math.ceil(recordNums / lINENUMBER);
|
||
$('#h5_curPage').innerText = curPage;
|
||
$('#h5_totalPage').innerText = totalPage;
|
||
}
|
||
let tmpDir = [];
|
||
try {
|
||
/**
|
||
* RPC.getDeviceAllInfo 获取存储信息
|
||
* @param {string} 'getDeviceAllInfo' 方法名
|
||
* @return {Promise}
|
||
*/
|
||
tmpDir = await RPC.getDeviceAllInfo('getDeviceAllInfo');
|
||
} catch (e) {
|
||
console.log(e);
|
||
}
|
||
let dirs = null;
|
||
if (tmpDir.info && tmpDir.info.length > 1) {
|
||
dirs = 'All';
|
||
} else {
|
||
//dirs = tmpDir.info?[0]?.Detail?[0]?.Path ?? '/mnt/sd';
|
||
dirs = tmpDir.info && tmpDir.info[0] && tmpDir.info[0].Detail && tmpDir.info[0].Detail[0] && tmpDir.info[0].Detail[0].Path || '/mnt/sd';
|
||
}
|
||
|
||
let startTime = $('#h5_startTime').value.replace('T', ' ');
|
||
let endTime = $('#h5_endTime').value.replace('T', ' ');
|
||
if (startTime.split(' ')[1].split(':').length < 3) {
|
||
startTime = startTime + ':00';
|
||
}
|
||
if (endTime.split(' ')[1].split(':').length < 3) {
|
||
endTime = endTime + ':00';
|
||
}
|
||
let params = {
|
||
condition: {
|
||
Channel: playChannel,
|
||
Dirs: [dirs],
|
||
StartTime: startTime,
|
||
EndTime: endTime,
|
||
Flags: null,
|
||
Events: ['*'],
|
||
Types: ['dav']
|
||
}
|
||
};
|
||
getMediaFile(params).catch((err) => {
|
||
if (err && err.error && err.error.code === 285409409) {
|
||
alert('回放功能需要确保SD卡经过设备认证');
|
||
} else {
|
||
// alert('无数据');
|
||
}
|
||
});
|
||
}
|
||
/**
|
||
* @description 勾选当前页的全部录像
|
||
*/
|
||
const onCheckAll = () => {
|
||
let dom = $('#h5_checkAll');
|
||
let ele = document.querySelectorAll('[id^=h5_check_]');
|
||
let domChecked = dom.checked;
|
||
ele.forEach((item, index) => {
|
||
item.checked = domChecked;
|
||
})
|
||
}
|
||
/**
|
||
* @description 下载录像
|
||
*/
|
||
const onDownload = async () => {
|
||
let ele = document.querySelectorAll('[id^=h5_check_]');
|
||
downList = [];
|
||
ele.forEach((item, index) => {
|
||
let _id = item.getAttribute('id').split('_')[2] - 0;
|
||
if (item.checked) {
|
||
recordArr[(curPage - 1) * lINENUMBER + _id].selfCheckIndex = _id;
|
||
downList.push(recordArr[(curPage - 1) * lINENUMBER + _id]);
|
||
}
|
||
});
|
||
downItemIndex = 0;
|
||
onStartNVRDownload(downList[0]);
|
||
// if(WebCaps != null) {
|
||
// // let supportDownloadEncrypt = await RPC.MagicBox.getProductDefinition('SupportDownloadEncrypt').then(json => {
|
||
// // return !!json.SupportDownloadEncrypt;
|
||
// // }).catch(err => {
|
||
// // return false;
|
||
// // });
|
||
// const downFile = (name, href) => {
|
||
// let a = document.createElement('a');
|
||
// a.href = href;
|
||
// a.download = '';
|
||
// document.body.appendChild(a);
|
||
// a.click();
|
||
// setTimeout(() => {
|
||
// document.body.removeChild(a);
|
||
// }, 1000);
|
||
// };
|
||
// const loop = list => {
|
||
// if (list === undefined) {
|
||
// return;
|
||
// }
|
||
// // let tmpUrl = supportDownloadEncrypt ? '/RPC_Encrypt_Loadfile' : '/RPC_Loadfile';
|
||
// let tmpUrl = '/RPC_Loadfile';
|
||
// // let hrefs = window.location.origin + tmpUrl + list.FilePath;
|
||
// let hrefs = 'http://' + $ip.value + tmpUrl + list.FilePath;
|
||
// setTimeout( function () {
|
||
// downFile('', hrefs);
|
||
// loop(downList.shift());
|
||
// }, 1000);
|
||
// };
|
||
// loop(downList.shift());
|
||
// } else {
|
||
// onStartNVRDownload( downList[downItemIndex] );
|
||
// }
|
||
}
|
||
/**
|
||
* @description 更新录像列表当前页
|
||
*/
|
||
const updateTable = () => {
|
||
playerInstance.forEach(item => {
|
||
if (item) {
|
||
item.stop();
|
||
item.close();
|
||
item = null;
|
||
}
|
||
});
|
||
$('#h5_checkAll').checked = false;
|
||
$('#h5_curPage').innerText = curPage;
|
||
let table = document.querySelector('#h5_table tbody');
|
||
table.innerHTML = '';
|
||
let index = (curPage - 1) * lINENUMBER;
|
||
let infos = recordArr.slice(index, index + lINENUMBER);
|
||
for (let i = 0; i < infos.length; i++) {
|
||
let time = infos[i].StartTime + '-' + infos[i].EndTime;
|
||
let size = Math.round(infos[i].Length / 1024) + '(KB)';
|
||
let newRow = table.insertRow(-1);
|
||
newRow.innerHTML = `<td><input type="checkbox" id="h5_check_${i}"></td><td>${index + i + 1}</td><td>${time}</td><td>${size}</td><td><span id="h5_curTime_${i}">--</span><span>/</span><span id="h5_totalTime_${i}">--</span><input type="text" id="h5_goTime_${i}" style="width: 50px;"><input type="button" class="h5-button" id="h5_button_go_${i}" value="GO!"></td>`;
|
||
}
|
||
document.querySelectorAll('[id^=h5_button_go_]').forEach(function (item) {
|
||
item.addEventListener('click', function (event) {
|
||
let id = item.getAttribute('id').split('_')[3] - 0;
|
||
onGoTime(id);
|
||
});
|
||
});
|
||
document.querySelectorAll('[id^=h5_check_]').forEach(function (item) {
|
||
item.addEventListener('click', function (event) {
|
||
event.stopPropagation();
|
||
if (event.target.checked) {
|
||
//渲染裁剪时间
|
||
let _index = event.target.getAttribute('id').split('_')[2] - 0;
|
||
let startTime = recordArr[_index + lINENUMBER * (curPage - 1)].StartTime.split(' ').join('T');
|
||
let endTime = recordArr[_index + lINENUMBER * (curPage - 1)].EndTime.split(' ').join('T');
|
||
if (startTime.split(':')[2] === '00') {
|
||
startTime = startTime.substr(0, startTime.length - 3);
|
||
}
|
||
if (endTime.split(':')[2] === '00') {
|
||
endTime = endTime.substr(0, endTime.length - 3);
|
||
}
|
||
/* let _index = event.target.getAttribute('id').split('_')[2] - 0;
|
||
let startTime = recordArr[_index].StartTime;
|
||
let endTime = recordArr[_index].EndTime; */
|
||
$('#h5_cutStartTime').value = startTime;
|
||
$('#h5_cutEndTime').value = endTime;
|
||
document.querySelector('[btn-for=onStartCut]').setAttribute('cutIndex', _index);
|
||
}
|
||
});
|
||
});
|
||
document.querySelectorAll('#h5_table tbody tr').forEach(function (item) {
|
||
item.addEventListener('dblclick', function (event) {
|
||
event.stopPropagation();
|
||
let dom = event.target.parentNode.childNodes[1];
|
||
if (event.target.nodeName === 'TD') {
|
||
event.target.style.color = 'blue';
|
||
let value = dom.innerText - 1;
|
||
let url = recordArr[value].FilePath;
|
||
onPreview(true, url, value);
|
||
}
|
||
|
||
});
|
||
});
|
||
}
|
||
/**
|
||
* @description 暂停回放
|
||
*/
|
||
const onPausePlayback = () => {
|
||
if (playerInstance[WndIndex]) {
|
||
playerInstance[WndIndex].pause();
|
||
}
|
||
}
|
||
/**
|
||
* @description 继续回放
|
||
*/
|
||
const onContinuePlayback = () => {
|
||
if (playerInstance[WndIndex]) {
|
||
playerInstance[WndIndex].play();
|
||
}
|
||
}
|
||
/**
|
||
* @description 停止回放
|
||
*/
|
||
const onClosePlayback = () => {
|
||
if (playerInstance[WndIndex]) {
|
||
playerInstance[WndIndex].stop();
|
||
playerInstance[WndIndex].close();
|
||
playerInstance[WndIndex] = null;
|
||
let dom = $canvas;
|
||
if (dom.style.display === 'none') {
|
||
dom = $video;
|
||
}
|
||
dom.style.display = 'none';
|
||
}
|
||
}
|
||
/**
|
||
* @description 录像跳到指定时间
|
||
* @param 要跳转时间的录像的id
|
||
*/
|
||
const onGoTime = (id) => {
|
||
let curTime = $('#h5_goTime_' + id).value - 0;
|
||
console.log(curTime, 'xxxxx');
|
||
if (playerInstance[WndIndex]) {
|
||
playerInstance[WndIndex].playByTime(curTime);
|
||
}
|
||
}
|
||
const goTime = (time) => {
|
||
console.log(time);
|
||
if (playerInstance[WndIndex]) {
|
||
playerInstance[WndIndex].playByTime(time);
|
||
}
|
||
}
|
||
/**
|
||
* @description 切换窗口分割
|
||
*/
|
||
const onChangeWdnNum = () => {
|
||
let val = document.querySelector('[sel-for=onChangeWdnNum]').value;
|
||
let ivsDom = document.querySelectorAll('[id^=h5_ivs_]');
|
||
let divDom = document.querySelectorAll('.h5-play-wrap div');
|
||
if (val === '1') {
|
||
divDom.forEach(item => {
|
||
item.style.width = '100%';
|
||
item.style.height = '100%';
|
||
item.style.borderColor = '#000';
|
||
});
|
||
} else if (val === '2') {
|
||
divDom.forEach((item, index) => {
|
||
item.style.width = 'calc(50% - 2px)';
|
||
item.style.height = 'calc(50% - 2px)';
|
||
if (index === 0) {
|
||
item.style.borderColor = ' rgb(255, 204, 0)';
|
||
} else {
|
||
item.style.borderColor = ' rgb(125, 125, 125)';
|
||
}
|
||
});
|
||
} else if (val === '3') {
|
||
divDom.forEach((item, index) => {
|
||
item.style.height = 'calc(33.333% - 2px)';
|
||
item.style.width = 'calc(33.333% - 2px)';
|
||
if (index === 0) {
|
||
item.style.borderColor = ' rgb(255, 204, 0)';
|
||
} else {
|
||
item.style.borderColor = ' rgb(125, 125, 125)';
|
||
}
|
||
});
|
||
} else if (val === '4') {
|
||
divDom.forEach((item, index) => {
|
||
item.style.width = 'calc(25% - 2px)';
|
||
item.style.height = 'calc(25% - 2px)';
|
||
if (index === 0) {
|
||
item.style.borderColor = 'rgb(255, 204, 0)';
|
||
} else {
|
||
item.style.borderColor = 'rgb(125, 125, 125)';
|
||
}
|
||
});
|
||
}
|
||
ivsDom.forEach(item => {
|
||
item.setAttribute('width', `${item.parentNode.clientWidth}`);
|
||
item.setAttribute('height', `${item.parentNode.clientHeight}`);
|
||
});
|
||
ivsInstance.forEach(item => {
|
||
item && item.resize();
|
||
});
|
||
document.querySelector('#h5_ivs_0').click();
|
||
}
|
||
/**
|
||
* @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();
|