智慧工地前端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1244 lines
41 KiB

let SDKModule;
const VIDEO_FRAME_SUB_TYPE_I = 0; //I帧
const VIDEO_FRAME_SUB_TYPE_P = 1; //P帧
const VIDEO_FRAME_SUB_TYPE_B = 2; //B帧
const VIDEO_FRAME_SUB_TYPE_SMART_I = 18; //智能I帧
const VIDEO_FRAME_SUB_TYPE_SMART_P = 19; //智能P帧
const VIDEO_FRAME_SUB_TYPE_SMART_I_NORENDER = 20; //智能I帧,但不显示
const ENCODE_TYPE_VIDEO_HI_H264 = 2; //海思H.264编码格式
const ENCODE_TYPE_VIDEO_MY_H264 = 4; //公司H.264编码格式
const ENCODE_TYPE_VIDEO_STD_H264 = 8; //标准H.264编码格式
const ENCODE_TYPE_VIDEO_H265 = 12; //H.265编码格式
const DATA_RECORD_MP4 = 5; //录制MP4格式
const SP_STREAM_TYPE_DHSTD = 8; //dav编码格式
const STREAM_TYPE_SVC = 13; //H.264 SVC编码格式
const SP_STREAM_TYPE_FLV = 18; //flv编码格式
const ENCRYPT_UNKOWN = 0; //未知加密类型
const ENCRYPT_AES = 1; //AES加密类型,16进制数组格式
const ENCRYPT_AES256 = 2; //AES256加密类型,16进制数组格式
const ENCRYPT_AES_STRING_FORMAT = 3; //AES加密类型,字符串格式
const CACHE_MODE_OFF = 0; //关闭实时流自适应缓冲模式
const ADAPTIVE_CACHE = 1; //自适应缓冲
const REALTIME_FIRST = 2; //实时优先
const FLUENCY_FIRST = 3; //流畅优先
const FRAME_SCENE_POINTS_INFOR_SIZE = 144; // 景物点信息单组信息长度
/* IVS类型 */
var IVS_TYPE =
{
IVSINFOTYPE_PRESETPOS : 1,
IVSINFOTYPE_MOTINTRKS : 2,
IVSINFOTYPE_MOTINTRKS_EX : 3,
IVSINFOTYPE_LIGHT : 4, // 光照
IVSINFOTYPE_RAWDATA : 5, // jason数据
IVSINFOTYPE_TRACK : 6, // 智能分析信息
IVSINFOTYPE_TRACK_EX_B0 : 7, // 智能结构化数据信息
IVSINFOTYPE_MOTIONFRAME : 9,
IVSINFOTYPE_VIDEO_CONCENTRATION : 10,
IVSINFOTYPE_OVERLAY_PIC : 11, // 叠加图片帧
IVSINFOTYPE_OSD_INFO : 12, // OSD辅助帧
IVSINFOTYPE_GPS_INFO : 13, // GPS辅助帧
IVSINFOTYPE_TAGGING_INFO : 14, // 景物点信息标注帧,辅助帧(0x13)
IVSINFOTYPE_TRACK_A1 : 15, // NVR浓缩信息轨迹点
IVSINFOTYPE_DATA_WITH_LARGE_AMOUNT : 16,
IVSINFOTYPE_TRACK_A1_EX : 17, // NVR浓缩信息轨迹点(扩展)
IVSINFOTYPE_DATA_WITH_WATER_LEVEL_MONITOR : 18, //水位检测水位尺信息帧(0x17)
IVSINFOTYPE_INTELFLOW : 19, // 智能客流量
IVSINFOTYPE_DATA_WITH_SOUND_DECIBEL : 20, //声音警报分贝值信息帧(0x18)
IVSINFOTYPE_DATA_WITH_SMART_MOTION : 21, //智能动检信息帧(0x19)
IVSINFOTYPE_DHOP_SMART : 22, //开放平台智能帧(0x14)
IVSINFOTYPE_TRAFFIC_LIGHT : 23, //交通信号灯(红绿灯)辅助帧(0x1D)
IVSINFOTYPE_PTZ_LOCATION : 24, //云台位置帧(0x21)
};
var DRAW_TYPE =
{
DRAW_JSON : 0,
DRAW_TRACK : 1,
DRAW_ALARM : 2,
DRAW_RULE : 3,
DRAW_MOVE_CHECK : 7,
DRAW_TEST : 9,
DRAW_WEB_RULE : 11,
DRAW_WEB_ALARM : 12,
DRAW_FLOW_INFO : 13,
DRAW_TRACKEX2 : 14,
DRAW_WUXI235_TRACKEX2 : 15,
DRAW_TRACKEXA1 : 16,
DRAW_TRACKEX2_TYPE_HUMAN : 17,
DRAW_TRACKEX2_TYPE_VEHICLE : 18,
DRAW_TRACKEX2_TYPE_NONMOTOR : 19,
DRAW_TRACKEX2_TYPE_SHOPPRESENCE : 20,
DRAW_TRACKEX2_TYPE_FLOWBUSINESS : 21,
DRAW_INTELFLOW : 22,
DRAW_SMARTMOTION : 23,
DRAW_DHOPSMART : 24,
DRAW_DATA_WITH_LARGE_AMOUNT : 25,//大数据量帧
DRAW_TRACKEX2_TYPE_BAG : 26,
DRAW_RULE_HIGHWAY_LANES : 27, //高速车道线
DRAW_WATER_LEVEL_MONITOR : 28, //水位尺
DRAW_END : 29
};
//DHOP元素类型
var IVS_DHOP_ElEMENT_TYPE =
{
EM_DHOP_CIRCLE : 1,
EM_DHOP_BrokenLine : 2,
EM_DHOP_POLYGON : 3,
EM_DHOP_TEXT : 4
};
importScripts('libplay.js');
addEventListener('message', receiveMessage, false);
Module.onRuntimeInitialized = function(){
m_bLoadSuccess = true;
var msgType = 'LoadSuccess';
sendMessage(m_nPlayPort, msgType, null);
}
var m_bPlayback = 0;
var m_bSupportH264MSE = false;
var m_bSupportH265MSE = false;
var m_nCanvasWidth = 1920;
var m_nCanvasHeight = 1080;
var m_nPlayPort = 0;
var jsInputData = null;
var jsInputDataAry = null;
var jsFrameBuf = null;
var jsFrameInfo = null;
let dataView = null;
var jsBuf = null;
var jsFrameBodyData = null;
var jsBufY = null;
var jsBufU = null;
var jsBufV = null;
var jsYuvDataY = null;
var jsYuvDataU = null;
var jsYuvDataV = null;
var jsRecordFrameBuf = null;
var jsRecordFrameInfo = null;
var dataViewRecord = null;
let ivsBuf = null;
let ivsDataArray = null;
let ivsDataView = null;
var m_nWidth = 0;
var m_nHeight = 0;
var m_nPreWidth = 0;
var m_nPreHeight = 0;
var m_bSmartEncode = 0;
var m_nVideoEncodeType = 0;
var m_bLoadSuccess = false;
var m_bDecryptionResult = false;
var m_nTotalStreamLength = 0;
function receiveMessage(event)
{
if (!m_bLoadSuccess)
{
return;
}
var message = event.data;
switch (message.nType)
{
//初始化
case 'Init':
m_bPlayback = message.option.bPlayback;
m_bSupportH264MSE = message.option.bSupportH264MSE;
m_bSupportH265MSE = message.option.bSupportH265MSE;
m_nCanvasWidth = message.option.nCanvasWidth;
m_nCanvasHeight = message.option.nCanvasHeight;
Init();
break;
//送流
case 'InputData':
InputData(message.pData);
break;
//打开智能绘制
case 'OpenIVSDraw':
OpenIVSDraw();
break;
//关闭智能绘制
case 'CloseIVSDraw':
CloseIVSDraw();
break;
//开始码流录制
case 'StartRecord':
StartRecord(message.nRecordType);
break;
//停止码流录制
case 'StopRecord':
StopRecord();
break;
//设置播放速度
case 'SetPlaySpeed':
SetPlaySpeed(message.nSpeed);
break;
//设置OSD叠加
case 'SetYUVOSDInfoEx':
SetYUVOSDInfoEx(message.OSDInfo);
break;
case 'GetOriginalKeyCallBack':
GetOriginalKey(message.playToken, message.playTokenKey, message.deviceID);
break;
case 'SetWebSecurityKey':
SetWebSecurityKey(message.nDecryptType, message.nFrameType, message.strKey, message.stStreamInfo);
break;
//设置解密秘钥
case 'SetSecurityKey':
SetSecurityKey(message.nEncryptType, message.szKey, message.nKeyLen, message.szKeyId, message.nKeyIdLen);
break;
//设置是否支持硬解码标记
case 'SetSupportWebMSE':
m_bSupportH264MSE = message.bSupportH264MSE;
m_bSupportH265MSE = message.bSupportH265MSE;
SetSupportWebMSE(m_bSupportH264MSE, m_bSupportH265MSE);
//暂停播放
case 'Pause':
Pause(message.bPause);
break;
//抓图
case 'CatchPic':
CatchPic();
break;
//停止播放
case 'Stop':
Stop();
break;
case 'setPrintLogLevel':
SetPrintLogLevel(message.nLogLevel);
break;
default:
break;
}
}
function Init()
{
//获取PlaySDK空闲端口号
var jsPort = Module._malloc(1);
var jsPortAry = new Uint8Array(Module.HEAPU8.buffer, jsPort, 1);
Module._PLAY_GetFreePort(jsPortAry.byteOffset);
m_nPlayPort = jsPortAry[0];
jsPortAry = null;
Module._free(jsPort);
//设置播放窗口宽高属性
Module._PLAY_ViewResolutionChanged(m_nPlayPort, m_nCanvasWidth, m_nCanvasHeight, 0);
//设置实时流模式
var nRet = Module._PLAY_SetStreamOpenMode(m_nPlayPort, m_bPlayback);
nRet = Module._PLAY_OpenStream(m_nPlayPort, 0, 0, 10*1024*1024);
nRet = Module._PLAY_SetSupportWebMSE(m_nPlayPort, m_bSupportH264MSE, m_bSupportH265MSE);
nRet = Module._PLAY_Play(m_nPlayPort, 1);
if (nRet)
{
//向C++层申请一块wasm内存,用于接收码流
jsInputData = Module._malloc(5*1024*1024);
jsInputDataAry = new Uint8Array(Module.HEAPU8.buffer, jsInputData, 5*1024*1024);
var msgType = 'InitSuccess';
sendMessage(m_nPlayPort, msgType, null);
}
}
function InputData(data)
{
m_nTotalStreamLength += data.length;
if(jsInputDataAry)
{
jsInputDataAry.set(data);
var nRet = Module._PLAY_InputData(m_nPlayPort, jsInputDataAry.byteOffset, data.length);
var i = 0;
}
}
function OpenIVSDraw()
{
Module._PLAY_RenderPrivateData(m_nPlayPort, 1, 0);
}
function CloseIVSDraw()
{
Module._PLAY_RenderPrivateData(m_nPlayPort, 0, 0);
}
function StartRecord(nRecordType)
{
Module._PLAY_StartDataRecord(m_nPlayPort, 0, nRecordType);
}
function StopRecord()
{
Module._PLAY_StopDataRecord(m_nPlayPort);
}
function SetPlaySpeed(nSpeed)
{
Module._PLAY_SetPlaySpeed(m_nPlayPort, nSpeed);
}
function SetYUVOSDInfoEx(OSDInfo)
{
if (0 == m_nCanvasWidth || 0 == m_nCanvasHeight)
{
return;
}
let nOsdCount = OSDInfo.osdCount;
let nStuOsdInfoSize = 18376;//单个YUV_OSD_INFO_EX结构体18376字节
const OsdDataInfoPtr = Module._malloc(nStuOsdInfoSize);
let arrayFormat = new Uint8Array(Module.HEAPU8.buffer);
for (let i = 0; i < nStuOsdInfoSize; i ++)
{
arrayFormat[OsdDataInfoPtr + i] = 0;
}
Module.HEAPU8[OsdDataInfoPtr + 0] = 1;//是否是私有字体
let strFontPath = "Font.bin";
let nSequence = 0;
strFontPath.split('').forEach((char, nIndex) =>
{
let nValue = char.charCodeAt(0);
arrayFormat[OsdDataInfoPtr + nSequence + 1] = nValue;
nSequence++;
});
Module.HEAP32[OsdDataInfoPtr/4 + 65] = nOsdCount;
for (let i = 0; i < nOsdCount; i ++)
{
let nPointX = OSDInfo.osdList[i].pointX / m_nCanvasWidth * m_nWidth;
let nPointY = OSDInfo.osdList[i].pointY / m_nCanvasHeight * m_nHeight;
Module.HEAP32[OsdDataInfoPtr/4 + 66 + 564/4 * i] = nPointX;// 旋转点像素x位置
Module.HEAP32[OsdDataInfoPtr/4 + 67 + 564/4 * i] = nPointY;// 旋转点像素y位置
Module.HEAP32[OsdDataInfoPtr/4 + 68 + 564/4 * i] = OSDInfo.osdList[i].colorR;// osd叠加颜色r,范围0-255
Module.HEAP32[OsdDataInfoPtr/4 + 69 + 564/4 * i] = OSDInfo.osdList[i].colorG;// osd叠加颜色g,范围0-255
Module.HEAP32[OsdDataInfoPtr/4 + 70 + 564/4 * i] = OSDInfo.osdList[i].colorB;// osd叠加颜色b,范围0-255
Module.HEAP32[OsdDataInfoPtr/4 + 71 + 564/4 * i] = OSDInfo.osdList[i].colorA;// osd叠加透明度,范围0-255
nSequence = 0;
//JS默认采用UTF-16编码,需要先转为UTF-8编码
let UTF8Array = UTF16ToUTF8(OSDInfo.osdList[i].strOsdData);
for(let j = 0; j < UTF8Array.length; j++)
{
arrayFormat[(OsdDataInfoPtr + nSequence + 288 + 564 * i) >> 0] = UTF8Array[j];// osd数据,使用utf-8编码
nSequence++;
}
Module.HEAP32[OsdDataInfoPtr/4 + 200 + 564/4 * i] = OSDInfo.osdList[i].fontX;// 字体宽度, 使用私有字体时无效
Module.HEAP32[OsdDataInfoPtr/4 + 201 + 564/4 * i] = OSDInfo.osdList[i].fontY;// 字体高度, 最大512
Module.HEAP32[OsdDataInfoPtr/4 + 202 + 564/4 * i] = OSDInfo.osdList[i].rotateAngle;// 旋转角度,范围0-359度
Module.HEAPU8[OsdDataInfoPtr + 812 + 564 * i] = OSDInfo.osdList[i].coordinate8192;// 8192坐标系, 0表示像素坐标x,y基于码流分辨率, 1表示基于8192坐标系
}
Module._PLAY_SetYUVOSDInfoEx(m_nPlayPort, OsdDataInfoPtr);
Module._free(OsdDataInfoPtr);
}
function GetOriginalKey(playToken, playTokenKey, deviceID)
{
var arrPlayToken = Module.intArrayFromString(playToken).concat(0);//add '\0'
var playTokenPtr = Module._malloc(arrPlayToken.length);//采用声明的c函数 _malloc
Module.HEAPU8.set(arrPlayToken, playTokenPtr);//复制字符串内容
var arrPlayTokenKey = Module.intArrayFromString(playTokenKey).concat(0);
var playTokenKeyPtr = Module._malloc(arrPlayTokenKey.length);
Module.HEAPU8.set(arrPlayTokenKey, playTokenKeyPtr);
var arrDeviceID = Module.intArrayFromString(deviceID).concat(0);
var deviceIDPtr = Module._malloc(arrDeviceID.length);
Module.HEAPU8.set(arrDeviceID, deviceIDPtr);
var outKeyPtr = Module._malloc(256);
var outKeyLengthPtr = Module._malloc(4);
var nRet = Module._PLAY_GetOriginalKey(m_nPlayPort, playTokenPtr, playTokenKeyPtr, deviceIDPtr, outKeyPtr, outKeyLengthPtr);
var outKeyLength = Module.HEAP32[outKeyLengthPtr >>2];
var outKeyTmp = "";
if ((1 == nRet) && (outKeyLength <= 256))
{
var jsKeyBuf = new ArrayBuffer(outKeyLength);
var jsKeyData = new Uint8Array(jsKeyBuf);
jsKeyData.set(Module.HEAPU8.subarray(outKeyPtr, outKeyPtr + outKeyLength));
outKeyTmp = ArrayBufferToString(jsKeyBuf);
}
Module._free(playTokenPtr);//释放内存
Module._free(playTokenKeyPtr);
Module._free(deviceIDPtr);
Module._free(outKeyPtr);
Module._free(outKeyLengthPtr);
var outKeyParam =
{
nRet: nRet,
outKey: outKeyTmp,
};
var msgType = 'GetOriginalKeyCallBack';
var msgData =
{
nRet: nRet,
outKey: outKeyTmp,
}
sendMessage(m_nPlayPort, msgType, msgData);
}
function SetWebSecurityKey(nDecryptType, nFrameType, strKey, stStreamInfo)
{
var arrStrKey = Module.intArrayFromString(strKey).concat(0);
var strKeyPtr = Module._malloc(arrStrKey.length);
Module.HEAPU8.set(arrStrKey, strKeyPtr);
var arrSdpInfo = Module.intArrayFromString(stStreamInfo.sdpInfo).concat(0);
var sdpInfoPtr = Module._malloc(arrSdpInfo.length);
Module.HEAPU8.set(arrSdpInfo, sdpInfoPtr);
var arrUserName = Module.intArrayFromString(stStreamInfo.strUserName).concat(0);
var userNamePtr = Module._malloc(arrUserName.length);
Module.HEAPU8.set(arrUserName, userNamePtr);
var arrPassWord = Module.intArrayFromString(stStreamInfo.strPassWord).concat(0);
var passWordPtr = Module._malloc(arrPassWord.length);
Module.HEAPU8.set(arrPassWord, passWordPtr);
const stStreamInfoPtr = Module._malloc(16);//4:uint32的字节大小
Module.HEAP32[stStreamInfoPtr/4 + 0] = sdpInfoPtr;
Module.HEAP32[stStreamInfoPtr/4 + 1] = userNamePtr;
Module.HEAP32[stStreamInfoPtr/4 + 2] = passWordPtr;
Module.HEAP32[stStreamInfoPtr/4 + 3] = stStreamInfo.nSsrc;
Module._PLAY_SetWebSecurityKey(m_nPlayPort, nDecryptType, nFrameType, strKeyPtr, stStreamInfoPtr);
Module._free(strKeyPtr);//释放内存
Module._free(sdpInfoPtr);
Module._free(userNamePtr);
Module._free(passWordPtr);
Module._free(stStreamInfoPtr);
}
function SetSecurityKey(nEncryptType, szKey, nKeyLen, szKeyId, nKeyIdLen)
{
var nRet = 1;
var strKey = Module._malloc(49);
var arrayKey = new Uint8Array(Module.HEAPU8.buffer);
var nSequence = 0;
if (ENCRYPT_AES == nEncryptType)
{
//逐字节的形式去内存中设置值,直接修改wasm内存数据
szKey.forEach((value, nIndex) => {
arrayKey[(strKey + nSequence) >> 0] = value;
nSequence++;
});
}
else if(ENCRYPT_AES256 == nEncryptType)
{
var szKeyIdTmp = new Uint8Array(16); ;
//协议规定ENCRYPT_AES256对应的枚举值为1
arrayKey[(strKey + nSequence) >> 0] = 1;
nSequence++;
if (0 == nKeyIdLen)
{
for(var i = 0; i < 16; i++)
{
szKeyIdTmp[i] = 0x00;
}
nKeyIdLen = 16;
szKeyId = szKeyIdTmp;
}
//拼接上key ID,逐字节的形式去内存中设置值,直接修改wasm内存数据
szKeyId.forEach((value, nIndex) => {
arrayKey[(strKey + nSequence) >> 0] = value;
nSequence++;
});
//拼接上key,逐字节的形式去内存中设置值,直接修改wasm内存数据
szKey.forEach((value, nIndex) => {
arrayKey[strKey + nSequence] = value;
nSequence++;
});
nKeyLen = 1 + nKeyLen + nKeyIdLen;
szKeyIdTmp = null;
}
else if(ENCRYPT_AES_STRING_FORMAT == nEncryptType)
{
szKey.split('').forEach((char, nIndex) => {
arrayKey[(strKey + nSequence) >> 0] = char.charCodeAt(0);
nSequence++;
});
}
nRet = Module._PLAY_SetSecurityKey(m_nPlayPort, strKey, nKeyLen);
Module._free(strKey);
return nRet;
}
function SetSupportWebMSE(bSupportH264MSE, bSupportH265MSE)
{
Module._PLAY_SetSupportWebMSE(m_nPlayPort, bSupportH264MSE, bSupportH265MSE);
}
function Pause(bPause)
{
Module._PLAY_Pause(m_nPlayPort, bPause);
}
function CatchPic()
{
var nSize = m_nWidth * m_nHeight * 3/2;
var pJpegBuf = Module._malloc(nSize);
var pJpegBufArr = new Uint8Array(Module.HEAPU8.buffer, pJpegBuf, nSize);
var pJpegSize = Module._malloc(4);
var pJpegSizeArr = new Uint8Array(Module.HEAPU8.buffer, pJpegSize, 4);
//获取当前图像编码后的jpeg图片数据
Module._PLAY_GetPicJPEG(m_nPlayPort, pJpegBufArr.byteOffset, nSize, pJpegSizeArr.byteOffset, 100);
//C++内存数据拷贝至JS内存
var nDataSize = (pJpegSizeArr[3] << 24) + (pJpegSizeArr[2] << 16) + (pJpegSizeArr[1] << 8) + pJpegSizeArr[0];
var pOutJpegBuf = new ArrayBuffer(nDataSize);
var pOutJpegBufArr = new Uint8Array(pOutJpegBuf);
pOutJpegBufArr.set(Module.HEAPU8.subarray(pJpegBufArr.byteOffset, pJpegBufArr.byteOffset + nDataSize));
var msgType = 'CatchPicCallBack';
var msgData =
{
buffer: pOutJpegBufArr
}
sendMessage(m_nPlayPort, msgType, msgData);
Module._free(pJpegBuf);
Module._free(pJpegSize);
pJpegBufArr = null;
pJpegSizeArr = null;
pOutJpegBuf= null;
pOutJpegBufArr = null;
}
function Stop()
{
var nRet = Module._PLAY_Stop(m_nPlayPort);
if (0 == nRet)
{
return;
}
nRet = Module._PLAY_CloseStream(m_nPlayPort);
jsInputDataAry = null;
Module._free(jsInputData);
jsFrameBuf = null;
jsFrameInfo = null;
dataView = null;
jsBufY = null;
jsBufU = null;
jsBufV = null;
jsYuvDataY = null;
jsYuvDataU = null;
jsYuvDataV = null;
jsRecordFrameBuf = null;
jsRecordFrameInfo = null;
dataViewRecord = null;
m_nTotalStreamLength = 0;
}
function SetPrintLogLevel(nLogLevel)
{
Module._PLAY_SetPrintLogLevel(nLogLevel);
}
function cPlusVisibleDecCallBack(nPort, pBufY, pBufU, pBufV, nSize, pFrameInfo)
{
var stuFrameInfo = {};
stuFrameInfo.nTotalStreamLength = m_nTotalStreamLength;
if(!jsFrameInfo)
{
jsFrameBuf = new ArrayBuffer(292);//通过二进制对象分配一块连续内存
jsFrameInfo = new Uint8Array(jsFrameBuf);//二进制对象绑定到视图,通过视图对内存进行读写操作
dataView = new DataView(jsFrameBuf);
}
jsFrameInfo.set(Module.HEAPU8.subarray(pFrameInfo, pFrameInfo + 292));//c中的内存拷贝到刚分配的js内存中
//帧类型
stuFrameInfo.nFrameType = dataView.getInt32(0, true);
//帧序号
stuFrameInfo.nFrameID = dataView.getInt32(4, true);
//帧子类型
stuFrameInfo.nFrameSubType = dataView.getInt32(56, true);
//帧时间
stuFrameInfo.nYear = dataView.getUint16(40, true);
stuFrameInfo.nMonth = dataView.getUint16(42, true);
stuFrameInfo.nDay = dataView.getUint16(46, true);
stuFrameInfo.nHour = dataView.getUint16(48, true);
stuFrameInfo.nMinute = dataView.getUint16(50, true);
stuFrameInfo.nSecond = dataView.getUint16(52, true);
var msgData = {};
//视频
if (1 == stuFrameInfo.nFrameType)
{
//剩余缓冲数据量
stuFrameInfo.nRemainData = dataView.getInt32(36, true);
//抽帧标记
stuFrameInfo.bThrowFrame = dataView.getUint8(120, true);
if (0 == stuFrameInfo.bThrowFrame)
{
//编码类型
stuFrameInfo.nEncodeType = dataView.getInt32(108, true);
//码流类型
stuFrameInfo.nStreamType = dataView.getInt32(112, true);
//时间戳
stuFrameInfo.nTimeStamp = dataView.getUint32(8, true);
//图像宽度
stuFrameInfo.nWidth = dataView.getInt32(12, true);
m_nWidth = stuFrameInfo.nWidth;
//图像高度
stuFrameInfo.nHeight = dataView.getInt32(16, true);
m_nHeight = stuFrameInfo.nHeight;
//视频帧率
stuFrameInfo.nFrameRate = dataView.getInt32(20, true);
//图像跨距
stuFrameInfo.nStride = dataView.getInt32(116, true);
//vui句法中视频三原色
stuFrameInfo.nColorPrimaries = dataView.getUint8(124, true);
//vui句法中视频信号转换函数
stuFrameInfo.nColorTransfer = dataView.getUint8(125, true);
//vui中视频颜色空间
stuFrameInfo.nColorSpace = dataView.getUint8(126, true);
//颜色范围 0:yuv范围16-235,对应 TV; 1:yuv范围0-255, 对应 PC
stuFrameInfo.bColorFull = dataView.getUint8(127, true);
if ((ENCODE_TYPE_VIDEO_HI_H264 == stuFrameInfo.nEncodeType) || (ENCODE_TYPE_VIDEO_MY_H264 == stuFrameInfo.nEncodeType) || (ENCODE_TYPE_VIDEO_STD_H264 == stuFrameInfo.nEncodeType))
{
//H.264编码类型
m_nVideoEncodeType = 1;
}
else if(12 == stuFrameInfo.nEncodeType)
{
//H.265编码类型
m_nVideoEncodeType = 2;
}
//智能I/P帧
if ((VIDEO_FRAME_SUB_TYPE_SMART_I == stuFrameInfo.nFrameSubType)
|| (VIDEO_FRAME_SUB_TYPE_SMART_P == stuFrameInfo.nFrameSubType)
|| (VIDEO_FRAME_SUB_TYPE_SMART_I_NORENDER == stuFrameInfo.nFrameSubType))
{
//Smart H.264或者Smart H.265
m_bSmartEncode = 1;
}
else if(0 == stuFrameInfo.nFrameSubType)
{
m_bSmartEncode = 0;
}
//SVC码流不支持硬解码
if ((((1 == m_nVideoEncodeType) && (true == m_bSupportH264MSE))
|| ((2 == m_nVideoEncodeType) && (true == m_bSupportH265MSE)))
&& (STREAM_TYPE_SVC != stuFrameInfo.nStreamType))
{
//读取码流裸数据
jsBuf = new ArrayBuffer(nSize);//通过二进制对象分配一块连续内存
jsFrameBodyData = new Uint8Array(jsBuf);//二进制对象绑定到视图,通过视图对内存进行读写操作
jsFrameBodyData.set(Module.HEAPU8.subarray(pBufY, pBufY + nSize));//c中的内存拷贝到刚分配的js内存中
msgData =
{
pBufY: jsFrameBodyData,
pBufU: null,
pBufV: null,
nSize: nSize,
stuFrameInfo: stuFrameInfo,
}
}
else
{
if((0 == pBufY) || (0 == pBufU) || (0 == pBufV))
{
return;
}
if (m_nWidth != m_nPreWidth || m_nHeight != m_nPreHeight)
{
m_nPreWidth = m_nWidth;
m_nPreHeight = m_nHeight;
jsBufY = null;
jsBufU = null;
jsBufV = null;
jsYuvDataY = null;
jsYuvDataU = null;
jsYuvDataV = null;
jsBufY = new ArrayBuffer(m_nWidth * m_nHeight);//通过二进制对象分配一块连续内存
jsYuvDataY = new Uint8Array(jsBufY);//二进制对象绑定到视图,通过视图对内存进行读写操作
jsBufU = new ArrayBuffer(m_nWidth * m_nHeight / 4);
jsYuvDataU = new Uint8Array(jsBufU);
jsBufV = new ArrayBuffer(m_nWidth * m_nHeight / 4);
jsYuvDataV = new Uint8Array(jsBufV);
}
var h = 0;
//将C++层YUV解码数据Y分量数据拷贝至JS层内存中
for(h = 0; h < stuFrameInfo.nHeight; h++)
{
jsYuvDataY.set(Module.HEAPU8.subarray((pBufY + h * stuFrameInfo.nStride), (pBufY + h * stuFrameInfo.nStride) + stuFrameInfo.nWidth), h * stuFrameInfo.nWidth);//c中的内存拷贝到刚分配的js内存中
}
//将C++层YUV解码数据U分量数据拷贝至JS层内存中
for(h = 0; h < stuFrameInfo.nHeight / 2; h++)
{
jsYuvDataU.set(Module.HEAPU8.subarray((pBufU + h * stuFrameInfo.nStride/2), (pBufU + h * stuFrameInfo.nStride/2) + stuFrameInfo.nWidth/2), h * stuFrameInfo.nWidth/2);//c中的内存拷贝到刚分配的js内存中
}
//将C++层YUV解码数据V分量数据拷贝至JS层内存中
for(h = 0; h < stuFrameInfo.nHeight / 2; h++)
{
jsYuvDataV.set(Module.HEAPU8.subarray((pBufV + h * stuFrameInfo.nStride/2), (pBufV + h * stuFrameInfo.nStride/2) + stuFrameInfo.nWidth/2), h * stuFrameInfo.nWidth/2);//c中的内存拷贝到刚分配的js内存中
}
msgData =
{
pBufY: jsYuvDataY,
pBufU: jsYuvDataU,
pBufV: jsYuvDataV,
nSize: nSize,
stuFrameInfo: stuFrameInfo,
}
}
}
else
{
msgData =
{
pBufY: null,
pBufU: null,
pBufV: null,
nSize: 0,
stuFrameInfo: stuFrameInfo,
}
}
}
else if(2 == stuFrameInfo.nFrameType)//音频帧
{
//总通道数
stuFrameInfo.nTotalChannel = dataView.getInt32(68, true);
//当前通道
stuFrameInfo.nCurChannel = dataView.getInt32(72, true);
//暂不支持双通道音频播放
if (stuFrameInfo.nCurChannel > 0)
{
return;
}
//采样位数
stuFrameInfo.nBits = dataView.getInt32(28, true);
//采样率
stuFrameInfo.nSamples = dataView.getInt32(32, true);
//声道数
stuFrameInfo.nAudioChnNum = dataView.getInt32(24, true);
var AudioBuf = new ArrayBuffer(nSize);
var UI8AudioData = new Uint8Array(AudioBuf);
//将C++层解码后的pcm音频数据拷贝至JS层内存
UI8AudioData.set(Module.HEAPU8.subarray(pBufY, pBufY + nSize));
msgData =
{
pBufY: UI8AudioData,
pBufU: null,
pBufV: null,
nSize: nSize,
stuFrameInfo: stuFrameInfo,
}
}
var msgType = 'VisibleDecCallBack';
sendMessage(nPort, msgType, msgData);
jsBuf = null;
jsFrameBodyData = null;
}
/*
* C++层AES解密回调
*
* @param[in] nPort 端口号
* @param[in] nFrameID 视频帧序号
* @param[in] bSuccess 是否解密成功
*/
function cDigitalSignCallBack(nPort, nFrameID, bSuccess)
{
m_bDecryptionResult = bSuccess;
var msgType = 'DecryptionResultCallBack';
var msgData =
{
bSuccess: bSuccess
}
sendMessage(nPort, msgType, msgData);
}
/*
* C++层码流录制回调回调至JS层进行数据存储
*
* @param[in] nPort 端口号
* @param[in] pData 码流数据
* @param[in] nDataLen 数据长度
* @param[in] nOffset 偏移量
* @param[in] pFrameInfo 码流信息
*/
function cRecordDataCallBack(nPort, pData, nDataLen, nOffset, pFrameInfo)
{
var stuFrameInfo = {};
if (!jsRecordFrameInfo)
{
jsRecordFrameBuf = new ArrayBuffer(292); //通过二进制对象分配一块连续内存
jsRecordFrameInfo = new Uint8Array(jsRecordFrameBuf); //二进制对象绑定到视图,通过视图对内存进行读写操作
dataViewRecord = new DataView(jsRecordFrameBuf);
}
jsRecordFrameInfo.set(Module.HEAPU8.subarray(pFrameInfo, pFrameInfo + 292)); //c中的内存拷贝到刚分配的js内存中
//帧类型
stuFrameInfo.nFrameType = dataViewRecord.getInt32(0, true);
//帧序号
stuFrameInfo.nFrameID = dataViewRecord.getInt32(4, true);
//帧子类型
stuFrameInfo.nFrameSubType = dataViewRecord.getInt32(56, true);
//视频帧
if (1 == stuFrameInfo.nFrameType)
{
//编码类型
stuFrameInfo.nEncodeType = dataViewRecord.getInt32(68, true);
//码流类型
stuFrameInfo.nStreamType = dataViewRecord.getInt32(72, true);
//时间戳
stuFrameInfo.nTimeStamp = dataViewRecord.getUint32(8, true);
//帧时间
stuFrameInfo.nYear = dataViewRecord.getUint16(40, true);
stuFrameInfo.nMonth = dataViewRecord.getUint16(42, true);
stuFrameInfo.nDay = dataViewRecord.getUint16(46, true);
stuFrameInfo.nHour = dataViewRecord.getUint16(48, true);
stuFrameInfo.nMinute = dataViewRecord.getUint16(50, true);
stuFrameInfo.nSecond = dataViewRecord.getUint16(52, true);
}
var bufRecord = new ArrayBuffer(nDataLen);
var arrayRecord = new Uint8Array(bufRecord);
arrayRecord.set(Module.HEAPU8.subarray(pData, pData + nDataLen));
var msgType = 'RecordDataCallBack';
var msgData =
{
pRecordData: arrayRecord,
nLen: nDataLen,
Offset: nOffset,
stuFrameInfo: stuFrameInfo,
}
sendMessage(nPort, msgType, msgData);
bufRecord = null;
arrayRecord = null;
}
function cIVSDrawDataCallBack(nPort, pBuf, nType, nLen, nReallen)
{
//帧序号为-1时不绘制
if(-1 == nReallen)
{
return;
}
var pParseredBuf = null;
ivsBuf = new ArrayBuffer(nLen);//通过二进制对象分配一块连续内存
ivsDataArray = new Uint8Array(ivsBuf);//二进制对象绑定到视图,通过视图对内存进行读写操作
ivsDataArray.set(Module.HEAPU8.subarray(pBuf, pBuf + nLen));
ivsDataView = new DataView(ivsDataArray.buffer);
if (IVS_TYPE.IVSINFOTYPE_INTELFLOW == nType)
{//智能客流量
var stuIntelflowInfo = {};
stuIntelflowInfo.NumberStat = ivsDataView.getUint16(0, true);//大类业务方案
stuIntelflowInfo.nIntelFlowPlanNum = ivsDataView.getUint16(2, true);//智能客流规则数量(最大不会超过32个)
var pIntelFlowPlan = ivsDataView.getUint32(4, true);
let IntelFlowPlanBuf = new ArrayBuffer(12);
let IntelFlowPlanArray = new Uint8Array(IntelFlowPlanBuf);
let IntelFlowPlanView = new DataView(IntelFlowPlanBuf);
stuIntelflowInfo.pIntelFlowPlan = new Array(stuIntelflowInfo.nIntelFlowPlanNum);
for (let i = 0; i < stuIntelflowInfo.nIntelFlowPlanNum; i++)
{
IntelFlowPlanArray.set(Module.HEAPU8.subarray(pIntelFlowPlan + i * 12, pIntelFlowPlan + i * 12 + 12));
//解析智能客流规则
stuIntelflowInfo.pIntelFlowPlan[i] = {};
stuIntelflowInfo.pIntelFlowPlan[i].PlanId = IntelFlowPlanView.getUint16(0, true);//规则ID
stuIntelflowInfo.pIntelFlowPlan[i].RuleType = IntelFlowPlanView.getUint16(2, true);//规则类型
stuIntelflowInfo.pIntelFlowPlan[i].RegionNum = IntelFlowPlanView.getUint16(8, true);//区域数目
var pRegion = IntelFlowPlanView.getUint32(4, true);
let RegionBuf = new ArrayBuffer(12);
let RegionArray = new Uint8Array(RegionBuf);
let RegionView = new DataView(RegionBuf);
stuIntelflowInfo.pIntelFlowPlan[i].pRegion = new Array(stuIntelflowInfo.pIntelFlowPlan[i].RegionNum);
for (let j = 0; j < stuIntelflowInfo.pIntelFlowPlan[i].RegionNum; j++)
{
RegionArray.set(Module.HEAPU8.subarray(pRegion + j * 12, pRegion + j * 12 + 12));
stuIntelflowInfo.pIntelFlowPlan[i].pRegion[j] = {};
stuIntelflowInfo.pIntelFlowPlan[i].pRegion[j].RegionId = RegionView.getUint16(0, true);//区域ID
stuIntelflowInfo.pIntelFlowPlan[i].pRegion[j].State = RegionView.getUint16(2, true);//状态:离开or进入
stuIntelflowInfo.pIntelFlowPlan[i].pRegion[j].PeopleNum = RegionView.getUint32(4, true);//人数
}
}
pParseredBuf = stuIntelflowInfo;
}
else if (IVS_TYPE.IVSINFOTYPE_DHOP_SMART == nType)
{//DHOP开放平台智能帧
var stuObjDHOP = {};
stuObjDHOP.nId = ivsDataView.getUint32(0, true);//对象ID
stuObjDHOP.wCustom = ivsDataView.getUint16(4, true);//自定义值
stuObjDHOP.chState = ivsDataView.getUint8(6, true);//对象状态
stuObjDHOP.chCount = ivsDataView.getUint8(7, true);//元素个数
//解析DHOP元素
var pElement = ivsDataView.getUint32(8, true);
let elementBuf = new ArrayBuffer(12);
let elementDataArray = new Uint8Array(elementBuf);
let elementDataView = new DataView(elementBuf);
stuObjDHOP.pElement = new Array(stuObjDHOP.chCount);
for (var i = 0; i < stuObjDHOP.chCount; i++)
{
elementDataArray.set(Module.HEAPU8.subarray(pElement + i * 12, pElement + i * 12 + 12));
//解析DHOP元素类型
stuObjDHOP.pElement[i] = {};
stuObjDHOP.pElement[i].nStructType = elementDataView.getUint32(0, true);
stuObjDHOP.pElement[i].nStructLength = elementDataView.getUint32(4, true);
var pStruct = elementDataView.getUint32(8, true);
let structBuf = new ArrayBuffer(stuObjDHOP.pElement[i].nStructLength);
let structArray = new Uint8Array(structBuf);
let structDataView = new DataView(structBuf);
structArray.set(Module.HEAPU8.subarray(pStruct, pStruct + stuObjDHOP.pElement[i].nStructLength));
stuObjDHOP.pElement[i].pStruct = {};
if (IVS_DHOP_ElEMENT_TYPE.EM_DHOP_CIRCLE == stuObjDHOP.pElement[i].nStructType)
{
stuObjDHOP.pElement[i].pStruct.chType = structDataView.getUint8(0, true);//子类型0x3
stuObjDHOP.pElement[i].pStruct.chWidth = structDataView.getUint8(1, true);//线宽,单位px
stuObjDHOP.pElement[i].pStruct.chStyle = structDataView.getUint8(2, true);//样式
stuObjDHOP.pElement[i].pStruct.wRadius = structDataView.getUint16(4, true);//半径
stuObjDHOP.pElement[i].pStruct.positionCircle = {};//圆心坐标
stuObjDHOP.pElement[i].pStruct.positionCircle.x = structDataView.getUint16(8, true);
stuObjDHOP.pElement[i].pStruct.positionCircle.y = structDataView.getUint16(10, true);
stuObjDHOP.pElement[i].pStruct.chLineA = structDataView.getUint8(12, true);//边框线条颜色(ARGB)
stuObjDHOP.pElement[i].pStruct.chLineR = structDataView.getUint8(13, true);
stuObjDHOP.pElement[i].pStruct.chLineG = structDataView.getUint8(14, true);
stuObjDHOP.pElement[i].pStruct.chLineB = structDataView.getUint8(15, true);
stuObjDHOP.pElement[i].pStruct.chRegA = structDataView.getUint8(16, true);//区域填充颜色(ARGB)
stuObjDHOP.pElement[i].pStruct.chRegR = structDataView.getUint8(17, true);
stuObjDHOP.pElement[i].pStruct.chRegG = structDataView.getUint8(18, true);
stuObjDHOP.pElement[i].pStruct.chRegB = structDataView.getUint8(19, true);
}
else if(IVS_DHOP_ElEMENT_TYPE.EM_DHOP_BrokenLine == stuObjDHOP.pElement[i].nStructType)
{
stuObjDHOP.pElement[i].pStruct.chType = structDataView.getUint8(0, true);//子类型0x2
stuObjDHOP.pElement[i].pStruct.chCount = structDataView.getUint8(1, true);//端点个数
stuObjDHOP.pElement[i].pStruct.chWidth = structDataView.getUint8(2, true);//线宽,单位px
stuObjDHOP.pElement[i].pStruct.chStyle = structDataView.getUint8(3, true);//样式
stuObjDHOP.pElement[i].pStruct.chLineA = structDataView.getUint8(4, true);//边框线条颜色(ARGB)
stuObjDHOP.pElement[i].pStruct.chLineR = structDataView.getUint8(5, true);
stuObjDHOP.pElement[i].pStruct.chLineG = structDataView.getUint8(6, true);
stuObjDHOP.pElement[i].pStruct.chLineB = structDataView.getUint8(7, true);
//端点坐标
var pPoints = null;
let pointsBuf = null;
let pointsDataArray = null;
let pointsDataView = null;
if (stuObjDHOP.pElement[i].pStruct.chCount > 0)
{
stuObjDHOP.pElement[i].pStruct.pPoints = new Array(stuObjDHOP.pElement[i].pStruct.chCount);
pPoints = structDataView.getUint32(8, true);
pointsBuf = new ArrayBuffer(4);
pointsDataArray = new Uint8Array(pointsBuf);
pointsDataView = new DataView(pointsBuf);
}
for(var j = 0; j < stuObjDHOP.pElement[i].pStruct.chCount; j++)
{
pointsDataArray.set(Module.HEAPU8.subarray(pPoints + j*4, pPoints + j*4 + 4));
stuObjDHOP.pElement[i].pStruct.pPoints[j] = {};
stuObjDHOP.pElement[i].pStruct.pPoints[j].x = pointsDataView.getUint16(0, true);
stuObjDHOP.pElement[i].pStruct.pPoints[j].y = pointsDataView.getUint16(2, true);
}
}
else if(IVS_DHOP_ElEMENT_TYPE.EM_DHOP_POLYGON == stuObjDHOP.pElement[i].nStructType)
{
stuObjDHOP.pElement[i].pStruct.chType = structDataView.getUint8(0, true);//子类型0x3
stuObjDHOP.pElement[i].pStruct.chCount = structDataView.getUint8(1, true);//端点个数
stuObjDHOP.pElement[i].pStruct.chWidth = structDataView.getUint8(2, true);//线宽,单位px
stuObjDHOP.pElement[i].pStruct.chStyle = structDataView.getUint8(3, true);//样式
stuObjDHOP.pElement[i].pStruct.chLineA = structDataView.getUint8(4, true);//边框线条颜色(ARGB)
stuObjDHOP.pElement[i].pStruct.chLineR = structDataView.getUint8(5, true);
stuObjDHOP.pElement[i].pStruct.chLineG = structDataView.getUint8(6, true);
stuObjDHOP.pElement[i].pStruct.chLineB = structDataView.getUint8(7, true);
stuObjDHOP.pElement[i].pStruct.chRegA = structDataView.getUint8(8, true);//区域填充颜色(ARGB)
stuObjDHOP.pElement[i].pStruct.chRegR = structDataView.getUint8(9, true);
stuObjDHOP.pElement[i].pStruct.chRegG = structDataView.getUint8(10, true);
stuObjDHOP.pElement[i].pStruct.chRegB = structDataView.getUint8(11, true);
//端点坐标
var pPoints = null;
let pointsBuf = null;
let pointsDataArray = null;
let pointsDataView = null;
if (stuObjDHOP.pElement[i].pStruct.chCount > 0)
{
stuObjDHOP.pElement[i].pStruct.pPoints = new Array(stuObjDHOP.pElement[i].pStruct.chCount);
pPoints = structDataView.getUint32(12, true);
pointsBuf = new ArrayBuffer(4);
pointsDataArray = new Uint8Array(pointsBuf);
pointsDataView = new DataView(pointsBuf);
}
for(var j = 0; j < stuObjDHOP.pElement[i].pStruct.chCount; j++)
{
pointsDataArray.set(Module.HEAPU8.subarray(pPoints + j*4, pPoints + j*4 + 4));
stuObjDHOP.pElement[i].pStruct.pPoints[j] = {};
stuObjDHOP.pElement[i].pStruct.pPoints[j].x = pointsDataView.getUint16(0, true);
stuObjDHOP.pElement[i].pStruct.pPoints[j].y = pointsDataView.getUint16(2, true);
}
}
else if(IVS_DHOP_ElEMENT_TYPE.EM_DHOP_TEXT == stuObjDHOP.pElement[i].nStructType)
{
stuObjDHOP.pElement[i].pStruct.chType = structDataView.getUint8(0, true);//子类型0x4
stuObjDHOP.pElement[i].pStruct.chCharset = structDataView.getUint8(1, true);//编码方式
stuObjDHOP.pElement[i].pStruct.stringPos = {};//字符坐标
stuObjDHOP.pElement[i].pStruct.stringPos.x = structDataView.getUint16(4, true);
stuObjDHOP.pElement[i].pStruct.stringPos.y = structDataView.getUint16(6, true);
stuObjDHOP.pElement[i].pStruct.chLineA = structDataView.getUint8(8, true);//字体颜色(ARGB)
stuObjDHOP.pElement[i].pStruct.chLineR = structDataView.getUint8(9, true);
stuObjDHOP.pElement[i].pStruct.chLineG = structDataView.getUint8(10, true);
stuObjDHOP.pElement[i].pStruct.chLineB = structDataView.getUint8(11, true);
stuObjDHOP.pElement[i].pStruct.chFontSize = structDataView.getUint8(12, true);//字体大小,单位px
stuObjDHOP.pElement[i].pStruct.chFontAlign = structDataView.getUint8(13, true);//对齐方式
stuObjDHOP.pElement[i].pStruct.wTxtLen = structDataView.getUint16(14, true);//字符长度
var pString = structDataView.getUint32(16, true);
var stringBuf = new ArrayBuffer(stuObjDHOP.pElement[i].pStruct.wTxtLen);
var stringDataArray = new Uint8Array(stringBuf);
var stringDataView = new DataView(stringBuf);
stringDataArray.set(Module.HEAPU8.subarray(pString, pString + stuObjDHOP.pElement[i].pStruct.wTxtLen));
stuObjDHOP.pElement[i].pStruct.stringDataArray = stringDataArray;
}
}
//解析DHOP信息内容
stuObjDHOP.nInfoLen = ivsDataView.getUint16(12, true);//信息长度
if (stuObjDHOP.nInfoLen > 0)
{
var pInfo = ivsDataView.getUint32(16, true);
let infoBuf = new ArrayBuffer(stuObjDHOP.nInfoLen);
let infoDataArray = new Uint8Array(infoBuf);
infoDataArray.set(Module.HEAPU8.subarray(pInfo, pInfo + stuObjDHOP.nInfoLen));
stuObjDHOP.pInfo = infoDataArray;
}
pParseredBuf = stuObjDHOP;
}
else if (IVS_TYPE.IVSINFOTYPE_TAGGING_INFO == nType)//景物点信息标注帧
{
let dataView = new DataView(ivsBuf);
let tagInfoNum = nLen/FRAME_SCENE_POINTS_INFOR_SIZE;
let tagInfos = [];
for (let tagInfoIndex = 0; tagInfoIndex < tagInfoNum; tagInfoIndex++)
{
var tagInfo = {};
let Stride = FRAME_SCENE_POINTS_INFOR_SIZE * tagInfoIndex;
//编号
tagInfo.nIndex = dataView.getInt32(Stride + 0, true);
//景物点x坐标
tagInfo.xPoint = dataView.getUint16(Stride + 4, true);
//景物点y坐标
tagInfo.yPoint = dataView.getUint16(Stride + 6, true);
//一级名称
var jsNameBuf = new ArrayBuffer(64);
jsNameBuf = ivsBuf.slice(Stride + 8);
tagInfo.strName = ArrayBufferToStringAutoClip(jsNameBuf);
//使能标记
tagInfo.enable = dataView.getInt8(Stride + 72, true);
//标签类型
tagInfo.titleType = dataView.getInt8(Stride + 73, true);
//标签属性
tagInfo.titleAttribute = dataView.getInt8(Stride + 74, true);
tagInfo.sharpType = dataView.getInt8(Stride + 75, true);
tagInfo.polygonNum = dataView.getInt8(Stride + 76, true);
tagInfo.polygon = [];
//与上一个中间空了三字节
for(let i = 0;i< tagInfo.polygonNum*2;i+=2)
{
tagInfo.polygon[i] ={x: dataView.getInt8(Stride + 79 + 2*i, true),
y: dataView.getInt8(Stride + 79 + 2*(i+1), true)};
}
tagInfos[tagInfoIndex] = tagInfo;
jsNameBuf = null;
}
var msgType = 'ARTagInfoCallback';
var msgData =
{
tagInfo: tagInfos,
}
sendMessage(nPort, msgType, msgData);
pParseredBuf = ivsDataArray;
dataView = null;
}
else
{
pParseredBuf = ivsDataArray;
}
var msgType = 'IVSDataCallBack';
var msgData =
{
pBuf: pParseredBuf,
nType: nType,
nLen: nLen,
nReallen: nReallen,
}
sendMessage(nPort, msgType, msgData);
}
function sendMessage(nPort, msgType, msgData)
{
var event =
{
nPort: nPort,
msgType: msgType,
msgData: msgData,
};
postMessage(event);
}
function ArrayBufferToString(buffer, encoding = 'utf-8')
{
const decoder = new TextDecoder(encoding);
return decoder.decode(buffer);
}
function ArrayBufferToStringAutoClip(buffer, encoding = 'utf-8')
{
const decoder = new TextDecoder(encoding);
const uint8Array = new Uint8Array(buffer);
let i = 0;
while (i < uint8Array.length) {
if (uint8Array[i] === 0) {
break;
}
i++;
}
return decoder.decode(buffer.slice(0,i));
}
function UTF16ToUTF8(UTF16Str)
{
var UTF8Arr = [];
var byteSize = 0;
for (var i = 0; i < UTF16Str.length; i++)
{
//获取字符Unicode码值
var code = UTF16Str.charCodeAt(i);
//如果码值是1个字节的范围,则直接写入
if (code >= 0x00 && code <= 0x7f)
{
byteSize += 1;
UTF8Arr.push(code);
//如果码值是2个字节以上的范围,则按规则进行填充补码转换
}
else if (code >= 0x80 && code <= 0x7ff)
{
byteSize += 2;
UTF8Arr.push((192 | (31 & (code >> 6))));
UTF8Arr.push((128 | (63 & code)))
}
else if ((code >= 0x800 && code <= 0xd7ff) || (code >= 0xe000 && code <= 0xffff))
{
byteSize += 3;
UTF8Arr.push((224 | (15 & (code >> 12))));
UTF8Arr.push((128 | (63 & (code >> 6))));
UTF8Arr.push((128 | (63 & code)))
}
else if(code >= 0x10000 && code <= 0x10ffff)
{
byteSize += 4;
UTF8Arr.push((240 | (7 & (code >> 18))));
UTF8Arr.push((128 | (63 & (code >> 12))));
UTF8Arr.push((128 | (63 & (code >> 6))));
UTF8Arr.push((128 | (63 & code)))
}
}
return UTF8Arr
}