引入海康威视插件

This commit is contained in:
zhoumengru
2025-09-11 16:14:55 +08:00
parent 671dd9fec7
commit e995c25fd2
57 changed files with 11735 additions and 2304 deletions

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@@ -0,0 +1,87 @@
importScripts('AudioAMER.js');
let channelNum = 2; // 通道数需求上只需要2通道不用改
let sampleRate = 32000; // 采样率支持8K/16K/32K/48K
let bitsPerSample = 16; // 采样精度支持16/32
let dataLen = 320; // 一帧数据长度采样点数320个16位采样点即640B支持4/8/10/16/20/24/30/32/40ms
// self.JSAudioCodecModule['onRuntimeInitialized'] = function () {
// JSAudioCodecModule().then(instance => {
// AudioModule = instance;
// });
// postMessage({type: "loaded"});
// };
JSAudioCodecModule().then(instance => {
AudioModule = instance;
postMessage({type: "loaded"});
});
onmessage = function (e) {
let data = e.data;
if ("create" === data.type) {
let size = AudioModule._malloc(4);
let alignment = AudioModule._malloc(4);
if (size === null || alignment === null) {
console.log("inputdata malloc failed!!!");
return -1;
}
channelNum = data.channelNum;
sampleRate = data.sampleRate;
bitsPerSample = data.bitsPerSample;
dataLen = data.dataLen;
let iRet = AudioModule._JSHIK_AMER_GetMemSize(channelNum, sampleRate, bitsPerSample, dataLen, size, alignment);
if (iRet !== 1) {
console.log("_CreatHandle failed!" + iRet);
} else {
let sizeOut = AudioModule.getValue(size, "i32");
let alignmentOut = AudioModule.getValue(alignment, "i32");
iRet = AudioModule._JSHIK_AMER_Create(channelNum, sampleRate, bitsPerSample, dataLen, sizeOut, alignmentOut);
console.log("Create_res:" + iRet);
postMessage({type: "created"});
}
if (size !== null) {
AudioModule._free(size);
size = null;
}
if (alignment !== null) {
AudioModule._free(alignment);
alignment = null;
}
} else if ("inputData" === data.type) {
let inputSize = dataLen * 2;//dataLen为320inputSize应该是 320 * 2 = 640
let pInputData1 = AudioModule._malloc(inputSize);
let pInputData2 = AudioModule._malloc(inputSize);
let pOutputData1 = AudioModule._malloc(inputSize);
let pOutputData2 = AudioModule._malloc(inputSize);
let pOutputData3 = AudioModule._malloc(inputSize);
if (pInputData1 === null || pInputData2 === null || pOutputData1 === null || pOutputData2 === null || pOutputData3 === null) {
console.log("inputdata or outputData malloc failed!!!");
return -1;
}
let inputData1 = new Uint8Array(data.buf1);
let inputData2 = new Uint8Array(data.buf2);
AudioModule.writeArrayToMemory(inputData1, pInputData1);
AudioModule.writeArrayToMemory(inputData2, pInputData2);
inputData1 = null;
inputData2 = null;
// 开始处理
let res = AudioModule._JSHIK_AMER_Process(pInputData1, pInputData2, pOutputData1, pOutputData2, pOutputData3, parseInt(inputSize / 2, 10));
if (res === 1) {
let aOutputData = new Uint8Array(inputSize);
aOutputData.set(AudioModule.HEAPU8.subarray(pOutputData3, pOutputData3 + inputSize)); // 必须取pOutputData3的数据
// postMessage({ type: "outputData", buf: aOutputData}, [aOutputData]);
postMessage({ type: "outputData", dType: 1, buf: aOutputData.buffer}, [aOutputData.buffer]);
}
AudioModule._free(pInputData1);
AudioModule._free(pInputData2);
AudioModule._free(pOutputData1);
AudioModule._free(pOutputData2);
AudioModule._free(pOutputData3);
} else if ("release" === data.type) {
//奇怪,到时和研究院确认一下,库为什么不提供释放资源或者停止的接口??
close();
}
};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
"use strict";var Module={};var initializedJS=false;function threadPrintErr(){var text=Array.prototype.slice.call(arguments).join(" ");console.error(text)}function threadAlert(){var text=Array.prototype.slice.call(arguments).join(" ");postMessage({cmd:"alert",text:text,threadId:Module["_pthread_self"]()})}var err=threadPrintErr;self.alert=threadAlert;Module["instantiateWasm"]=(info,receiveInstance)=>{var module=Module["wasmModule"];Module["wasmModule"]=null;var instance=new WebAssembly.Instance(module,info);return receiveInstance(instance)};self.onunhandledrejection=e=>{throw e.reason??e};function handleMessage(e){try{if(e.data.cmd==="load"){let messageQueue=[];self.onmessage=e=>messageQueue.push(e);self.startWorker=instance=>{Module=instance;postMessage({"cmd":"loaded"});for(let msg of messageQueue){handleMessage(msg)}self.onmessage=handleMessage};Module["wasmModule"]=e.data.wasmModule;for(const handler of e.data.handlers){Module[handler]=(...args)=>{postMessage({cmd:"callHandler",handler:handler,args:args})}}Module["wasmMemory"]=e.data.wasmMemory;Module["buffer"]=Module["wasmMemory"].buffer;Module["ENVIRONMENT_IS_PTHREAD"]=true;if(typeof e.data.urlOrBlob=="string"){importScripts(e.data.urlOrBlob)}else{var objectUrl=URL.createObjectURL(e.data.urlOrBlob);importScripts(objectUrl);URL.revokeObjectURL(objectUrl)}JSPlayerModule(Module)}else if(e.data.cmd==="run"){Module["__emscripten_thread_init"](e.data.pthread_ptr,0,0,1);Module["__emscripten_thread_mailbox_await"](e.data.pthread_ptr);Module["establishStackSpace"]();Module["PThread"].receiveObjectTransfer(e.data);Module["PThread"].threadInitTLS();if(!initializedJS){Module["__embind_initialize_bindings"]();initializedJS=true}try{Module["invokeEntryPoint"](e.data.start_routine,e.data.arg)}catch(ex){if(ex!="unwind"){throw ex}}}else if(e.data.cmd==="cancel"){if(Module["_pthread_self"]()){Module["__emscripten_thread_exit"](-1)}}else if(e.data.target==="setimmediate"){}else if(e.data.cmd==="checkMailbox"){if(initializedJS){Module["checkMailbox"]()}}else if(e.data.cmd){err("worker.js received unknown command "+e.data.cmd);err(e.data)}}catch(ex){if(Module["__emscripten_thread_crashed"]){Module["__emscripten_thread_crashed"]()}throw ex}}self.onmessage=handleMessage;

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
"use strict";var Module={};var initializedJS=false;function threadPrintErr(){var text=Array.prototype.slice.call(arguments).join(" ");console.error(text)}function threadAlert(){var text=Array.prototype.slice.call(arguments).join(" ");postMessage({cmd:"alert",text:text,threadId:Module["_pthread_self"]()})}var err=threadPrintErr;self.alert=threadAlert;Module["instantiateWasm"]=(info,receiveInstance)=>{var module=Module["wasmModule"];Module["wasmModule"]=null;var instance=new WebAssembly.Instance(module,info);return receiveInstance(instance)};self.onunhandledrejection=e=>{throw e.reason??e};function handleMessage(e){try{if(e.data.cmd==="load"){let messageQueue=[];self.onmessage=e=>messageQueue.push(e);self.startWorker=instance=>{Module=instance;postMessage({"cmd":"loaded"});for(let msg of messageQueue){handleMessage(msg)}self.onmessage=handleMessage};Module["wasmModule"]=e.data.wasmModule;for(const handler of e.data.handlers){Module[handler]=(...args)=>{postMessage({cmd:"callHandler",handler:handler,args:args})}}Module["wasmMemory"]=e.data.wasmMemory;Module["buffer"]=Module["wasmMemory"].buffer;Module["ENVIRONMENT_IS_PTHREAD"]=true;if(typeof e.data.urlOrBlob=="string"){importScripts(e.data.urlOrBlob)}else{var objectUrl=URL.createObjectURL(e.data.urlOrBlob);importScripts(objectUrl);URL.revokeObjectURL(objectUrl)}JSPlayerModule(Module)}else if(e.data.cmd==="run"){Module["__emscripten_thread_init"](e.data.pthread_ptr,0,0,1);Module["__emscripten_thread_mailbox_await"](e.data.pthread_ptr);Module["establishStackSpace"]();Module["PThread"].receiveObjectTransfer(e.data);Module["PThread"].threadInitTLS();if(!initializedJS){Module["__embind_initialize_bindings"]();initializedJS=true}try{Module["invokeEntryPoint"](e.data.start_routine,e.data.arg)}catch(ex){if(ex!="unwind"){throw ex}}}else if(e.data.cmd==="cancel"){if(Module["_pthread_self"]()){Module["__emscripten_thread_exit"](-1)}}else if(e.data.target==="setimmediate"){}else if(e.data.cmd==="checkMailbox"){if(initializedJS){Module["checkMailbox"]()}}else if(e.data.cmd){err("worker.js received unknown command "+e.data.cmd);err(e.data)}}catch(ex){if(Module["__emscripten_thread_crashed"]){Module["__emscripten_thread_crashed"]()}throw ex}}self.onmessage=handleMessage;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@@ -0,0 +1 @@
"use strict";var Module={};var ENVIRONMENT_IS_NODE=typeof process=="object"&&typeof process.versions=="object"&&typeof process.versions.node=="string";if(ENVIRONMENT_IS_NODE){var nodeWorkerThreads=require("worker_threads");var parentPort=nodeWorkerThreads.parentPort;parentPort.on("message",data=>onmessage({data:data}));var fs=require("fs");Object.assign(global,{self:global,require:require,Module:Module,location:{href:__filename},Worker:nodeWorkerThreads.Worker,importScripts:f=>(0,eval)(fs.readFileSync(f,"utf8")+"//# sourceURL="+f),postMessage:msg=>parentPort.postMessage(msg),performance:global.performance||{now:Date.now}})}var initializedJS=false;function threadPrintErr(){var text=Array.prototype.slice.call(arguments).join(" ");if(ENVIRONMENT_IS_NODE){fs.writeSync(2,text+"\n");return}console.error(text)}function threadAlert(){var text=Array.prototype.slice.call(arguments).join(" ");postMessage({cmd:"alert",text:text,threadId:Module["_pthread_self"]()})}var err=threadPrintErr;self.alert=threadAlert;Module["instantiateWasm"]=(info,receiveInstance)=>{var module=Module["wasmModule"];Module["wasmModule"]=null;var instance=new WebAssembly.Instance(module,info);return receiveInstance(instance)};self.onunhandledrejection=e=>{throw e.reason??e};function handleMessage(e){try{if(e.data.cmd==="load"){let messageQueue=[];self.onmessage=e=>messageQueue.push(e);self.startWorker=instance=>{Module=instance;postMessage({"cmd":"loaded"});for(let msg of messageQueue){handleMessage(msg)}self.onmessage=handleMessage};Module["wasmModule"]=e.data.wasmModule;for(const handler of e.data.handlers){Module[handler]=(...args)=>{postMessage({cmd:"callHandler",handler:handler,args:args})}}Module["wasmMemory"]=e.data.wasmMemory;Module["buffer"]=Module["wasmMemory"].buffer;Module["ENVIRONMENT_IS_PTHREAD"]=true;if(typeof e.data.urlOrBlob=="string"){importScripts(e.data.urlOrBlob)}else{var objectUrl=URL.createObjectURL(e.data.urlOrBlob);importScripts(objectUrl);URL.revokeObjectURL(objectUrl)}JSAudioInterComModule(Module)}else if(e.data.cmd==="run"){Module["__emscripten_thread_init"](e.data.pthread_ptr,0,0,1);Module["__emscripten_thread_mailbox_await"](e.data.pthread_ptr);Module["establishStackSpace"]();Module["PThread"].receiveObjectTransfer(e.data);Module["PThread"].threadInitTLS();if(!initializedJS){Module["__embind_initialize_bindings"]();initializedJS=true}try{Module["invokeEntryPoint"](e.data.start_routine,e.data.arg)}catch(ex){if(ex!="unwind"){throw ex}}}else if(e.data.cmd==="cancel"){if(Module["_pthread_self"]()){Module["__emscripten_thread_exit"](-1)}}else if(e.data.target==="setimmediate"){}else if(e.data.cmd==="checkMailbox"){if(initializedJS){Module["checkMailbox"]()}}else if(e.data.cmd){err("worker.js received unknown command "+e.data.cmd);err(e.data)}}catch(ex){if(Module["__emscripten_thread_crashed"]){Module["__emscripten_thread_crashed"]()}throw ex}}self.onmessage=handleMessage;

View File

@@ -0,0 +1,881 @@
/* eslint-disable no-cond-assign */
var bindAsEventListener = function (object, fun) {
var args = Array.prototype.slice.call(arguments).slice(2);
return function (event) {
return fun.apply(object, [event || window.event].concat(args));
};
};
/*
Function: bind
Description: 绑定对象到函数
Input: object 对象, fun 函数
Output: 无
return: 关联后的函数
*************************************************/
var bind = function (object, fun) {
return function () {
return fun.apply(object, arguments);
};
};
/*
Function: addEventHandler
Description: 添加事件
Input: oTarget 目标对象, sEventType 事件, fnHandler 函数
Output: 无
return: 无
*************************************************/
var addEventHandler = function (oTarget, sEventType, fnHandler) {
oTarget["on" + sEventType] = fnHandler;
};
var removeEventHandler = function (oTarget, sEventType) {
oTarget["on" + sEventType] = null;
};
/*
Function: getObjLeft
Description: 获取对象相对网页的左上角坐标
Input: obj 对象
Output: 无
return: 坐标
*************************************************/
function getObjLeft(obj) {
var x = obj.offsetLeft;
while (obj = obj.offsetParent) {
x += obj.offsetLeft;
}
return x;
}
/*
Function: getObjTop
Description: 获取对象相对网页的左上角坐标
Input: obj 对象
Output: 无
return: 坐标
*************************************************/
function getObjTop(obj) {
var y = obj.offsetTop;
while (obj = obj.offsetParent) {
y += obj.offsetTop;
}
return y;
}
/*
* Class ScaleInfo
* @version v1.0
* @function 工具类,时间刻度信息
*************************************************/
function ScaleInfo(x, y, iSeconds) {
this.m_ix = x;
this.m_iy = y;
this.m_ixMin = 0;
this.m_ixMax = 0;
this.m_iHour = parseInt(iSeconds / 3600, 10);
this.m_iMinute = parseInt(iSeconds % 3600 / 60, 10);
this.m_iSecond = parseInt(iSeconds % 3600 % 60, 10);
this.m_szTime = "";
if (this.m_iHour < 10 && this.m_iMinute < 10) {
this.m_szTime = "0" + this.m_iHour + ":0" + this.m_iMinute;
} else if (this.m_iHour < 10 && this.m_iMinute >= 10) {
this.m_szTime = "0" + this.m_iHour + ":" + this.m_iMinute;
} else if (this.m_iHour >= 10 && this.m_iMinute >= 10) {
this.m_szTime = "" + this.m_iHour + ":" + this.m_iMinute;
} else {
this.m_szTime = "" + this.m_iHour + ":0" + this.m_iMinute;
}
}
/*
Function: setPos
Description: 设置刻度的位置
Input: x 横坐标, y 纵坐标
Output: 无
return: 无
*************************************************/
ScaleInfo.prototype.setPos = function (x, y) {
// this.x = x;
if (x < this.m_ixMin) {
x = this.m_ixMax - (this.m_ixMin - x);
} else if (x > this.m_ixMax) {
x = this.m_ixMin + (x - this.m_ixMax);
}
this.m_ix = x;
this.m_iy = y;
};
/*
Function: setPosRange
Description: 设置刻度显示的范围
Input: ixMin 最小横坐标, ixMax 最大横坐标
Output: 无
return: 无
*************************************************/
ScaleInfo.prototype.setPosRange = function (ixMin, ixMax) {
this.m_ixMin = ixMin;
this.m_ixMax = ixMax;
};
/*
Function: isInRange
Description: 是否在范围内
Input: ixMin 最小横坐标, ixMax 最大横坐标
Output: 无
return: bool
*************************************************/
ScaleInfo.prototype.isInRange = function (iMin, iMax) {
if (this.m_ix >= iMin && this.m_ix <= iMax) {
return true;
}
return false;
};
/*
Function: update
Description: 更新刻度时间
Input: iSeconds
Output: 无
return: 无
*************************************************/
ScaleInfo.prototype.update = function (iSeconds) {
this.m_iHour = parseInt(iSeconds / 3600, 10);
this.m_iMinute = parseInt(iSeconds % 3600 / 60, 10);
this.m_iSecond = parseInt(iSeconds % 3600 % 60, 10);
if (this.m_iHour < 10 && this.m_iMinute < 10) {
this.m_szTime = "0" + this.m_iHour + ":0" + this.m_iMinute;
} else if (this.m_iHour < 10 && this.m_iMinute >= 10) {
this.m_szTime = "0" + this.m_iHour + ":" + this.m_iMinute;
} else if (this.m_iHour >= 10 && this.m_iMinute >= 10) {
this.m_szTime = "" + this.m_iHour + ":" + this.m_iMinute;
} else {
this.m_szTime = "" + this.m_iHour + ":0" + this.m_iMinute;
}
};
/*
* Class Time
* @version v1.0
* @function 工具类,时间相关信息
*************************************************/
function Time() {
var tCurrentTime = new Date();
this.m_iYear = tCurrentTime.getFullYear();
this.m_iMonth = tCurrentTime.getMonth() + 1;
this.m_iDay = tCurrentTime.getDate();
this.m_iHour = tCurrentTime.getHours();
this.m_iMinute = tCurrentTime.getMinutes();
this.m_iSecond = tCurrentTime.getSeconds();
this.m_iMilliseconds = tCurrentTime.getTime();//返回 1970 年 1 月 1 日至今的毫秒数
}
/*
Function: setTimeByMis
Description: 设置时间
Input: iMilliseconds: 1970 年 1 月 1 日至今的毫秒数
Output: 无
return: 无
*************************************************/
Time.prototype.setTimeByMis = function (iMilliseconds) {
var tSetTime = new Date(iMilliseconds);
this.m_iYear = tSetTime.getFullYear();
this.m_iMonth = tSetTime.getMonth() + 1;
this.m_iDay = tSetTime.getDate();
this.m_iHour = tSetTime.getHours();
this.m_iMinute = tSetTime.getMinutes();
this.m_iSecond = tSetTime.getSeconds();
this.m_iMilliseconds = iMilliseconds;
};
/*
Function: getStringTime
Description: 获取时间字符串
Input: 无
Output: 无
return: string yyyy-MM-dd HH:mm:ss
*************************************************/
Time.prototype.getStringTime = function () {
var szYear = "" + this.m_iYear;
var szMonth;
if (this.m_iMonth < 10) {
szMonth = "0" + this.m_iMonth;
} else {
szMonth = "" + this.m_iMonth;
}
var szDay;
if (this.m_iDay < 10) {
szDay = "0" + this.m_iDay;
} else {
szDay = "" + this.m_iDay;
}
var szHour;
if (this.m_iHour < 10) {
szHour = "0" + this.m_iHour;
} else {
szHour = "" + this.m_iHour;
}
var szMinute;
if (this.m_iMinute < 10) {
szMinute = "0" + this.m_iMinute;
} else {
szMinute = "" + this.m_iMinute;
}
var szSecond;
if (this.m_iSecond < 10) {
szSecond = "0" + this.m_iSecond;
} else {
szSecond = "" + this.m_iSecond;
}
var szCurrentTime = szYear + "-" + szMonth + "-" + szDay + " " + szHour + ":" + szMinute + ":" + szSecond;
return szCurrentTime;
};
/*
Function: parseTime
Description: 通过时间字符串设置时间
Input: szTime 时间 yyyy-MM-dd HH:mm:ss
Output: 无
return: 无
*************************************************/
Time.prototype.parseTime = function (szTime) {
var aDate = szTime.split(' ')[0].split('-');
var aTime = szTime.split(' ')[1].split(':');
this.m_iYear = parseInt(aDate[0], 10);
this.m_iMonth = parseInt(aDate[1], 10);
this.m_iDay = parseInt(aDate[2], 10);
this.m_iHour = parseInt(aTime[0], 10);
this.m_iMinute = parseInt(aTime[1], 10);
this.m_iSecond = parseInt(aTime[2], 10);
var tTime = new Date();
tTime.setFullYear(this.m_iYear);
tTime.setMonth(this.m_iMonth - 1, this.m_iDay);
tTime.setHours(this.m_iHour);
tTime.setMinutes(this.m_iMinute);
tTime.setSeconds(this.m_iSecond);
this.m_iMilliseconds = tTime.getTime();
};
/*
* Class FileInfo
* @version v1.0
* @function 工具类,录像文件相关信息
*************************************************/
function FileInfo(iX, iY, iWidth, iHeight, iType, cColor, tStartTime, tStopTime) {
this.m_iX = iX;
this.m_ixMin = 0;
this.m_ixMax = 0;
this.m_iY = iY;
this.m_iWidth = iWidth;
this.m_iHeight = iHeight;
this.m_cColor = cColor;
this.m_iType = iType;
this.m_tStartTime = tStartTime;
this.m_tStopTime = tStopTime;
}
/*
Function: isInRange
Description: 是否在范围之内
Input: left 左起始点 right 右终点
Output: 无
return: 无
*************************************************/
FileInfo.prototype.isInRange = function (left, right) {
if ((this.m_iX + this.m_iWidth) <= left || this.m_iX >= right) {
return false;
}
return true;
};
/*
Function: setPos
Description: 设置位置内
Input: iX iY左起始点坐标 iWidth 宽度 iHeight高度
Output: 无
return: 无
*************************************************/
FileInfo.prototype.setPos = function (iX, iY, iWidth, iHeight) {
this.m_iX = iX;
this.m_iWidth = iWidth;
this.m_iY = iY;
this.m_iHeight = iHeight;
};
/*
Function: setPosRange
Description: 设置范围
Input: ixMin, ixMax
Output: 无
return: 无
*************************************************/
FileInfo.prototype.setPosRange = function (ixMin, ixMax) {
this.m_ixMin = ixMin;
this.m_ixMax = ixMax;
};
/*
Function: draw
Description: 画文件信息
Input: g 设备资源
Output: 无
return: 无
*************************************************/
FileInfo.prototype.draw = function (g) {
if (this.isInRange(this.m_ixMin, this.m_ixMax)) {
var colorOld = g.fillStyle;
g.fillStyle = this.m_cColor;
if ((this.m_iX >= this.m_ixMin) && (this.m_iX + this.m_iWidth) <= this.m_ixMax) {
g.fillRect(this.m_iX, this.m_iY, this.m_iWidth, this.m_iHeight);
} else if ((this.m_iX < this.m_ixMax) && ((this.m_iX + this.m_iWidth) > this.m_ixMax)) {
g.fillRect(this.m_iX, this.m_iY, this.m_ixMax - this.m_iX, this.m_iHeight);
} else {
g.fillRect(this.m_ixMin, this.m_iY, (this.m_iX + this.m_iWidth) - this.m_ixMin, this.m_iHeight);
}
g.fillStyle = colorOld;
}
};
/*
* Class TimeBar
* @version v1.0
* @function 工具类,时间条
*************************************************/
function TimeBar(canvas, iWidth, iHeight, options) {
canvas.width = iWidth || 300;
canvas.height = iHeight || 50;
this.m_canvas = canvas;
this.m_ctx = canvas.getContext("2d");
this.m_iMinFileWidth = 1; //文件的最小宽度
let backgroundColor = 'rgb(0, 0, 0)'; //时间条背景颜色
let partLineColor = 'rgb(0,0,0)'; //分割线颜色
let timeScaleColor = 'rgb(150, 250, 150)'; //时间条刻度颜色
let middleLineColor = 'rgb(0, 250, 0)'; //中轴线颜色
let middleLineTimeColor = 'rgb(0, 250, 0)'; //中轴时间颜色
if (options) {
if (options.backgroundColor) {
backgroundColor = options.backgroundColor;
}
if (options.partLineColor) {
partLineColor = options.partLineColor;
}
if (options.timeScaleColor) {
timeScaleColor = options.timeScaleColor;
}
if (options.middleLineColor) {
middleLineColor = options.middleLineColor;
}
if (options.middleLineTimeColor) {
middleLineTimeColor = options.middleLineTimeColor;
}
}
this.backgroundColor = backgroundColor; //时间条背景颜色
this.partLineColor = partLineColor; //分割线颜色
this.channelNameColor = 'rgb(150, 150, 150)'; //通道名称颜色
this.timeScaleColor = timeScaleColor; //时间条刻度颜色
this.middleLineColor = middleLineColor; //中轴线颜色
this.middleLineTimeColor = middleLineTimeColor; //中轴时间颜色
this.defaultFileColor = 'rgb(0, 255, 0)'; //默认录像类型颜色
this.cmdFileColor = 'rgb(21, 184, 155)'; //命令触发录像颜色
this.scheFileColor = 'rgb(33, 150, 243)'; //录像计划颜色
this.alarmFileColor = 'rgb(255, 104, 66)'; //警告录像颜色
this.manualFileColor = 'rgb(247, 199, 5)'; //手动录像颜色
this.anrFileColor = 'rgb(138, 146, 153)'; //回传录像颜色
this.m_fMidTimeFont = '14px Verdana'; //中线时间字体及大小
this.m_fCurTimeFont = 'bold 12px Arial'; //鼠标当前时间字体及大小
this.m_fScaleFont = 'bold 10px Arial'; //刻度字体及大小 sans-serif
this.m_fChannelNameFont = '14px Verdana'; //通道名称字体
canvas.style.backgroundColor = this.backgroundColor;
this.m_szCurChannelName = ''; //当前通道名称
this.m_fCellTime = parseFloat(2.0); //每个代表几个小时
this.ScaleInfo = [];
this.ScaleInfoNum = parseInt(24 / this.m_fCellTime, 10); //总的刻度数量
this.ScaleInfoDisNum = 12; //显示的刻度数量
//初始化刻度
for (var i = 0; i < this.ScaleInfoNum; i++) {
this.ScaleInfo.push(new ScaleInfo(0, 0, parseInt(i * 3600 * this.m_fCellTime, 10)));
}
this.m_iMaxWndNum = 16; //最大窗口数
this.m_iSelWnd = 0; //选中的窗口号
this.FileInfoSet = new Array(this.m_iMaxWndNum); //文件信息集合
//初始化文件信息集合
for (i = 0; i < this.m_iMaxWndNum; i++) {
this.FileInfoSet[i] = [];
}
this.m_iHeight = parseInt(canvas.height, 10);
this.m_iWidth = parseInt(canvas.width, 10);
this.m_iFileListStartPos = 0; // 文件列表起始位置
this.m_iBlankHeight = 4; // 中间及底边空白高度
this.m_iTimeRectHeight = 30; //parseInt(this.m_iHeight * 4 / 7) 时间块的高度
this.m_iFileRectHeight = this.m_iHeight - this.m_iTimeRectHeight - this.m_iBlankHeight; //文件块的高度
this.m_iMiddleLinePos = parseInt((this.m_iFileListStartPos + this.m_iWidth) / 2, 10); //中轴线的位置
this.m_iCellWidth = Math.floor((this.m_iWidth - this.m_iFileListStartPos) / this.ScaleInfoDisNum); //每个像素的秒数
this.m_iCellMilliseconds = parseInt((3600 * this.m_fCellTime * 1000) / this.m_iCellWidth, 10); //每个像素的毫秒数
this.m_tCurrentMidTime = new Time(); //当前中轴线的时间
this.m_ctx.font = this.m_fMidTimeFont;
this.m_iTextWidth = this.m_ctx.measureText(this.m_tCurrentMidTime.getStringTime()).width;
this.m_tMouseCurTime = new Time(); //当前鼠标点的时间
this.m_ctx.font = this.m_fCurTimeFont;
this.m_iCurTextWidth = this.m_ctx.measureText(this.m_tMouseCurTime.getStringTime()).width;
this.m_iCanvasLeft = getObjLeft(this.m_canvas);
this.m_iCanvasTop = getObjTop(this.m_canvas);
//初始化时间刻度信息
for (i = 0; i < this.ScaleInfoNum; i++) {
// 计算与中轴线的时间差(只计算时分秒)
var seconds = (this.ScaleInfo[i].m_iHour - this.m_tCurrentMidTime.m_iHour) * 3600 + (this.ScaleInfo[i].m_iMinute - this.m_tCurrentMidTime.m_iMinute) * 60 + (this.ScaleInfo[i].m_iSecond - this.m_tCurrentMidTime.m_iSecond);
var iScalePos = this.m_iMiddleLinePos + parseInt(parseFloat(seconds / (3600 * this.m_fCellTime)) * this.m_iCellWidth, 10);
// 设置刻度位置范围
this.ScaleInfo[i].setPosRange(this.m_iFileListStartPos, this.m_iFileListStartPos + parseInt(this.m_iCellWidth * this.ScaleInfoNum, 10));
this.ScaleInfo[i].setPos(iScalePos, this.m_iTimeRectHeight);
}
//注册消息响应
this.m_ieventX = 0;
this.m_iMousePosX = 0;
this.m_bMouseDown = false;
this.m_bMouseOver = false;
this.m_iMove = 0;
this.m_iMiddleLineTime = 0;
this.Start = function (oEvent) {
this.m_iMove = 0;
this.m_ieventX = oEvent.clientX;
this.m_iMiddleLineTime = this.m_tCurrentMidTime.m_iMilliseconds;
this.m_bMouseDown = true;
this.mouseDownCallbackFunc();
addEventHandler(document, 'mousemove', bindAsEventListener(this, this.Move));
addEventHandler(document, 'mouseup', bind(this, this.Stop));
addEventHandler(parent.document, 'mouseup', bind(this, this.Stop)); //解决鼠标在父页面释放时不能响应的问题
//焦点丢失
addEventHandler(window, "blur", bindAsEventListener(this, bindAsEventListener(this, this.Stop)));
//阻止默认动作
oEvent.preventDefault();
removeEventHandler(canvas, 'mousemove', bindAsEventListener(this, this.onMouseMove));
};
this.mouseDownCallbackFunc = function () {
//
};
this.mouseUpCallbackFunc = function () {
//
};
this.mouseMoveCallbackFunc = function () {
//
};
this.Stop = function () {
this.m_bMouseDown = false;
if (this.m_iMove === 0) {
this.m_tCurrentMidTime.setTimeByMis(this.m_tMouseCurTime.m_iMilliseconds);
}
this.mouseUpCallbackFunc();
removeEventHandler(document, 'mousemove', bindAsEventListener(this, this.Move));
removeEventHandler(document, 'mouseup', bindAsEventListener(this, this.Stop));
removeEventHandler(window, "blur", bindAsEventListener(this, this.Stop));
addEventHandler(canvas, 'mousemove', bindAsEventListener(this, this.onMouseMove));
};
this.onMouseMoveIn = true;
this.Move = function (oEvent) {
this.m_iMove = oEvent.clientX - this.m_ieventX;
if (this.m_bMouseDown) {
//清除选择
window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
this.m_tCurrentMidTime.setTimeByMis(this.m_iMiddleLineTime - this.m_iMove * this.m_iCellMilliseconds);
this.repaint();
this.mouseMoveCallbackFunc();
}
};
this.onMouseMove = function (oEvent) {
this.m_iMousePosX = oEvent.clientX - this.m_iCanvasLeft;
this.m_tMouseCurTime.setTimeByMis((this.m_iMousePosX - this.m_iMiddleLinePos) * this.m_iCellMilliseconds + this.m_tCurrentMidTime.m_iMilliseconds);
this.repaint();
var szCurMouseTime = this.m_tMouseCurTime.getStringTime();
this.m_ctx.fillStyle = this.middleLineTimeColor;
this.m_ctx.font = this.m_fCurTimeFont;
this.m_ctx.fillText(szCurMouseTime.split(' ')[1], this.m_iMousePosX/*(this.m_iMousePosX - parseInt(this.m_iCurTextWidth / 2))*/, 20/*parseInt(this.m_iTimeRectHeight / 4)*/);
};
this.onMouseOut = function (/*oEvent*/) {
this.repaint();
};
addEventHandler(canvas, 'mousedown', bindAsEventListener(this, this.Start));
addEventHandler(canvas, 'mousemove', bindAsEventListener(this, this.onMouseMove));
addEventHandler(canvas, 'mouseout', bindAsEventListener(this, this.onMouseOut));
this.repaint();
}
/*
Function: repaint
Description: 重绘
Input: 无
Output: 无
return: 无
*************************************************/
TimeBar.prototype.repaint = function () {
// var szCurrentTime = this.m_tCurrentMidTime.getStringTime();
this.updateScalePos();
this.updateFileListPos();
this.m_ctx.clearRect(0, 0, this.m_iWidth, this.m_iHeight);
//画通道名称分割线
this.m_ctx.strokeStyle = this.partLineColor;
this.m_ctx.lineWidth = 1;
this.m_ctx.beginPath();
this.m_ctx.moveTo(this.m_iFileListStartPos, this.m_iTimeRectHeight);
this.m_ctx.lineTo(this.m_iFileListStartPos, this.m_iHeight);
this.m_ctx.stroke();
//画文件两条横轴和纵轴
this.m_ctx.lineWidth = this.m_iBlankHeight;
this.m_ctx.beginPath();
this.m_ctx.moveTo(0, this.m_iTimeRectHeight);
this.m_ctx.lineTo(this.m_iWidth, this.m_iTimeRectHeight);
this.m_ctx.stroke();
this.m_ctx.beginPath();
this.m_ctx.moveTo(0, this.m_iHeight - this.m_iBlankHeight / 2);
this.m_ctx.lineTo(this.m_iWidth, this.m_iHeight - this.m_iBlankHeight / 2);
this.m_ctx.stroke();
//显示通道名称
this.m_ctx.fillStyle = this.channelNameColor;
this.m_ctx.font = this.m_fChannelNameFont;
this.m_ctx.fillText(this.m_szCurChannelName, 0, this.m_iTimeRectHeight + this.m_iBlankHeight + parseInt(this.m_iFileRectHeight / 2, 10) + 5, 90);
this.m_ctx.strokeStyle = this.timeScaleColor;
this.m_ctx.font = this.m_fScaleFont;
this.m_ctx.lineWidth = 1;
//画时间刻度
var i;
for (i = 0; i < this.ScaleInfoNum; i++) {
if (this.ScaleInfo[i].isInRange(this.m_iFileListStartPos, this.m_iWidth)) {
this.m_ctx.beginPath();
this.m_ctx.moveTo(this.ScaleInfo[i].m_ix, 2/*this.m_iTimeRectHeight*/);
this.m_ctx.lineTo(this.ScaleInfo[i].m_ix, 10/*this.m_iHeight*/);
this.m_ctx.stroke();
this.m_ctx.fillText(this.ScaleInfo[i].m_szTime, this.ScaleInfo[i].m_ix + 2/*this.ScaleInfo[i].m_ix - 15*/, 12/*this.m_iTimeRectHeight - 5*/);
}
}
//画文件信息区域
for (i = 0; i < this.FileInfoSet[this.m_iSelWnd].length; i++) {
this.FileInfoSet[this.m_iSelWnd][i].draw(this.m_ctx);
}
//画中轴线
this.m_ctx.strokeStyle = this.middleLineColor;
this.m_ctx.lineWidth = 2;
this.m_ctx.beginPath();
this.m_ctx.moveTo(this.m_iMiddleLinePos, 0);
this.m_ctx.lineTo(this.m_iMiddleLinePos, this.m_iHeight);
this.m_ctx.stroke();
};
/*
Function: updateScalePos
Description: 更新刻度
Input: 无
Output: 无
return: 无
*************************************************/
TimeBar.prototype.updateScalePos = function () {
if (this.ScaleInfo.length === 0) {
return;
}
// 以00:00移动的距离为准
var seconds = (this.ScaleInfo[0].m_iHour - this.m_tCurrentMidTime.m_iHour) * 3600 + (this.ScaleInfo[0].m_iMinute - this.m_tCurrentMidTime.m_iMinute) * 60 + (this.ScaleInfo[0].m_iSecond - this.m_tCurrentMidTime.m_iSecond);
var iPos0 = this.m_iMiddleLinePos + parseInt(parseFloat(seconds / (3600 * this.m_fCellTime)) * this.m_iCellWidth, 10);
if (iPos0 < this.ScaleInfo[0].m_ixMin) {
iPos0 = this.ScaleInfo[0].m_ixMax - (this.ScaleInfo[0].m_ixMin - iPos0);
} else if (iPos0 > this.ScaleInfo[0].m_ixMax) {
iPos0 = this.ScaleInfo[0].m_ixMin + (iPos0 - this.ScaleInfo[0].m_ixMax);
}
var iMoved = iPos0 - this.ScaleInfo[0].m_ix;
//没有移动直接返回
if (iMoved === 0) {
return;
}
// 更新所有的刻度
for (var i = 0; i < this.ScaleInfoNum; i++) {
var iScalePos = this.ScaleInfo[i].m_ix + iMoved;
// 设置刻度位置范围
this.ScaleInfo[i].setPosRange(this.m_iFileListStartPos, this.m_iFileListStartPos + parseInt(this.m_iCellWidth * this.ScaleInfoNum, 10));
this.ScaleInfo[i].setPos(iScalePos, this.m_iTimeRectHeight);
}
};
/*
Function: updateFileListPos
Description: 更新文件
Input: 无
Output: 无
return: 无
*************************************************/
TimeBar.prototype.updateFileListPos = function () {
var iFileLength = this.FileInfoSet[this.m_iSelWnd].length;
if (iFileLength === 0) {
return;
}
var tStartTime = this.FileInfoSet[this.m_iSelWnd][0].m_tStartTime;
var seconds = parseInt((tStartTime.m_iMilliseconds - this.m_tCurrentMidTime.m_iMilliseconds) / 1000, 10);
var iFile0Pos = this.m_iMiddleLinePos + parseInt(parseFloat(seconds / (3600 * this.m_fCellTime)) * this.m_iCellWidth, 10);
var iMoved = iFile0Pos - this.FileInfoSet[this.m_iSelWnd][0].m_iX;
//没有移动直接返回
if (iMoved === 0) {
return;
}
// 更新所有
for (var i = 0; i < iFileLength; i++) {
var iX = this.FileInfoSet[this.m_iSelWnd][i].m_iX + iMoved;
var iY = this.FileInfoSet[this.m_iSelWnd][i].m_iY;
var iWidth = this.FileInfoSet[this.m_iSelWnd][i].m_iWidth;
var iHeight = this.FileInfoSet[this.m_iSelWnd][i].m_iHeight;
this.FileInfoSet[this.m_iSelWnd][i].setPos(iX, iY, iWidth, iHeight);
}
};
/*
Function: resize
Description: 重置大小
Input: iWidth宽度, iHeight高度
Output: 无
return: 无
*************************************************/
TimeBar.prototype.resize = function (iWidth, iHeight) {
this.m_canvas.height = iHeight;
this.m_canvas.width = iWidth;
this.m_iHeight = iHeight;
this.m_iWidth = iWidth;
this.m_iTimeRectHeight = parseInt(this.m_iHeight * 4 / 7, 10);
this.m_iFileRectHeight = this.m_iHeight - this.m_iTimeRectHeight - this.m_iBlankHeight;
this.m_iMiddleLinePos = parseInt((this.m_iFileListStartPos + this.m_iWidth) / 2, 10);
this.m_iCellWidth = Math.floor((this.m_iWidth - this.m_iFileListStartPos) / this.ScaleInfoDisNum);
this.m_iCellMilliseconds = parseInt((3600 * this.m_fCellTime * 1000) / this.m_iCellWidth, 10);
//初始化时间刻度信息
var i;
for (i = 0; i < this.ScaleInfoNum; i++) {
// 计算与中轴线的时间差(只计算时分秒)
var seconds = (this.ScaleInfo[i].m_iHour - this.m_tCurrentMidTime.m_iHour) * 3600 + (this.ScaleInfo[i].m_iMinute - this.m_tCurrentMidTime.m_iMinute) * 60 + (this.ScaleInfo[i].m_iSecond - this.m_tCurrentMidTime.m_iSecond);
var iScalePos = this.m_iMiddleLinePos + parseInt(parseFloat(seconds / (3600 * this.m_fCellTime)) * this.m_iCellWidth, 10);
// 设置刻度位置范围
this.ScaleInfo[i].setPosRange(this.m_iFileListStartPos, this.m_iFileListStartPos + parseInt(this.m_iCellWidth * this.ScaleInfoNum, 10));
this.ScaleInfo[i].setPos(iScalePos, this.m_iTimeRectHeight);
}
//初始化文件列表信息
for (i = 0; i < this.FileInfoSet[this.m_iSelWnd].length; i++) {
var FileInfoSetSel = this.FileInfoSet[this.m_iSelWnd][i];
var iXLeftSeconds = parseInt((FileInfoSetSel.m_tStartTime.m_iMilliseconds - this.m_tCurrentMidTime.m_iMilliseconds) / 1000, 10);
var iFilePosLeft = this.m_iMiddleLinePos + parseInt(parseFloat(iXLeftSeconds / (3600 * this.m_fCellTime)) * this.m_iCellWidth, 10);
var iXRightSeconds = parseInt((FileInfoSetSel.m_tStopTime.m_iMilliseconds - this.m_tCurrentMidTime.m_iMilliseconds) / 1000, 10);
var iFilePosRight = this.m_iMiddleLinePos + parseInt(parseFloat(iXRightSeconds / (3600 * this.m_fCellTime)) * this.m_iCellWidth, 10);
if ((iFilePosRight - iFilePosLeft) < this.m_iMinFileWidth) {
iFilePosRight = iFilePosLeft + this.m_iMinFileWidth;
}
FileInfoSetSel.setPos(iFilePosLeft, this.m_iTimeRectHeight + parseInt(this.m_iBlankHeight / 2, 10), iFilePosRight - iFilePosLeft, this.m_iFileRectHeight + 2);
}
this.repaint();
};
/*
Function: setSpanType
Description: 设置时间条的显示样式
Input: 无
Output: 无
return: 无
*************************************************/
TimeBar.prototype.setSpanType = function (iSpanType) {
switch (iSpanType) {
case 6://每2小时一格
this.ScaleInfoDisNum = 12;
this.m_fCellTime = parseFloat(2.0);
break;
case 7://每小时一格
this.ScaleInfoDisNum = 12;
this.m_fCellTime = parseFloat(1.0);
break;
case 8://每半小时一格
this.ScaleInfoDisNum = 12;
this.m_fCellTime = parseFloat(0.5);
break;
case 9://每10分钟一格
this.ScaleInfoDisNum = 12;
this.m_fCellTime = parseFloat(1 / 6);
break;
case 10://每5分钟一格
this.ScaleInfoDisNum = 12;
this.m_fCellTime = parseFloat(1 / 12);
break;
case 11://每1分钟一格
this.ScaleInfoDisNum = 12;
this.m_fCellTime = parseFloat(1 / 60);
break;
default:
this.ScaleInfoDisNum = 12;
this.m_fCellTime = parseFloat(2.0);
return;
}
this.ScaleInfoNum = parseInt(24 / this.m_fCellTime, 10);
this.m_iCellWidth = Math.floor((this.m_iWidth - this.m_iFileListStartPos) / this.ScaleInfoDisNum);
this.m_iCellMilliseconds = parseInt((3600 * this.m_fCellTime * 1000) / this.m_iCellWidth, 10);
//初始化刻度
this.ScaleInfo.length = 0;
for (var i = 0; i < this.ScaleInfoNum; i++) {
this.ScaleInfo.push(new ScaleInfo(0, 0, parseInt(i * 3600 * this.m_fCellTime, 10)));
}
//初始化时间刻度信息
for (i = 0; i < this.ScaleInfoNum; i++) {
// 计算与中轴线的时间差(只计算时分秒)
var seconds = (this.ScaleInfo[i].m_iHour - this.m_tCurrentMidTime.m_iHour) * 3600 + (this.ScaleInfo[i].m_iMinute - this.m_tCurrentMidTime.m_iMinute) * 60 + (this.ScaleInfo[i].m_iSecond - this.m_tCurrentMidTime.m_iSecond);
var iScalePos = this.m_iMiddleLinePos + parseInt(parseFloat(seconds / (3600 * this.m_fCellTime)) * this.m_iCellWidth, 10);
// 设置刻度位置范围
this.ScaleInfo[i].setPosRange(this.m_iFileListStartPos, this.m_iFileListStartPos + parseInt(this.m_iCellWidth * this.ScaleInfoNum, 10));
this.ScaleInfo[i].setPos(iScalePos, this.m_iTimeRectHeight);
}
//初始化文件列表信息
for (i = 0; i < this.FileInfoSet[this.m_iSelWnd].length; i++) {
var FileInfoSetSel = this.FileInfoSet[this.m_iSelWnd][i];
var iXLeftSeconds = parseInt((FileInfoSetSel.m_tStartTime.m_iMilliseconds - this.m_tCurrentMidTime.m_iMilliseconds) / 1000, 10);
var iFilePosLeft = this.m_iMiddleLinePos + parseInt(parseFloat(iXLeftSeconds / (3600 * this.m_fCellTime)) * this.m_iCellWidth, 10);
var iXRightSeconds = parseInt((FileInfoSetSel.m_tStopTime.m_iMilliseconds - this.m_tCurrentMidTime.m_iMilliseconds) / 1000, 10);
var iFilePosRight = this.m_iMiddleLinePos + parseInt(parseFloat(iXRightSeconds / (3600 * this.m_fCellTime)) * this.m_iCellWidth, 10);
if ((iFilePosRight - iFilePosLeft) < this.m_iMinFileWidth) {
iFilePosRight = iFilePosLeft + this.m_iMinFileWidth;
}
FileInfoSetSel.setPos(iFilePosLeft, this.m_iTimeRectHeight + parseInt(this.m_iBlankHeight / 2, 10), iFilePosRight - iFilePosLeft, this.m_iFileRectHeight + 2);
}
this.repaint();
};
/*
Function: addFile
Description: 添加文件
Input: StartTime 开始时间, StopTime 结束时间, iType 类型, iWndNum 默认当前窗口 添加到某个窗口
Output: 无
return: 无
*************************************************/
TimeBar.prototype.addFile = function (StartTime, StopTime, iType/*, iWndNum*/) {
var tStartTime = new Time();
var tStopTime = new Time();
tStartTime.parseTime(StartTime);
tStopTime.parseTime(StopTime);
var fileColor;
switch (iType) {
case 1:
fileColor = this.scheFileColor;
break;
case 2:
fileColor = this.alarmFileColor;
break;
case 3:
fileColor = this.cmdFileColor;
break;
case 4:
fileColor = this.manualFileColor;
break;
case 5:
fileColor = this.anrFileColor;
break;
default:
fileColor = this.defaultFileColor;
break;
}
var iXLeftSeconds = parseInt((tStartTime.m_iMilliseconds - this.m_tCurrentMidTime.m_iMilliseconds) / 1000, 10);
var iFilePosLeft = this.m_iMiddleLinePos + parseInt(parseFloat(iXLeftSeconds / (3600 * this.m_fCellTime)) * this.m_iCellWidth, 10);
var iXRightSeconds = parseInt((tStopTime.m_iMilliseconds - this.m_tCurrentMidTime.m_iMilliseconds) / 1000, 10);
var iFilePosRight = this.m_iMiddleLinePos + parseInt(parseFloat(iXRightSeconds / (3600 * this.m_fCellTime)) * this.m_iCellWidth, 10);
var fileInfo = new FileInfo(iFilePosLeft, this.m_iTimeRectHeight + parseInt(this.m_iBlankHeight / 2, 10), iFilePosRight - iFilePosLeft, this.m_iFileRectHeight + 2, iType, fileColor, tStartTime, tStopTime);
fileInfo.setPosRange(this.m_iFileListStartPos, this.m_iFileListStartPos + parseInt(this.m_iCellWidth * this.ScaleInfoNum, 10));
if (arguments.length >= 4) {
this.FileInfoSet[arguments[3]].push(fileInfo);
} else {
this.FileInfoSet[this.m_iSelWnd].push(fileInfo);
}
};
/*
Function: clearWndFileList
Description: 清空某个窗口的文件信息
Input: iWndNum 窗口号 0-15 默认当前选中窗口
Output: 无
return: 无
*************************************************/
TimeBar.prototype.clearWndFileList = function ()/*iWndNum*/ {
var iWndParam;
if (arguments.length === 0) {
iWndParam = this.m_iSelWnd;
} else {
iWndParam = arguments[0];
}
if (iWndParam < 0) {
iWndParam = 0;
}
if (iWndParam >= 16) {
iWndParam = 15;
}
this.FileInfoSet[iWndParam].length = 0;
};
/*
Function: setMidLineTime
Description: 设置中轴线时间
Input: szTime yyyy-MM-dd HH:mm:ss
Output: 无
return: 无
*************************************************/
TimeBar.prototype.setMidLineTime = function (szTime) {
var tCurTime = new Time();
tCurTime.parseTime(szTime);
this.m_tCurrentMidTime.setTimeByMis(tCurTime.m_iMilliseconds);
this.repaint();
};
TimeBar.prototype.setMouseDownCallback = function (callbackFunc) {
this.mouseDownCallbackFunc = callbackFunc;
};
/*
Function: setMouseUpCallback
Description: 设置鼠标弹起回调函数
Input: func 回调函数 function(tStartTime, tStopTime)
Output: 无
return: 无
*************************************************/
TimeBar.prototype.setMouseUpCallback = function (callbackFunc) {
this.mouseUpCallbackFunc = callbackFunc;
};
TimeBar.prototype.setMouseMoveCallback = function (callbackFunc) {
this.mouseMoveCallbackFunc = callbackFunc;
};

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,240 @@
importScripts('libSystemTransform.js');
const RECORDRTP = 0; //录制一份未经过转封装的码流原始数据,用于定位问题
let dataType = 1;
// 字母字符串转byte数组
function stringToBytes (str) {
var ch;
var st;
var re = [];
for (var i = 0; i < str.length; i++) {
ch = str.charCodeAt(i); // get char
st = []; // set up "stack"
do {
st.push(ch & 0xFF); // push byte to stack
ch = ch >> 8; // shift value down by 1 byte
}
while (ch);
// add stack contents to result
// done because chars have "wrong" endianness
re = re.concat(st.reverse());
}
// return an array of bytes
return re;
}
// 转封装库回调函数
self.STCallBack = function (fileIndex, indexLen, data, dataLen) {
//stFrameInfo的类型见DETAIL_FRAME_INFO
let stFrameInfo = Module._GetDetialFrameInfo();
let nIsMp4Index = stFrameInfo.nIsMp4Index;
//console.log("FrameType is " , stFrameInfo);
//console.log("nIsMp4Index is " + nIsMp4Index);
//debugger
var pData = null;
pData = new Uint8Array(dataLen);
pData.set(Module.HEAPU8.subarray(data, data + dataLen));
if (dataType === 1) {
postMessage({ type: "outputData",
buf: pData.buffer,
dType: 1,
frameInfo: stFrameInfo }, [pData.buffer]);
dataType = 2;
} else {
if (nIsMp4Index) {
postMessage({ type: "outputData",
buf: pData.buffer,
dType: 6,
frameInfo: stFrameInfo }, [pData.buffer]); //6索引类型
} else {
postMessage({ type: "outputData",
buf: pData.buffer,
dType: 2,
frameInfo: stFrameInfo }, [pData.buffer]); //2:码流
}
}
//stFrameInfo的类型见DETAIL_FRAME_INFO
//let stFrameInfo = Module._GetDetialFrameInfo();
//let stFrameType = stFrameInfo.nFrameType;
//let nFrameNum = stFrameInfo.nFrameNum;
//let nTimeStamp = stFrameInfo.nTimeStamp;
//let nIsMp4Index = stFrameInfo.nIsMp4Index;
//console.log("FrameType is " + stFrameType);
//console.log("nIsMp4Index is " + nIsMp4Index);
};
// self.Module = { memoryInitializerRequest: loadMemInitFile(), TOTAL_MEMORY: 128*1024*1024 };
// importScripts('SystemTransform.js');
self.Module['onRuntimeInitialized'] = function () {
postMessage({type: "loaded"});
};
onmessage = function (e) {
var data = e.data;
if ("create" === data.type) {
if (RECORDRTP) {
postMessage({ type: "created" });
postMessage({ type: "outputData",
buf: data.buf,
dType: 1 }, [data.buf]);
} else {
var iHeadLen = data.len;
var pHead = Module._malloc(iHeadLen);
if (pHead === null) {
console.log("inputdata malloc failed!!!");
return -1;
}
var iTransType = data.packType;//目标格式
var iRet = 0;
var buf = new Uint8Array(data.buf);
//PS流(只有ps支持探测)并且编码格式异常正常是265和26411位和10位 不可能全是0全0 并且是ps就探测策略的情况下使用探测策略
if (buf[9] === 0 && buf[8] === 2 && buf[11] === 0 && buf[10] === 0) {
iRet = Module._CreatHandle(0, iTransType, iHeadLen); //用探测的策略
} else {
self.writeArrayToMemory(buf, pHead);
iRet = Module._CreatHandle(pHead, iTransType, iHeadLen);
//-2147483645代表的是参数错误此种情况大概率发生在头信息错误例如大华设备的情况此时用 无头探测的策略
//其他情况 按海康标准处理流程,不要做任何特殊处理
if (iRet == -2147483645) {
iRet = Module._CreatHandle(0, iTransType, iHeadLen); //失败了,用探测的策略再试一次
}
}
if (iRet != 0) {
if (iRet == -2147483647) {
postMessage({ type: "outputData",
dType: 1501 }); //标记为格式不支持
} else {
postMessage({ type: "outputData",
dType: 1501 }); //转封装创建失败,也同样提示码流格式不支持,如果后续要细化再区分
}
console.log("_CreatHandle failed!" + iRet);
} else {
if (data.options && typeof data.options.pKeyData !== "undefined" && data.options.pKeyData !== null) {
if ((2 === iTransType && "" === data.options.pKeyData)) {
//转ps的时候如果密码是空是允许的即使码流加密了导出加密后的码流就行
//此时不要设置密码否则反而会提示密码错误
} else {
var secretInfo = data.options;
var keyLen = secretInfo.nKeyLen;
var pKeyData = Module._malloc(keyLen);
if (pKeyData === null) {
console.log("setEncryptKey malloc failed!!!");
return -1;
}
var nKeySize = secretInfo.pKeyData.length;
var bufData = stringToBytes(secretInfo.pKeyData);
let inputData = new Uint8Array(bufData);
Module.writeArrayToMemory(inputData, pKeyData);
inputData = null;
iRet = Module._SysTransSetEncryptKey(secretInfo.nKeyType, pKeyData, keyLen, nKeySize);
if (iRet != 0) {
console.log("_SysTransSetEncryptKey failed!");
}
if (pKeyData != null) {
Module._free(pKeyData);
pKeyData = null;
}
}
}
//带samplingParam参数代表需要 用到 音频替换功能
if (data.options && typeof data.options.samplingParam !== "undefined") {
var oParam = data.options.samplingParam;
var nCapacityType = 1; //写死1 代表 剔除音频
var nType = 3; //写死3 代表 修改输出目标的海康头配置,内部包含视频参数、音频参数
var nAudioEnable = 1; //音频参数修改使能开关0=不启用1=启用
var nAudioFormat = oParam.iAudioType; //音频编码类型 对应关系参考海康媒体头规范PCM 0x7001 G711_U 0x7110 G711_A 0x7111 AAC 0x2001
var nAudioChannels = oParam.iChannel; //音频通道数直接设置为
var nAudioBitsPerSample = oParam.iAudioBitWidth; //音频位样率
var nAudioSamplesrate = oParam.iAudioSamplingRate; //音频采样率
var nAudioBitrate = oParam.iAudioBitRate; //音频比特率
iRet = Module._SysTransConfig(nCapacityType, nType, nAudioEnable, nAudioFormat,
nAudioChannels, nAudioBitsPerSample, nAudioSamplesrate, nAudioBitrate);
if (iRet != 0) {
console.log("_SysTransConfig Failed:" + iRet);
}
} else {
iRet = Module._SysTransConfig(128, 0, 0, 0, 0, 0, 0, 0); //nCapacityType = 0x00000080 代表开启私有信息回调 解决转mp4后私有信息丢失问题
if (iRet != 0) {
console.log("_SysTransConfig Failed:" + iRet);
}
}
iRet = Module._SysTransRegisterDataCallBack();
if (iRet != 0) {
console.log("_SysTransRegisterDataCallBack Failed:" + iRet);
}
iRet = Module._SysTransStart(null, null);
if (iRet != 0) {
console.log("_SysTransStart Failed:" + iRet);
}
postMessage({type: "created"});
}
if (pHead != null) {
Module._free(pHead);
pHead = null;
}
}
} else if ("inputData" === data.type) {
if (RECORDRTP) {
var aFileData = new Uint8Array(data.buf); // 拷贝一份
var iBufferLen = aFileData.length;
var szBufferLen = iBufferLen.toString(16);
if (szBufferLen.length === 1) {
szBufferLen = "000" + szBufferLen;
} else if (szBufferLen.length === 2) {
szBufferLen = "00" + szBufferLen;
} else if (szBufferLen.length === 3) {
szBufferLen = "0" + szBufferLen;
}
var aData = [0, 0, parseInt(szBufferLen.substring(0, 2), 16), parseInt(szBufferLen.substring(2, 4), 16)];
for (var iIndex = 0, iDataLength = aFileData.length; iIndex < iDataLength; iIndex++) {
aData[iIndex + 4] = aFileData[iIndex];
}
var dataUint8 = new Uint8Array(aData);
postMessage({type: "outputData",
buf: dataUint8.buffer,
dType: 2});
} else {
let inputMode = 0; //代表输入原始数据
if (data.samplingParam) {
iRet = Module._SysTransInputAudioPara(5, data.samplingParam.iChannel, data.samplingParam.iAudioBitWidth,
data.samplingParam.iAudioSamplingRate, data.samplingParam.iTimeStamp, data.samplingParam.iAudioBitRate); //参数含义和_SysTransConfig类似
if (iRet != 0) {
console.log("_SysTransInputAudioPara Failed:" + iRet);
}
inputMode = 2; //输入替换的音频
}
var pInputDataBuf = Module._malloc(data.len);
var idataLen = data.len;
self.writeArrayToMemory(new Uint8Array(data.buf), pInputDataBuf);
// 输入数据每次最多2m
let pp = Module._SysTransInputData(inputMode, pInputDataBuf, idataLen);
if (pp == -2147483627) {
//-2147483627 对应十六进制的80000015
postMessage({ type: "outputData",
dType: 1500 }); //标记为密码错误
} else if (pp == -2147483647) {
postMessage({ type: "outputData",
dType: 1501 }); //标记为格式不支持
} else if (pp != 0) {
console.log("InputData Failed:" + pp);
}
Module._free(pInputDataBuf);
}
} else if ("release" === data.type) {
var iRet = Module._SysTransStop();
if (iRet != 0) {
console.log("_SysTransStop failed!");
}
Module._SysTransRelease();
if (iRet != 0) {
console.log("_SysTransRelease failed!");
}
close();
}
};