systemTransform-worker.js 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. importScripts('libSystemTransform.js');
  2. const RECORDRTP = 0; //录制一份未经过转封装的码流原始数据,用于定位问题
  3. let dataType = 1;
  4. // 字母字符串转byte数组
  5. function stringToBytes (str) {
  6. var ch;
  7. var st;
  8. var re = [];
  9. for (var i = 0; i < str.length; i++) {
  10. ch = str.charCodeAt(i); // get char
  11. st = []; // set up "stack"
  12. do {
  13. st.push(ch & 0xFF); // push byte to stack
  14. ch = ch >> 8; // shift value down by 1 byte
  15. }
  16. while (ch);
  17. // add stack contents to result
  18. // done because chars have "wrong" endianness
  19. re = re.concat(st.reverse());
  20. }
  21. // return an array of bytes
  22. return re;
  23. }
  24. // 转封装库回调函数
  25. self.STCallBack = function (fileIndex, indexLen, data, dataLen) {
  26. //stFrameInfo的类型见DETAIL_FRAME_INFO
  27. let stFrameInfo = Module._GetDetialFrameInfo();
  28. let nIsMp4Index = stFrameInfo.nIsMp4Index;
  29. //console.log("FrameType is " , stFrameInfo);
  30. //console.log("nIsMp4Index is " + nIsMp4Index);
  31. //debugger
  32. var pData = null;
  33. pData = new Uint8Array(dataLen);
  34. pData.set(Module.HEAPU8.subarray(data, data + dataLen));
  35. if (dataType === 1) {
  36. postMessage({ type: "outputData",
  37. buf: pData.buffer,
  38. dType: 1,
  39. frameInfo: stFrameInfo }, [pData.buffer]);
  40. dataType = 2;
  41. } else {
  42. if (nIsMp4Index) {
  43. postMessage({ type: "outputData",
  44. buf: pData.buffer,
  45. dType: 6,
  46. frameInfo: stFrameInfo }, [pData.buffer]); //6:索引类型
  47. } else {
  48. postMessage({ type: "outputData",
  49. buf: pData.buffer,
  50. dType: 2,
  51. frameInfo: stFrameInfo }, [pData.buffer]); //2:码流
  52. }
  53. }
  54. //stFrameInfo的类型见DETAIL_FRAME_INFO
  55. //let stFrameInfo = Module._GetDetialFrameInfo();
  56. //let stFrameType = stFrameInfo.nFrameType;
  57. //let nFrameNum = stFrameInfo.nFrameNum;
  58. //let nTimeStamp = stFrameInfo.nTimeStamp;
  59. //let nIsMp4Index = stFrameInfo.nIsMp4Index;
  60. //console.log("FrameType is " + stFrameType);
  61. //console.log("nIsMp4Index is " + nIsMp4Index);
  62. };
  63. // self.Module = { memoryInitializerRequest: loadMemInitFile(), TOTAL_MEMORY: 128*1024*1024 };
  64. // importScripts('SystemTransform.js');
  65. self.Module['onRuntimeInitialized'] = function () {
  66. postMessage({type: "loaded"});
  67. };
  68. onmessage = function (e) {
  69. var data = e.data;
  70. if ("create" === data.type) {
  71. if (RECORDRTP) {
  72. postMessage({ type: "created" });
  73. postMessage({ type: "outputData",
  74. buf: data.buf,
  75. dType: 1 }, [data.buf]);
  76. } else {
  77. var iHeadLen = data.len;
  78. var pHead = Module._malloc(iHeadLen);
  79. if (pHead === null) {
  80. console.log("inputdata malloc failed!!!");
  81. return -1;
  82. }
  83. var iTransType = data.packType;//目标格式
  84. var iRet = 0;
  85. var buf = new Uint8Array(data.buf);
  86. //PS流(只有ps支持探测),并且编码格式异常(正常是265和264,11位和10位 不可能全是0,全0 并且是ps就探测策略)的情况下,使用探测策略
  87. if (buf[9] === 0 && buf[8] === 2 && buf[11] === 0 && buf[10] === 0) {
  88. iRet = Module._CreatHandle(0, iTransType, iHeadLen); //用探测的策略
  89. } else {
  90. self.writeArrayToMemory(buf, pHead);
  91. iRet = Module._CreatHandle(pHead, iTransType, iHeadLen);
  92. //-2147483645代表的是参数错误,此种情况,大概率发生在头信息错误,例如大华设备的情况,此时用 无头探测的策略
  93. //其他情况 按海康标准处理流程,不要做任何特殊处理
  94. if (iRet == -2147483645) {
  95. iRet = Module._CreatHandle(0, iTransType, iHeadLen); //失败了,用探测的策略再试一次
  96. }
  97. }
  98. if (iRet != 0) {
  99. if (iRet == -2147483647) {
  100. postMessage({ type: "outputData",
  101. dType: 1501 }); //标记为格式不支持
  102. } else {
  103. postMessage({ type: "outputData",
  104. dType: 1501 }); //转封装创建失败,也同样提示码流格式不支持,如果后续要细化再区分
  105. }
  106. console.log("_CreatHandle failed!" + iRet);
  107. } else {
  108. if (data.options && typeof data.options.pKeyData !== "undefined" && data.options.pKeyData !== null) {
  109. if ((2 === iTransType && "" === data.options.pKeyData)) {
  110. //转ps的时候,如果密码是空是允许的,即使码流加密了,导出加密后的码流就行
  111. //此时不要设置密码否则反而会提示密码错误
  112. } else {
  113. var secretInfo = data.options;
  114. var keyLen = secretInfo.nKeyLen;
  115. var pKeyData = Module._malloc(keyLen);
  116. if (pKeyData === null) {
  117. console.log("setEncryptKey malloc failed!!!");
  118. return -1;
  119. }
  120. var nKeySize = secretInfo.pKeyData.length;
  121. var bufData = stringToBytes(secretInfo.pKeyData);
  122. let inputData = new Uint8Array(bufData);
  123. Module.writeArrayToMemory(inputData, pKeyData);
  124. inputData = null;
  125. iRet = Module._SysTransSetEncryptKey(secretInfo.nKeyType, pKeyData, keyLen, nKeySize);
  126. if (iRet != 0) {
  127. console.log("_SysTransSetEncryptKey failed!");
  128. }
  129. if (pKeyData != null) {
  130. Module._free(pKeyData);
  131. pKeyData = null;
  132. }
  133. }
  134. }
  135. //带samplingParam参数,代表需要 用到 音频替换功能
  136. if (data.options && typeof data.options.samplingParam !== "undefined") {
  137. var oParam = data.options.samplingParam;
  138. var nCapacityType = 1; //写死1 代表 剔除音频
  139. var nType = 3; //写死3 代表 修改输出目标的海康头配置,内部包含视频参数、音频参数
  140. var nAudioEnable = 1; //音频参数修改使能开关,0=不启用,1=启用
  141. var nAudioFormat = oParam.iAudioType; //音频编码类型 对应关系参考海康媒体头规范,PCM 0x7001 G711_U 0x7110 G711_A 0x7111 AAC 0x2001
  142. var nAudioChannels = oParam.iChannel; //音频通道数直接设置为
  143. var nAudioBitsPerSample = oParam.iAudioBitWidth; //音频位样率
  144. var nAudioSamplesrate = oParam.iAudioSamplingRate; //音频采样率
  145. var nAudioBitrate = oParam.iAudioBitRate; //音频比特率
  146. iRet = Module._SysTransConfig(nCapacityType, nType, nAudioEnable, nAudioFormat,
  147. nAudioChannels, nAudioBitsPerSample, nAudioSamplesrate, nAudioBitrate);
  148. if (iRet != 0) {
  149. console.log("_SysTransConfig Failed:" + iRet);
  150. }
  151. } else {
  152. iRet = Module._SysTransConfig(128, 0, 0, 0, 0, 0, 0, 0); //nCapacityType = 0x00000080 代表开启私有信息回调 解决转mp4后,私有信息丢失问题
  153. if (iRet != 0) {
  154. console.log("_SysTransConfig Failed:" + iRet);
  155. }
  156. }
  157. iRet = Module._SysTransRegisterDataCallBack();
  158. if (iRet != 0) {
  159. console.log("_SysTransRegisterDataCallBack Failed:" + iRet);
  160. }
  161. iRet = Module._SysTransStart(null, null);
  162. if (iRet != 0) {
  163. console.log("_SysTransStart Failed:" + iRet);
  164. }
  165. postMessage({type: "created"});
  166. }
  167. if (pHead != null) {
  168. Module._free(pHead);
  169. pHead = null;
  170. }
  171. }
  172. } else if ("inputData" === data.type) {
  173. if (RECORDRTP) {
  174. var aFileData = new Uint8Array(data.buf); // 拷贝一份
  175. var iBufferLen = aFileData.length;
  176. var szBufferLen = iBufferLen.toString(16);
  177. if (szBufferLen.length === 1) {
  178. szBufferLen = "000" + szBufferLen;
  179. } else if (szBufferLen.length === 2) {
  180. szBufferLen = "00" + szBufferLen;
  181. } else if (szBufferLen.length === 3) {
  182. szBufferLen = "0" + szBufferLen;
  183. }
  184. var aData = [0, 0, parseInt(szBufferLen.substring(0, 2), 16), parseInt(szBufferLen.substring(2, 4), 16)];
  185. for (var iIndex = 0, iDataLength = aFileData.length; iIndex < iDataLength; iIndex++) {
  186. aData[iIndex + 4] = aFileData[iIndex];
  187. }
  188. var dataUint8 = new Uint8Array(aData);
  189. postMessage({type: "outputData",
  190. buf: dataUint8.buffer,
  191. dType: 2});
  192. } else {
  193. let inputMode = 0; //代表输入原始数据
  194. if (data.samplingParam) {
  195. iRet = Module._SysTransInputAudioPara(5, data.samplingParam.iChannel, data.samplingParam.iAudioBitWidth,
  196. data.samplingParam.iAudioSamplingRate, data.samplingParam.iTimeStamp, data.samplingParam.iAudioBitRate); //参数含义和_SysTransConfig类似
  197. if (iRet != 0) {
  198. console.log("_SysTransInputAudioPara Failed:" + iRet);
  199. }
  200. inputMode = 2; //输入替换的音频
  201. }
  202. var pInputDataBuf = Module._malloc(data.len);
  203. var idataLen = data.len;
  204. self.writeArrayToMemory(new Uint8Array(data.buf), pInputDataBuf);
  205. // 输入数据,每次最多2m
  206. let pp = Module._SysTransInputData(inputMode, pInputDataBuf, idataLen);
  207. if (pp == -2147483627) {
  208. //-2147483627 对应十六进制的80000015
  209. postMessage({ type: "outputData",
  210. dType: 1500 }); //标记为密码错误
  211. } else if (pp == -2147483647) {
  212. postMessage({ type: "outputData",
  213. dType: 1501 }); //标记为格式不支持
  214. } else if (pp != 0) {
  215. console.log("InputData Failed:" + pp);
  216. }
  217. Module._free(pInputDataBuf);
  218. }
  219. } else if ("release" === data.type) {
  220. var iRet = Module._SysTransStop();
  221. if (iRet != 0) {
  222. console.log("_SysTransStop failed!");
  223. }
  224. Module._SysTransRelease();
  225. if (iRet != 0) {
  226. console.log("_SysTransRelease failed!");
  227. }
  228. close();
  229. }
  230. };