mn-video-player-v2 1.4.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,2 @@
1
+ (function(){"use strict";const d=self.name==="em-pthread";d||(globalThis.Module={onRuntimeInitialized:function(){u(),f()},printErr:function(r){r&&/profile bitstream/.test(r)||console.error(r)}}),self.importScripts("./mn-common-c.js"),self.importScripts("./mn-media.js");class c{constructor(){this.ws="ws",this.host="",this.port=0,this.deviceType="",this.phone="",this.channel=0,this.messageId=0,this.mediaType=0,this.streamType=0,this.beginTime="",this.playbackMode=0,this.ctrlSendTime0=0,this.ctrlSendTime1=0,this.netSpeedTimer=null,this.realPlayTimer=null,this.playBackTimer=null,this.lang=null,this.playAudio=!1,this.coreLogLevel=0,this.cacheReqQue=[],this.cacheDataQue=[],this.recorderLen=0,this.decoding=!0,this.wasmLoaded=!1,this.hasConnected=!1,this.hasInited=!1,this.hasCached=!1,this.decoderInited=!1,this.chunkSize=1024*1024,this.websocket=null,this.cacheBuffer=null,this.speakBuffer=null,this.readyCallback=null,this.videoCallback=null,this.audioCallback=null,this.preTimeStamp=0,this.pauseTime=0,this.resumeTime=0,this.delayTime=1e3,this.keyFrame=null,this.netSpeedTime=1,this.netSpeedSize=0,this.heartBeatTime=0,this.fastForward=!1,this.voiceScheduling=!1,this.prefix="/mndp/stream",this.logger=new Logger("MnWorker"),this.userId=null,this.tenantId=null,this.token=null,this.speed=0,this.isPause=!1,this.speedValue=1,this.isStreamPause=!1,this.streamPauseTime=0,this.playMode=0,this.voiceTimeStamp=0,this.offsetTime=0,this.offsetDelay=0,this.isCacheLow=!1,this.isFirstLoaded=!1,this.checkCacheTimer=null}offset(e){if(this.speed>2||(this.offsetDelay=0,!e))return;this.offsetTime=parseInt(e);let t=!1;if(this.offsetTime>0?t=!1:t=!0,Math.abs(this.offsetTime)>2e3){this.offsetDelay=t?200:-200;return}if(Math.abs(this.offsetTime)>1e3){this.offsetDelay=t?100:-100;return}if(Math.abs(this.offsetTime)>200){this.offsetDelay=t?10:-10;return}}baseInit(){this.cacheBuffer=Module._malloc(this.chunkSize),this.speakBuffer=Module._malloc(1024);let e=Module._malloc(16);self.HEAPU8.set(this.toInt8Array(this.phone),e);let t=Module._baseInit(e,this.channel,this.readyCallback,this.videoCallback,this.audioCallback,this.speakCallback,this.coreLogLevel);e&&Module._free(e);let s={t:kOpenDecoderRsp,e:t};self.postMessage(s)}baseUnInit(){let e=0;Module._videoUnInit(),Module._baseUnInit(),this.cacheBuffer!=null&&(Module._free(this.cacheBuffer),this.cacheBuffer=null),this.speakBuffer!=null&&(Module._free(this.speakBuffer),this.speakBuffer=null),this.decoderInited=!1;let t={t:kCloseDecoderRsp,e};self.postMessage(t)}calNetSpeed(){const e=this.netSpeedSize/this.netSpeedTime,t=this.cacheDataQue.length;this.netSpeedSize=0;let s={t:kNetSpeedFrame,d:e,len:t};if(self.postMessage(s),this.heartBeatTime+=this.netSpeedTime,this.websocket!=null&&this.hasConnected&&this.heartBeatTime%(this.netSpeedTime*10)==0){let i={};i.phone=this.phone,i.channel=this.channel,i.messageId=0;let a=JSON.stringify(i);this.websocket.send(a)}}uuid(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(e){const t=Math.random()*16|0;return(e==="x"?t:t&3|8).toString(16)})}openStream(){const e=this.uuid();let t=this.ws+"://"+this.host+":"+this.port+this.prefix+"/"+this.phone+"-"+this.channel+`?user_id=${this.userId}&tenant_id=${this.tenantId}&access_token=${this.token}&host_uuid=${e}`;this.websocket=new WebSocket(t),this.websocket.binaryType="arraybuffer",this.websocket.onopen=function(){self.decoder.onOpen()},this.websocket.onmessage=function(s){if(typeof s.data=="string"){let i={t:kStringFrame,d:s.data};self.postMessage(i)}else self.decoder.sendData(s.data)},this.websocket.onerror=function(){let s="1连接视频服务器失败";switch(self.decoder.lang){case"zh-CN,zh;":s="1连接视频服务器失败";break;case"zh-TW,zh;":s="1連接視訊伺服器失敗";break;case"en-US,en;":s="1Failed to connect to video server";break;case"ru-RU,ru;":s="1Ошибка подключения к видео серверу";break;case"kk-KZ,kk;":s="1Видео серверіне қосылу жаңылысы";break}let i={t:kSocketErrorRsp,d:s};self.postMessage(i),self.decoder.websocket.close(),self.decoder.websocket=null},this.websocket.onclose=function(){self.decoder.stopCheckCache();let s="1网络连接断开,请稍候再试";switch(self.decoder.lang){case"zh-CN,zh;":s="1网络连接断开,请稍候再试";break;case"zh-TW,zh;":s="1網絡連接斷開,請稍候再試";break;case"en-US,en;":s="1Disconnected, please try again later";break;case"ru-RU,ru;":s="1Соединение прервано, повторите попытку позже.";break;case"kk-KZ,kk;":s="1Байланыс ажыратылды, әрекетті кейінірек қайталаңыз.";break;case"th-TH,th;":s="การเชื่อมต่อถูกตัดการเชื่อมต่อ โปรดลองอีกครั้งในภายหลัง";break}let i={t:kSocketCloseRsp,d:s};self.decoder.serverError!=""&&(i.d=self.decoder.serverError),self.decoder.websocket=null,self.decoder.hasConnected=!1,self.decoder.mnWorker=null,self.postMessage(i),this.websocket=null}}switchStream(e,t){if(this.websocket!=null&&this.hasConnected){let s={};s.phone=this.phone,s.channel=this.channel,s.messageId=37122,s.command=1,s.closeType=0,e!=null&&(s.mediaType=e,this.mediaType=e),t!=null&&(s.streamType=t,this.streamType=t);let i=JSON.stringify(s);this.websocket.send(i)}else this.logger.logInfo("Web socket is null or not connected.")}play(){if(this.websocket==null){this.logger.logInfo("Web socket is null");return}let e={};e.phone=this.phone,e.channel=this.channel,e.messageId=this.messageId,e.mediaType=this.mediaType,e.streamType=this.streamType,e.beginTime=this.beginTime,this.playMode=this.beginTime?1:0,e.acceptLanguage=this.lang,e.ws=this.ws,e.host=this.host,e.port=this.port,e.deviceType=this.deviceType;let t=JSON.stringify(e);this.websocket.send(t)}onOpen(){this.baseInit(),this.resume(),this.startCheckCache(),this.play(),this.hasConnected=!0,this.mediaType!==kMediaSpeak&&(this.netSpeedTimer=setInterval(this.calNetSpeed.bind(this),this.netSpeedTime*1e3))}resume(){this.isPause=!1,this.mediaType!==kMediaSpeak&&this.beginTime&&this.playBack(),this.decoding=!0}pause(){this.isPause=!0,this.beginTime?(this.pauseTime=new Date().getTime(),clearTimeout(this.playBackTimer)):(this.decoding=!1,clearTimeout(this.realPlayTimer),this.realPlayTimer=null,this.cacheReqQue.length=0,this.hasInited=!1,this.hasCached=!1)}realPlay(e,t,s){if(this.hasInited==!1)if(this.renderMode==1){if(e){const i=this.timeStamp(e);let a="",h=e.length-16;for(let o=0;o<16;o++)a+=String.fromCharCode(e[h+o]);let n=Number(a.substr(13,1)),l=!1;n==0&&(l=!0),self.postMessage({t:kVideoFrameOriginRsp,ti:i,isKey:l,d:e})}}else{if(!this.decoderInited){let i=kDecoderH264;s==99&&(i=kDecoderH265),Module._videoInit(i),this.decoderInited=!0}t==0&&(this.hasInited=!0)}this.decoding&&this.hasInited&&(self.HEAPU8.set(e,this.cacheBuffer),Module._decodeVideo(this.cacheBuffer,e.length-16),this.preTimeStamp=this.timeStamp(e))}startCheckCache(){setInterval(()=>{clearInterval(this.checkCacheTimer),this.checkCacheAndCtrl(),this.ctrlSendTime0=0,this.ctrlSendTime1=0},3e3)}stopCheckCache(){clearInterval(this.checkCacheTimer)}async playBack(){try{if(clearTimeout(this.playBackTimer),this.isPause)return;do{if(this.checkCacheAndCtrl(),this.cacheDataQue.length==0)break;if(this.hasInited===!1&&this.renderMode==0){let i=this.cacheDataQue.shift(),a="",h=i.length-16;for(let l=0;l<16;l++)a+=String.fromCharCode(i[h+l]);if(this.preTimeStamp=Number(a.substr(0,13)),!this.decoderInited){let l=kDecoderH264;a.substr(14)==99&&(l=kDecoderH265),Module._videoInit(l),this.decoderInited=!0}let n=Number(a.substr(13,1));this.decoding&&n==0&&(self.HEAPU8.set(i,this.cacheBuffer),Module._decodeVideo(this.cacheBuffer,h),this.hasInited=!0);break}let t=this.cacheDataQue.shift(),s=this.timeStamp(t);if(this.renderMode==1){let i=t,a="",h=i.length-16;for(let o=0;o<16;o++)a+=String.fromCharCode(i[h+o]);let n=Number(a.substr(13,1)),l=!1;n==0&&(l=!0),self.postMessage({t:kVideoFrameOriginRsp,ti:this.timeStamp(i),isKey:l,d:i})}else this.decoding&&(self.HEAPU8.set(t,this.cacheBuffer),Module._decodeVideo(this.cacheBuffer,t.length-16));this.preTimeStamp=s}while(!1);this.playBackTimer=setTimeout(this.playBack.bind(this),4)}catch{this.playBackTimer=setTimeout(this.playBack.bind(this),4)}}dateFormat(e,t){let s;const i={"Y+":t.getFullYear().toString(),"m+":(t.getMonth()+1).toString(),"d+":t.getDate().toString(),"H+":t.getHours().toString(),"M+":t.getMinutes().toString(),"S+":t.getSeconds().toString()};for(let a in i)s=new RegExp("("+a+")").exec(e),s&&(e=e.replace(s[1],s[1].length==1?i[a]:i[a].padStart(s[1].length,"0")));return e}playBackCtrl(e){if(new Date().getTime()-this.streamPauseTime<1e3)return;if(this.streamPauseTime=new Date().getTime(),e){if(this.isStreamPause=!0,this.playbackMode==1&&(this.ctrlSendTime1++,this.ctrlSendTime1>2))return;this.ctrlSendTime0=0,this.playbackMode=1}else{if(this.isStreamPause=!1,this.playbackMode==0&&(this.ctrlSendTime0++,this.ctrlSendTime0>2))return;this.ctrlSendTime1=0,this.playbackMode=0}let t={};t.phone=this.phone,t.channel=this.channel,t.messageId=37378,t.mediaType=this.mediaType,t.streamType=this.streamType,t.beginTime=this.beginTime,t.acceptLanguage=this.lang,t.playbackMode=this.playbackMode;let s=JSON.stringify(t);this.websocket!=null&&(this.websocket.readyState===this.websocket.OPEN?this.websocket.send(s):this.websocket=null)}timeStamp(e){let t="",s=e.length-16;for(let i=0;i<16;i++)t+=String.fromCharCode(e[s+i]);return Number(t.substr(0,13))}frameIndex(){let e=-1;for(let t=0;t<this.cacheDataQue.length;t++){let s=this.cacheDataQue[t],i=s.length-16;s[i+13]==48&&(e=t)}return e}enableAudio(e){this.playAudio=e}closeStream(){this.pause(),this.websocket!=null&&(this.websocket.onmessage=null,this.websocket.onerror=null,this.websocket.onopen=null,this.websocket.close(),this.websocket=null),this.netSpeedTimer!=null&&(clearInterval(this.netSpeedTimer),this.netSpeedTimer=null),this.baseUnInit()}sendData(e){if(!this.decoding)return;let t=new Uint8Array(e);this.netSpeedSize+=t.length;let s="",i=t.length-16;for(let n=0;n<16;n++)s+=String.fromCharCode(t[i+n]);let a=Number(s.substr(13,1)),h=s.substr(14);if(t[0]==0&&t[1]==0&&t[2]==0&&t[3]==1&&(h==98||h==99))this.beginTime?(this.cacheDataQue.push(t),this.checkCacheAndCtrl()):this.realPlay(t,a,h);else if(!this.voiceScheduling){if(t.length<100)return;if(s.indexOf("306")>0){t=t.slice(0,-15),t[t.length-1]=6;const n=s.slice(0,13);if(this.voiceTimeStamp!==0&&Math.abs(n-this.voiceTimeStamp)>1e3){let l={t:kFlushAudio,d:this.voiceTimeStamp};self.postMessage(l)}this.voiceTimeStamp=n}self.HEAPU8.set(t,this.cacheBuffer),Module._decodeAudio(this.cacheBuffer,t.length-1,t[t.length-1])}}checkCacheAndCtrl(){if(this.playMode==0)return;let e=10,t=30;this.playbackMode==6&&(e=1,t=5);let s=this.cacheDataQue.length;if(s==0&&!this.isFirstLoaded){this.isCacheLow=!0;let i={t:kNoCache,len:s};self.postMessage(i)}if(s>0&&!this.isFirstLoaded){this.isFirstLoaded=!0,this.isCacheLow=!1;let i={t:kCacheAvailable,len:s};self.postMessage(i)}if(this.isCacheLow&&s>=e*10){this.isCacheLow=!1;let i={t:kCacheAvailable,len:s};self.postMessage(i)}s<e*25?this.playBackCtrl(!1):s>t*25&&this.playBackCtrl(!0)}processReq(e){switch(e.t){case kVideoAudioOffset:this.offset(e.data);break;case kOpenDecoderReq:this.ws=e.ws,this.host=e.host,this.port=e.port,this.phone=e.phone,this.userId=e.userId,this.tenantId=e.tenantId,this.token=e.token,this.channel=e.channel,this.lang=e.lang,this.deviceType=e.deviceType,this.renderMode=e.renderMode;break;case kChangeRenderTypeReq:this.renderMode=e.renderMode;break;case kResumeDecodingReq:this.resume();break;case kPauseDecodingReq:this.pause();break;case kOpenStreamReq:this.messageId=e.messageId,this.mediaType=e.mediaType,this.streamType=e.streamType,this.beginTime=e.beginTime,this.lang=e.lang,this.openStream();break;case kEnableAudioReq:this.enableAudio(e.d);break;case kSwitchStreamReq:this.switchStream(e.m,e.s);break;case kRecorderSpeakReq:this.voiceScheduling=!0,this.encodeAudio(e.d);break;case kRecorderTalkReq:this.voiceScheduling=!1,this.encodeAudio(e.d);break;case kCloseStreamReq:this.closeStream();break;case kFastForward:this.fastForward=e.d;break;case kReplayReq:this.play();break;case kReplaySpeedReq:let t=this.beginTime;if(this.playbackMode=e.playbackMode,e.time)t=e.time;else if(this.preTimeStamp){let s=new Date(this.preTimeStamp);t=`${s.getUTCFullYear()}-${(s.getUTCMonth()+1).toString().padStart(2,"0")}-${s.getUTCDate().toString().padStart(2,"0")} ${s.getUTCHours().toString().padStart(2,"0")}:${s.getUTCMinutes().toString().padStart(2,"0")}:${s.getUTCSeconds().toString().padStart(2,"0")}`}this.websocket.send(JSON.stringify({playbackSpeed:e.d,messageId:37378,channel:this.channel,phone:this.phone,deviceType:this.deviceType,streamType:this.streamType,mediaType:this.mediaType,host:this.host,hostUuid:this.host_uuid,port:this.port,ws:this.ws,beginTime:t,acceptLanguage:this.lang,playbackMode:this.playbackMode})),this.speed=e.v,this.speedValue=e.d;break;default:this.logger.logError("Unsupport messsage "+e.t)}}encodeAudio(e){this.websocket!=null&&(self.HEAP8.set(e,this.speakBuffer),Module._encodeAudio(this.speakBuffer,e.length,this.deviceType=="6"?6:26))}toInt8Array(e){let t=[];for(let s=0;s<e.length;s++)t.push(e.charCodeAt(s));return new Int8Array(t)}cacheReq(e){e&&this.cacheReqQue.push(e)}onWasmLoaded(){this.wasmLoaded=!0,this.readyCallback=Module.addFunction(function(t,s){let i={t:kVideoReady,w:t,h:s};self.postMessage(i)},"vii");let e=this;for(this.videoCallback=Module.addFunction(function(t,s){let i=self.HEAPU8.subarray(Number(t),Number(t)+s),a=new Uint8Array(i),h={t:kVideoFrame,d:a,ti:e.preTimeStamp};self.postMessage(h,[h.d.buffer])},"vji"),this.audioCallback=Module.addFunction(function(t,s){let i=self.HEAPU8.subarray(Number(t),Number(t)+s),a=new Uint8Array(i),h={t:kAudioFrame,d:a,ti:e.voiceTimeStamp};self.postMessage(h,[h.d.buffer])},"vji"),this.speakCallback=Module.addFunction(function(t,s){let i=self.HEAPU8.subarray(Number(t),Number(t)+s),a=new Int8Array(i);self.decoder.websocket!==null&&self.decoder.websocket.readyState===self.decoder.websocket.OPEN&&self.decoder.websocket.send(a)},"vji");this.cacheReqQue.length>0;){let t=this.cacheReqQue.shift();this.processReq(t)}}}d||(self.decoder=new c,self.onmessage=function(r){if(!self.decoder)return;let e=r.data;if(!self.decoder.wasmLoaded){self.decoder.cacheReq(e);return}self.decoder.processReq(e)});function u(){const r=Module._baseInit,e=Module._decodeVideo,t=Module._decodeAudio,s=Module._encodeAudio;Module._baseInit=(i,a,h,n,l,o,p)=>r(BigInt(i),a,BigInt(h),BigInt(n),BigInt(l),BigInt(o),p),Module._decodeVideo=(i,a)=>e(BigInt(i),BigInt(a)),Module._decodeAudio=(i,a,h)=>t(BigInt(i),BigInt(a),h),Module._encodeAudio=(i,a,h)=>s(BigInt(i),BigInt(a),h)}function f(){self.decoder&&self.decoder.onWasmLoaded()}})();
2
+ //# sourceMappingURL=mn-worker-CW3JpGn0.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mn-worker-CW3JpGn0.js","sources":["src/js/mn-worker.js"],"sourcesContent":["// classic 模式:依赖(mn-common-c.js / mn-media.js / mn-media.wasm)需与 worker 脚本同目录部署\r\n// 新版 Emscripten 不再支持 mainScriptUrlOrBlob:pthread worker 直接以当前 worker 脚本 URL\r\n// (即本文件)创建,因此本文件会在 em-pthread 子线程里再次执行。\r\n// 子线程只负责解码,绝不能接管消息处理,否则会覆盖 mn-media.js 安装的 handleMessage,\r\n// 导致主线程等待 \"loaded\"(cmd 3)握手永远不返回、worker 一直加载中。\r\nconst isPthreadWorker = self.name === \"em-pthread\";\r\nif (!isPthreadWorker) {\r\n globalThis.Module = {\r\n onRuntimeInitialized: function () {\r\n // memory64 构建:SDK 导出未被胶水包装,先补 BigInt 转换再对外可用\r\n wrapSdkBigIntExports();\r\n onWasmLoaded();\r\n },\r\n // 过滤 wasm 内 FFmpeg 的良性日志(AV_LOG_WARNING,不影响解码):\r\n // \"[hevc @ 0x...] Unknown profile bitstream\"\r\n // FFmpeg 7.x hevc/ps.c 在 SPS 的 general_profile_idc 不在 {Main,Main10,Main Still,RExt} 时打印,\r\n // 属常见设备码流(如用 compatibility_flag 声明 Main 的流),解码会继续,仅控制台噪音。\r\n // pthread worker 的 stderr 会代理回主线程的 printErr,统一在这里过滤。\r\n printErr: function (msg) {\r\n if (msg && /profile bitstream/.test(msg)) {\r\n return; // 丢弃已知良性警告\r\n }\r\n console.error(msg);\r\n },\r\n };\r\n}\r\n\r\nself.importScripts(\"./mn-common-c.js\");\r\nself.importScripts(\"./mn-media.js\"); // 加载wasm视频解码器 直接作为JS运行\r\n/**\r\n * @description: web worker用于流媒体获取(websocket)及编(音频)、解码(音视频)、对讲\r\n * @author: lantf\r\n * @date: 2020/10/18 15:28\r\n */\r\n\r\nclass MnWorker {\r\n constructor() {\r\n this.ws = \"ws\";\r\n this.host = \"\";\r\n this.port = 0;\r\n this.deviceType = \"\";\r\n this.phone = \"\";\r\n this.channel = 0;\r\n this.messageId = 0;\r\n this.mediaType = 0;\r\n this.streamType = 0;\r\n this.beginTime = \"\";\r\n this.playbackMode = 0;\r\n this.ctrlSendTime0 = 0;\r\n this.ctrlSendTime1 = 0;\r\n this.netSpeedTimer = null;\r\n this.realPlayTimer = null;\r\n this.playBackTimer = null;\r\n this.lang = null;\r\n this.playAudio = false;\r\n this.coreLogLevel = 0;\r\n this.cacheReqQue = [];\r\n this.cacheDataQue = [];\r\n this.recorderLen = 0;\r\n this.decoding = true;\r\n this.wasmLoaded = false;\r\n this.hasConnected = false;\r\n this.hasInited = false;\r\n this.hasCached = false;\r\n this.decoderInited = false;\r\n this.chunkSize = 1024 * 1024;\r\n this.websocket = null;\r\n this.cacheBuffer = null;\r\n this.speakBuffer = null;\r\n this.readyCallback = null;\r\n this.videoCallback = null;\r\n this.audioCallback = null;\r\n this.preTimeStamp = 0;\r\n this.pauseTime = 0;\r\n this.resumeTime = 0;\r\n this.delayTime = 1000;\r\n this.keyFrame = null;\r\n this.netSpeedTime = 1;\r\n this.netSpeedSize = 0;\r\n this.heartBeatTime = 0;\r\n this.fastForward = false;\r\n this.voiceScheduling = false; // 语音调度\r\n this.prefix = \"/mndp/stream\";\r\n this.logger = new Logger(\"MnWorker\");\r\n this.userId = null;\r\n this.tenantId = null;\r\n this.token = null;\r\n // * 倍速 (0-无效,1-1倍,2-2倍,3-4倍,4-8倍,5-16倍)\r\n this.speed = 0;\r\n this.isPause = false;\r\n this.speedValue = 1;\r\n this.isStreamPause = false;\r\n this.streamPauseTime = 0;\r\n this.playMode = 0; // 0-实时 1-回放\r\n this.voiceTimeStamp = 0;\r\n this.offsetTime = 0;\r\n this.offsetDelay = 0;\r\n this.isCacheLow = false;\r\n this.isFirstLoaded = false;\r\n this.checkCacheTimer = null;\r\n }\r\n\r\n /* 偏移 */\r\n offset(time) {\r\n /* 如果是倍速则不比较 */\r\n if (this.speed > 2) {\r\n return;\r\n }\r\n this.offsetDelay = 0;\r\n if (!time) return;\r\n this.offsetTime = parseInt(time);\r\n let isVideoFast = false;\r\n if (this.offsetTime > 0) {\r\n /* 视频慢了减少等待时间 */\r\n isVideoFast = false;\r\n } else {\r\n /* 视频快了增加等待时间 */\r\n isVideoFast = true;\r\n }\r\n\r\n if (Math.abs(this.offsetTime) > 2000) {\r\n /* 超过2s需要处理 */\r\n /* 严重不同步 */\r\n // console.log(\"严重不同步!\", this.offsetTime);\r\n this.offsetDelay = isVideoFast ? +200 : -200;\r\n return;\r\n }\r\n if (Math.abs(this.offsetTime) > 1000) {\r\n /* 超过1s需要处理 */\r\n /* 稍微不同步 */\r\n // console.log(\"延迟\", this.offsetTime);\r\n this.offsetDelay = isVideoFast ? +100 : -100;\r\n return;\r\n }\r\n if (Math.abs(this.offsetTime) > 200) {\r\n /* 超过200ms需要处理 */\r\n /* 稍微不同步 */\r\n // console.log(\"延迟\", this.offsetTime);\r\n this.offsetDelay = isVideoFast ? +10 : -10;\r\n return;\r\n }\r\n }\r\n\r\n /**\r\n * 打开解码器\r\n **/\r\n baseInit() {\r\n this.cacheBuffer = Module._malloc(this.chunkSize);\r\n this.speakBuffer = Module._malloc(1024);\r\n let phoneBuffer = Module._malloc(16);\r\n self.HEAPU8.set(this.toInt8Array(this.phone), phoneBuffer);\r\n let ret = Module._baseInit(\r\n phoneBuffer,\r\n this.channel,\r\n this.readyCallback,\r\n this.videoCallback,\r\n this.audioCallback,\r\n this.speakCallback,\r\n this.coreLogLevel,\r\n );\r\n if (phoneBuffer) {\r\n Module._free(phoneBuffer);\r\n }\r\n\r\n let objData = {\r\n t: kOpenDecoderRsp,\r\n e: ret,\r\n };\r\n self.postMessage(objData);\r\n }\r\n\r\n /**\r\n * 关闭解码器\r\n **/\r\n baseUnInit() {\r\n let ret = 0;\r\n Module._videoUnInit();\r\n Module._baseUnInit();\r\n\r\n if (this.cacheBuffer != null) {\r\n Module._free(this.cacheBuffer);\r\n this.cacheBuffer = null;\r\n }\r\n if (this.speakBuffer != null) {\r\n Module._free(this.speakBuffer);\r\n this.speakBuffer = null;\r\n }\r\n\r\n this.decoderInited = false;\r\n\r\n let objData = {\r\n t: kCloseDecoderRsp,\r\n e: ret,\r\n };\r\n self.postMessage(objData);\r\n }\r\n\r\n /**\r\n * 统计流量\r\n **/\r\n calNetSpeed() {\r\n const speed = this.netSpeedSize / this.netSpeedTime;\r\n const len = this.cacheDataQue.length;\r\n this.netSpeedSize = 0;\r\n let objData = {\r\n t: kNetSpeedFrame,\r\n d: speed,\r\n len,\r\n };\r\n self.postMessage(objData);\r\n\r\n // 心跳(this.netSpeedTime的10倍秒数)\r\n this.heartBeatTime += this.netSpeedTime;\r\n if (this.websocket != null && this.hasConnected) {\r\n if (this.heartBeatTime % (this.netSpeedTime * 10) == 0) {\r\n let req = {};\r\n req.phone = this.phone;\r\n req.channel = this.channel;\r\n req.messageId = 0x0000;\r\n let json = JSON.stringify(req);\r\n this.websocket.send(json);\r\n }\r\n }\r\n }\r\n uuid() {\r\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(\r\n /[xy]/g,\r\n function (c) {\r\n const r = (Math.random() * 16) | 0;\r\n const v = c === \"x\" ? r : (r & 0x3) | 0x8;\r\n return v.toString(16);\r\n },\r\n );\r\n }\r\n /**\r\n * 打开websocket码流链路\r\n **/\r\n openStream() {\r\n const uid = this.uuid();\r\n let url =\r\n this.ws +\r\n \"://\" +\r\n this.host +\r\n \":\" +\r\n this.port +\r\n this.prefix +\r\n \"/\" +\r\n this.phone +\r\n \"-\" +\r\n this.channel +\r\n `?user_id=${this.userId}&tenant_id=${this.tenantId}&access_token=${this.token}&host_uuid=${uid}`;\r\n this.websocket = new WebSocket(url);\r\n this.websocket.binaryType = \"arraybuffer\";\r\n\r\n this.websocket.onopen = function () {\r\n self.decoder.onOpen();\r\n };\r\n\r\n this.websocket.onmessage = function (ev) {\r\n if (typeof ev.data === \"string\") {\r\n let objData = {\r\n t: kStringFrame,\r\n d: ev.data,\r\n };\r\n self.postMessage(objData);\r\n } else {\r\n self.decoder.sendData(ev.data);\r\n }\r\n };\r\n\r\n this.websocket.onerror = function () {\r\n let message = \"1连接视频服务器失败\";\r\n switch (self.decoder.lang) {\r\n case \"zh-CN,zh;\":\r\n message = \"1连接视频服务器失败\";\r\n break;\r\n case \"zh-TW,zh;\":\r\n message = \"1連接視訊伺服器失敗\";\r\n break;\r\n case \"en-US,en;\":\r\n message = \"1Failed to connect to video server\";\r\n break;\r\n case \"ru-RU,ru;\":\r\n message = \"1Ошибка подключения к видео серверу\";\r\n break;\r\n case \"kk-KZ,kk;\":\r\n message = \"1Видео серверіне қосылу жаңылысы\";\r\n break;\r\n }\r\n let objData = {\r\n t: kSocketErrorRsp,\r\n d: message,\r\n };\r\n self.postMessage(objData);\r\n // 注意:此处 this 指向 WebSocket 自身,须通过 self.decoder 操作\r\n self.decoder.websocket.close();\r\n self.decoder.websocket = null;\r\n };\r\n\r\n this.websocket.onclose = function () {\r\n self.decoder.stopCheckCache();\r\n let message = \"1网络连接断开,请稍候再试\";\r\n\r\n switch (self.decoder.lang) {\r\n case \"zh-CN,zh;\":\r\n message = \"1网络连接断开,请稍候再试\";\r\n break;\r\n case \"zh-TW,zh;\":\r\n message = \"1網絡連接斷開,請稍候再試\";\r\n break;\r\n case \"en-US,en;\":\r\n message = \"1Disconnected, please try again later\";\r\n break;\r\n case \"ru-RU,ru;\":\r\n message = \"1Соединение прервано, повторите попытку позже.\";\r\n break;\r\n case \"kk-KZ,kk;\":\r\n message = \"1Байланыс ажыратылды, әрекетті кейінірек қайталаңыз.\";\r\n break;\r\n case \"th-TH,th;\":\r\n message = \"การเชื่อมต่อถูกตัดการเชื่อมต่อ โปรดลองอีกครั้งในภายหลัง\";\r\n break;\r\n }\r\n let objData = {\r\n t: kSocketCloseRsp,\r\n d: message,\r\n };\r\n if (self.decoder.serverError != \"\") {\r\n // 用后端返回的提示(若有)\r\n objData.d = self.decoder.serverError;\r\n }\r\n self.decoder.websocket = null;\r\n self.decoder.hasConnected = false;\r\n self.decoder.mnWorker = null;\r\n self.postMessage(objData);\r\n this.websocket = null;\r\n };\r\n }\r\n\r\n /**\r\n * 切换码流\r\n **/\r\n switchStream(mediaType, streamType) {\r\n if (this.websocket != null && this.hasConnected) {\r\n let req = {};\r\n req.phone = this.phone;\r\n req.channel = this.channel;\r\n req.messageId = 0x9102;\r\n req.command = 1;\r\n req.closeType = 0;\r\n\r\n if (mediaType != null) {\r\n req.mediaType = mediaType;\r\n this.mediaType = mediaType;\r\n }\r\n\r\n if (streamType != null) {\r\n req.streamType = streamType;\r\n this.streamType = streamType;\r\n }\r\n\r\n let json = JSON.stringify(req);\r\n this.websocket.send(json);\r\n } else {\r\n this.logger.logInfo(\"Web socket is null or not connected.\");\r\n }\r\n }\r\n\r\n /**\r\n * 发送制命令\r\n **/\r\n play() {\r\n if (this.websocket == null) {\r\n this.logger.logInfo(\"Web socket is null\");\r\n return;\r\n }\r\n let req = {};\r\n req.phone = this.phone;\r\n req.channel = this.channel;\r\n req.messageId = this.messageId;\r\n req.mediaType = this.mediaType;\r\n req.streamType = this.streamType;\r\n req.beginTime = this.beginTime;\r\n this.playMode = this.beginTime ? 1 : 0;\r\n req.acceptLanguage = this.lang;\r\n req.ws = this.ws;\r\n req.host = this.host;\r\n req.port = this.port;\r\n req.deviceType = this.deviceType;\r\n let json = JSON.stringify(req);\r\n this.websocket.send(json);\r\n }\r\n\r\n /**\r\n * ws建立后初始化\r\n **/\r\n onOpen() {\r\n this.baseInit();\r\n this.resume();\r\n this.startCheckCache();\r\n this.play();\r\n this.hasConnected = true;\r\n if (this.mediaType !== kMediaSpeak) {\r\n this.netSpeedTimer = setInterval(\r\n this.calNetSpeed.bind(this),\r\n this.netSpeedTime * 1000,\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * 恢复解码\r\n **/\r\n resume() {\r\n // console.log('resume解码')\r\n this.isPause = false;\r\n if (this.mediaType !== kMediaSpeak) {\r\n if (this.beginTime) {\r\n this.playBack();\r\n }\r\n }\r\n this.decoding = true;\r\n }\r\n\r\n /**\r\n * 暂停解码\r\n **/\r\n pause() {\r\n this.isPause = true;\r\n if (!this.beginTime) {\r\n this.decoding = false;\r\n clearTimeout(this.realPlayTimer);\r\n this.realPlayTimer = null;\r\n this.cacheReqQue.length = 0;\r\n this.hasInited = false;\r\n this.hasCached = false;\r\n } else {\r\n this.pauseTime = new Date().getTime();\r\n // console.log(\"暂停\");\r\n // this.decoding = false;\r\n clearTimeout(this.playBackTimer);\r\n }\r\n }\r\n\r\n realPlay(u8a, frameType, ptRaw) {\r\n if (this.hasInited == false) {\r\n // 获取编码类型,初始化视频解码器\r\n if (this.renderMode == 1) {\r\n if (u8a) {\r\n const ti = this.timeStamp(u8a);\r\n // console.log(\"收到帧时间\", ti);\r\n let dataString = \"\";\r\n let dataLen = u8a.length - 16;\r\n for (let i = 0; i < 16; i++) {\r\n dataString += String.fromCharCode(u8a[dataLen + i]);\r\n }\r\n let frameType = Number(dataString.substr(13, 1));\r\n let isKey = false;\r\n if (frameType == 0) {\r\n isKey = true;\r\n }\r\n self.postMessage({\r\n t: kVideoFrameOriginRsp,\r\n ti: ti,\r\n isKey: isKey,\r\n d: u8a,\r\n });\r\n }\r\n } else {\r\n if (!this.decoderInited) {\r\n let decoderType = kDecoderH264;\r\n if (ptRaw == 99) {\r\n decoderType = kDecoderH265;\r\n }\r\n Module._videoInit(decoderType);\r\n this.decoderInited = true;\r\n }\r\n // 获取帧类型,必须先出个I帧,否则丢弃\r\n if (frameType == 0) {\r\n this.hasInited = true;\r\n }\r\n }\r\n }\r\n\r\n if (this.decoding && this.hasInited) {\r\n self.HEAPU8.set(u8a, this.cacheBuffer);\r\n Module._decodeVideo(this.cacheBuffer, u8a.length - 16); // 同步解码,返回前回调已触发\r\n this.preTimeStamp = this.timeStamp(u8a);\r\n }\r\n }\r\n /* 检测缓存 */\r\n startCheckCache() {\r\n setInterval(() => {\r\n clearInterval(this.checkCacheTimer);\r\n this.checkCacheAndCtrl();\r\n this.ctrlSendTime0 = 0;\r\n this.ctrlSendTime1 = 0;\r\n }, 3000);\r\n }\r\n stopCheckCache() {\r\n clearInterval(this.checkCacheTimer);\r\n }\r\n /**\r\n * 回放视频解码\r\n * 时间控制统一交由主线程 mn-player 的 timerCtrl(实时/回放、wasm/webdecoder 一致),\r\n * 此处仅按缓存顺序取帧并解码/透传,不再做 sleep/跳帧等节奏控制\r\n **/\r\n async playBack() {\r\n try {\r\n clearTimeout(this.playBackTimer);\r\n if (this.isPause) return;\r\n\r\n do {\r\n this.checkCacheAndCtrl();\r\n let queLen = this.cacheDataQue.length;\r\n if (queLen == 0) {\r\n break;\r\n }\r\n // 首先渲染出I帧(wasm 模式需要先初始化解码器)\r\n if (this.hasInited === false && this.renderMode == 0) {\r\n let u8a = this.cacheDataQue.shift();\r\n\r\n // 取出帧尾16个字符\r\n let dataString = \"\";\r\n let dataLen = u8a.length - 16;\r\n for (let i = 0; i < 16; i++) {\r\n dataString += String.fromCharCode(u8a[dataLen + i]);\r\n }\r\n\r\n // 获取时间戳\r\n this.preTimeStamp = Number(dataString.substr(0, 13));\r\n // 获取编码类型,初始化视频解码器\r\n if (!this.decoderInited) {\r\n let decoderType = kDecoderH264;\r\n if (dataString.substr(14) == 99) {\r\n decoderType = kDecoderH265;\r\n }\r\n Module._videoInit(decoderType);\r\n this.decoderInited = true;\r\n }\r\n\r\n // 获取帧类型,若是I帧,则立即解码\r\n let frameType = Number(dataString.substr(13, 1));\r\n if (this.decoding && frameType == 0) {\r\n self.HEAPU8.set(u8a, this.cacheBuffer);\r\n Module._decodeVideo(this.cacheBuffer, dataLen); // 同步解码,返回前回调已触发\r\n this.hasInited = true;\r\n }\r\n break;\r\n }\r\n\r\n let u8aHead = this.cacheDataQue.shift();\r\n let headTimeStamp = this.timeStamp(u8aHead);\r\n\r\n if (this.renderMode == 1) {\r\n let u8a = u8aHead;\r\n let dataString = \"\";\r\n let dataLen = u8a.length - 16;\r\n for (let i = 0; i < 16; i++) {\r\n dataString += String.fromCharCode(u8a[dataLen + i]);\r\n }\r\n let frameType = Number(dataString.substr(13, 1));\r\n let isKey = false;\r\n if (frameType == 0) {\r\n isKey = true;\r\n // console.log(\"this.timeStamp(u8a)\", this.timeStamp(u8a));\r\n }\r\n self.postMessage({\r\n t: kVideoFrameOriginRsp,\r\n ti: this.timeStamp(u8a),\r\n isKey: isKey,\r\n d: u8a,\r\n });\r\n } else if (this.decoding) {\r\n self.HEAPU8.set(u8aHead, this.cacheBuffer);\r\n Module._decodeVideo(this.cacheBuffer, u8aHead.length - 16); // 同步解码,返回前回调已触发\r\n }\r\n this.preTimeStamp = headTimeStamp;\r\n } while (false);\r\n this.playBackTimer = setTimeout(this.playBack.bind(this), 4);\r\n } catch (e) {\r\n this.playBackTimer = setTimeout(this.playBack.bind(this), 4);\r\n }\r\n }\r\n\r\n dateFormat(fmt, date) {\r\n let ret;\r\n const opt = {\r\n \"Y+\": date.getFullYear().toString(), // 年\r\n \"m+\": (date.getMonth() + 1).toString(), // 月\r\n \"d+\": date.getDate().toString(), // 日\r\n \"H+\": date.getHours().toString(), // 时\r\n \"M+\": date.getMinutes().toString(), // 分\r\n \"S+\": date.getSeconds().toString(), // 秒\r\n // 有其他格式化字符需求可以继续添加,必须转化成字符串\r\n };\r\n for (let k in opt) {\r\n ret = new RegExp(\"(\" + k + \")\").exec(fmt);\r\n if (ret) {\r\n fmt = fmt.replace(\r\n ret[1],\r\n ret[1].length == 1 ? opt[k] : opt[k].padStart(ret[1].length, \"0\"),\r\n );\r\n }\r\n }\r\n return fmt;\r\n }\r\n\r\n /**\r\n * 历史回放控制\r\n **/\r\n playBackCtrl(pause) {\r\n // 兜底添加一个节流\r\n if (new Date().getTime() - this.streamPauseTime < 1000) {\r\n return;\r\n }\r\n // console.log(\"下发回放控制命令\", pause, this.cacheDataQue.length);\r\n this.streamPauseTime = new Date().getTime();\r\n if (pause) {\r\n this.isStreamPause = true;\r\n if (this.playbackMode == 1) {\r\n this.ctrlSendTime1++;\r\n /* 已经发送过了 正常不再发送防止消息丢失 重发机制 */\r\n if(this.ctrlSendTime1 > 2){\r\n return\r\n }\r\n }\r\n this.ctrlSendTime0 = 0;\r\n this.playbackMode = 1;\r\n } else {\r\n this.isStreamPause = false;\r\n if (this.playbackMode == 0) {\r\n this.ctrlSendTime0++;\r\n if(this.ctrlSendTime0 > 2){\r\n return\r\n }\r\n }\r\n this.ctrlSendTime1 = 0;\r\n this.playbackMode = 0;\r\n }\r\n\r\n let req = {};\r\n req.phone = this.phone;\r\n req.channel = this.channel;\r\n req.messageId = 0x9202;\r\n req.mediaType = this.mediaType;\r\n req.streamType = this.streamType;\r\n req.beginTime = this.beginTime;\r\n req.acceptLanguage = this.lang;\r\n req.playbackMode = this.playbackMode;\r\n let json = JSON.stringify(req);\r\n\r\n if (this.websocket != null) {\r\n if (this.websocket.readyState === this.websocket.OPEN) {\r\n this.websocket.send(json);\r\n } else {\r\n this.websocket = null;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * 获取时间戳\r\n **/\r\n timeStamp(u8a) {\r\n let dataString = \"\";\r\n let dataLen = u8a.length - 16;\r\n\r\n for (let i = 0; i < 16; i++) {\r\n dataString += String.fromCharCode(u8a[dataLen + i]);\r\n }\r\n\r\n return Number(dataString.substr(0, 13));\r\n }\r\n\r\n /**\r\n * 获取数组中最后一个I帧的索引\r\n **/\r\n frameIndex() {\r\n let index = -1;\r\n for (let i = 0; i < this.cacheDataQue.length; i++) {\r\n let u8a = this.cacheDataQue[i];\r\n let dataLen = u8a.length - 16;\r\n if (u8a[dataLen + 13] == 48) {\r\n // 48 <=> '0'\r\n index = i;\r\n }\r\n }\r\n return index;\r\n }\r\n\r\n /**\r\n * 往码流链路发音频控制命令\r\n **/\r\n enableAudio(d) {\r\n this.playAudio = d;\r\n /* if (this.websocket != null) {\r\n let req = {};\r\n req.phone = this.phone;\r\n req.channel = this.channel;\r\n if (d) {\r\n req.messageId = 0x9601;\r\n } else {\r\n req.messageId = 0x9600;\r\n }\r\n let json = JSON.stringify(req);\r\n this.websocket.send(json);\r\n } else {\r\n this.logger.logInfo(\"Web socket is null\");\r\n }*/\r\n }\r\n\r\n /**\r\n * 关闭websocket码流链路\r\n **/\r\n closeStream() {\r\n this.pause();\r\n\r\n if (this.websocket != null) {\r\n this.websocket.onmessage = null;\r\n this.websocket.onerror = null;\r\n this.websocket.onopen = null;\r\n this.websocket.close();\r\n this.websocket = null;\r\n }\r\n\r\n if (this.netSpeedTimer != null) {\r\n clearInterval(this.netSpeedTimer);\r\n this.netSpeedTimer = null;\r\n }\r\n\r\n this.baseUnInit();\r\n }\r\n\r\n /**\r\n * 码流信息解码\r\n **/\r\n sendData(data) {\r\n if (!this.decoding) {\r\n return;\r\n }\r\n let u8a = new Uint8Array(data);\r\n this.netSpeedSize += u8a.length;\r\n //u8a = u8a.subarray(26, 114); // 去掉rtp头,可用于对讲测试\r\n let dataString = \"\";\r\n let dataLen = u8a.length - 16;\r\n for (let i = 0; i < 16; i++) {\r\n dataString += String.fromCharCode(u8a[dataLen + i]);\r\n }\r\n\r\n let frameType = Number(dataString.substr(13, 1));\r\n let ptRaw = dataString.substr(14);\r\n if (\r\n u8a[0] == 0 &&\r\n u8a[1] == 0 &&\r\n u8a[2] == 0 &&\r\n u8a[3] == 1 &&\r\n (ptRaw == 98 || ptRaw == 99)\r\n ) {\r\n if (this.beginTime) {\r\n // 回放,走流控\r\n this.cacheDataQue.push(u8a);\r\n this.checkCacheAndCtrl();\r\n } else {\r\n this.realPlay(u8a, frameType, ptRaw); // 实时,直接解码\r\n }\r\n } else {\r\n // if (this.mediaType !== kMediaSpeak && !this.playAudio) {\r\n // // 监听时,按声音开关控制播放音频\r\n // return;\r\n // }\r\n if (!this.voiceScheduling) {\r\n // 语音调度不播放上行音频\r\n // 最后一字节为音频编码类型\r\n if(u8a.length<100)return\r\n if (dataString.indexOf(\"306\") > 0) {\r\n u8a = u8a.slice(0, -15);\r\n u8a[u8a.length - 1] = 6;\r\n const nowAudioTime = dataString.slice(0, 13);\r\n if (\r\n this.voiceTimeStamp !== 0 &&\r\n Math.abs(nowAudioTime - this.voiceTimeStamp) > 1000\r\n ) {\r\n /* 如果音频跨段主动flush一次 */\r\n let objData = {\r\n t: kFlushAudio,\r\n d: this.voiceTimeStamp,\r\n };\r\n self.postMessage(objData);\r\n }\r\n this.voiceTimeStamp = nowAudioTime;\r\n }\r\n // console.log('dataString',dataString)\r\n self.HEAPU8.set(u8a, this.cacheBuffer);\r\n Module._decodeAudio(\r\n this.cacheBuffer,\r\n u8a.length - 1,\r\n u8a[u8a.length - 1],\r\n );\r\n }\r\n }\r\n }\r\n\r\n checkCacheAndCtrl() {\r\n if (this.playMode == 0) {\r\n return;\r\n }\r\n let min = 10;\r\n let max = 30;\r\n if (this.playbackMode == 6) {\r\n // 帧播放\r\n min = 1;\r\n max = 5;\r\n }\r\n let queLen = this.cacheDataQue.length;\r\n if (queLen == 0 && !this.isFirstLoaded) {\r\n this.isCacheLow = true;\r\n // console.log(\"缓存不足提示\");\r\n let objData = {\r\n t: kNoCache,\r\n len: queLen,\r\n };\r\n self.postMessage(objData);\r\n }\r\n if (queLen > 0 && !this.isFirstLoaded) {\r\n this.isFirstLoaded = true;\r\n this.isCacheLow = false;\r\n // console.log(\"缓存恢复提示\");\r\n let objData = {\r\n t: kCacheAvailable,\r\n len: queLen,\r\n };\r\n self.postMessage(objData);\r\n }\r\n if (this.isCacheLow && queLen >= min * 10) {\r\n this.isCacheLow = false;\r\n // console.log(\"缓存恢复提示\");\r\n let objData = {\r\n t: kCacheAvailable,\r\n len: queLen,\r\n };\r\n self.postMessage(objData);\r\n }\r\n if (queLen < min * 25) {\r\n // 恢复终端码流传输\r\n this.playBackCtrl(false);\r\n } else if (queLen > max * 25) {\r\n // 暂停终端码流传输\r\n this.playBackCtrl(true);\r\n }\r\n }\r\n\r\n /**\r\n * 处理来自MnPlayer的命令\r\n **/\r\n processReq(req) {\r\n switch (req.t) {\r\n case kVideoAudioOffset:\r\n this.offset(req.data);\r\n break;\r\n case kOpenDecoderReq:\r\n this.ws = req.ws;\r\n this.host = req.host;\r\n this.port = req.port;\r\n this.phone = req.phone;\r\n ((this.userId = req.userId),\r\n (this.tenantId = req.tenantId),\r\n (this.token = req.token),\r\n (this.channel = req.channel));\r\n this.lang = req.lang;\r\n this.deviceType = req.deviceType;\r\n this.renderMode = req.renderMode;\r\n break;\r\n case kChangeRenderTypeReq:\r\n this.renderMode = req.renderMode;\r\n break;\r\n case kResumeDecodingReq:\r\n this.resume();\r\n break;\r\n case kPauseDecodingReq:\r\n this.pause();\r\n break;\r\n case kOpenStreamReq:\r\n this.messageId = req.messageId;\r\n this.mediaType = req.mediaType;\r\n this.streamType = req.streamType;\r\n this.beginTime = req.beginTime;\r\n this.lang = req.lang;\r\n this.openStream();\r\n break;\r\n case kEnableAudioReq:\r\n this.enableAudio(req.d);\r\n break;\r\n case kSwitchStreamReq:\r\n this.switchStream(req.m, req.s);\r\n break;\r\n case kRecorderSpeakReq:\r\n this.voiceScheduling = true;\r\n this.encodeAudio(req.d);\r\n break;\r\n case kRecorderTalkReq:\r\n this.voiceScheduling = false;\r\n this.encodeAudio(req.d);\r\n break;\r\n case kCloseStreamReq:\r\n this.closeStream();\r\n break;\r\n case kFastForward:\r\n this.fastForward = req.d;\r\n break;\r\n case kReplayReq:\r\n this.play();\r\n break;\r\n case kReplaySpeedReq:\r\n let beginTime = this.beginTime;\r\n this.playbackMode = req.playbackMode;\r\n if (req.time) {\r\n beginTime = req.time;\r\n } else if (this.preTimeStamp) {\r\n let t = new Date(this.preTimeStamp);\r\n beginTime = `${t.getUTCFullYear()}-${(t.getUTCMonth() + 1)\r\n .toString()\r\n .padStart(2, \"0\")}-${t.getUTCDate().toString().padStart(2, \"0\")} ${t\r\n .getUTCHours()\r\n .toString()\r\n .padStart(2, \"0\")}:${t\r\n .getUTCMinutes()\r\n .toString()\r\n .padStart(\r\n 2,\r\n \"0\",\r\n )}:${t.getUTCSeconds().toString().padStart(2, \"0\")}`;\r\n }\r\n\r\n this.websocket.send(\r\n JSON.stringify({\r\n playbackSpeed: req.d,\r\n messageId: 0x9202,\r\n channel: this.channel,\r\n phone: this.phone,\r\n deviceType: this.deviceType,\r\n streamType: this.streamType,\r\n mediaType: this.mediaType,\r\n host: this.host,\r\n hostUuid: this.host_uuid,\r\n port: this.port,\r\n ws: this.ws,\r\n beginTime,\r\n acceptLanguage: this.lang,\r\n playbackMode: this.playbackMode,\r\n }),\r\n );\r\n this.speed = req.v;\r\n this.speedValue = req.d;\r\n break;\r\n default:\r\n this.logger.logError(\"Unsupport messsage \" + req.t);\r\n }\r\n }\r\n\r\n /**\r\n * 录音编码(对讲)\r\n **/\r\n //判断设备 6 等于QM003 26 = 磁北\r\n encodeAudio(data) {\r\n if (this.websocket != null) {\r\n self.HEAP8.set(data, this.speakBuffer);\r\n Module._encodeAudio(\r\n this.speakBuffer,\r\n data.length,\r\n this.deviceType == \"6\" ? 6 : 26,\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * 字符串转int8Array\r\n **/\r\n toInt8Array(str) {\r\n let i8a = [];\r\n for (let i = 0; i < str.length; i++) {\r\n i8a.push(str.charCodeAt(i));\r\n }\r\n return new Int8Array(i8a);\r\n }\r\n\r\n /**\r\n * 缓存来自MnPlayer的命令\r\n **/\r\n cacheReq(req) {\r\n if (req) {\r\n this.cacheReqQue.push(req);\r\n }\r\n }\r\n\r\n /**\r\n * WASM初始化\r\n **/\r\n onWasmLoaded() {\r\n this.wasmLoaded = true;\r\n this.readyCallback = Module.addFunction(function (width, height) {\r\n let objData = {\r\n t: kVideoReady,\r\n w: width,\r\n h: height,\r\n };\r\n self.postMessage(objData);\r\n }, \"vii\");\r\n let that = this;\r\n this.videoCallback = Module.addFunction(function (buff, size) {\r\n // 解码耗时已在调用侧用 token 精确计时(见 _decodeVideo 调用点),此处不再配对\r\n // memory64 构建:buff 是 i64 指针(BigInt),转 Number 后再访问 HEAP\r\n let outArray = self.HEAPU8.subarray(Number(buff), Number(buff) + size);\r\n let data = new Uint8Array(outArray);\r\n let objData = {\r\n t: kVideoFrame,\r\n d: data,\r\n ti: that.preTimeStamp,\r\n };\r\n self.postMessage(objData, [objData.d.buffer]);\r\n }, \"vji\");\r\n this.audioCallback = Module.addFunction(function (buff, size) {\r\n let outArray = self.HEAPU8.subarray(Number(buff), Number(buff) + size);\r\n let data = new Uint8Array(outArray);\r\n let objData = {\r\n t: kAudioFrame,\r\n d: data,\r\n ti: that.voiceTimeStamp,\r\n };\r\n self.postMessage(objData, [objData.d.buffer]);\r\n }, \"vji\");\r\n\r\n this.speakCallback = Module.addFunction(function (buff, size) {\r\n let outArray = self.HEAPU8.subarray(Number(buff), Number(buff) + size);\r\n let data = new Int8Array(outArray);\r\n if (\r\n self.decoder.websocket !== null &&\r\n self.decoder.websocket.readyState === self.decoder.websocket.OPEN\r\n ) {\r\n self.decoder.websocket.send(data);\r\n }\r\n }, \"vji\");\r\n\r\n // 执行缓存中的命令\r\n while (this.cacheReqQue.length > 0) {\r\n let req = this.cacheReqQue.shift();\r\n this.processReq(req);\r\n }\r\n }\r\n}\r\n\r\n// 仅主 worker 实例化 MnWorker;em-pthread 子线程必须保留 mn-media.js 的 handleMessage\r\n// (若在此覆盖 self.onmessage,pthread 握手 cmd 1 永远得不到 cmd 3 回复,主 worker 卡在加载中)\r\nif (!isPthreadWorker) {\r\n self.decoder = new MnWorker();\r\n\r\n /**\r\n * 接收主线程消息\r\n **/\r\n self.onmessage = function (evt) {\r\n // console.log(\"接收主线程消息\", evt, self.decoder);\r\n if (!self.decoder) {\r\n console.log(\"[ER] MnWorker not initialized!\");\r\n return;\r\n }\r\n\r\n let req = evt.data;\r\n if (!self.decoder.wasmLoaded) {\r\n // 若尚未初始化,则缓存该命令\r\n // console.log(\"缓存命令\", req);\r\n self.decoder.cacheReq(req);\r\n return;\r\n }\r\n // console.log(\"接收主线程消息\", req);\r\n self.decoder.processReq(req);\r\n };\r\n}\r\n\r\n// 每 5 秒自动打印解码性能汇总(仅主 worker;有新增样本才输出,避免空闲刷屏)\r\n\r\n\r\n/**\r\n * memory64(wasm64)构建适配:新版 wasm 使用 64 位指针,SDK 导出的\r\n * 指针/函数指针参数在 JS 侧调用时必须传 BigInt。\r\n * 胶水的 applySignatureConversions 只包装了内部函数(_malloc/_free 等),\r\n * 没有包装 _baseInit/_decodeVideo/_decodeAudio/_encodeAudio,这里补上。\r\n * 对应 wasm 签名:_baseInit(i64,i32,i64,i64,i64,i64,i32)、\r\n * _decodeVideo(i64,i64)、_decodeAudio(i64,i64,i32)、_encodeAudio(i64,i64,i32)。\r\n **/\r\nfunction wrapSdkBigIntExports() {\r\n const rawBaseInit = Module._baseInit;\r\n const rawDecodeVideo = Module._decodeVideo;\r\n const rawDecodeAudio = Module._decodeAudio;\r\n const rawEncodeAudio = Module._encodeAudio;\r\n Module._baseInit = (phone, channel, readyCb, videoCb, audioCb, speakCb, logLevel) =>\r\n rawBaseInit(\r\n BigInt(phone),\r\n channel,\r\n BigInt(readyCb),\r\n BigInt(videoCb),\r\n BigInt(audioCb),\r\n BigInt(speakCb),\r\n logLevel,\r\n );\r\n Module._decodeVideo = (buf, len) => rawDecodeVideo(BigInt(buf), BigInt(len));\r\n Module._decodeAudio = (buf, len, type) => rawDecodeAudio(BigInt(buf), BigInt(len), type);\r\n Module._encodeAudio = (buf, len, type) => rawEncodeAudio(BigInt(buf), BigInt(len), type);\r\n}\r\n\r\n/**\r\n * 初始化\r\n **/\r\nfunction onWasmLoaded() {\r\n if (self.decoder) {\r\n // console.log(\"WASM加载完成\");\r\n self.decoder.onWasmLoaded();\r\n } else {\r\n console.log(\"[ER] No decoder!\");\r\n }\r\n}\r\n"],"names":["isPthreadWorker","wrapSdkBigIntExports","onWasmLoaded","msg","MnWorker","time","isVideoFast","phoneBuffer","ret","objData","speed","len","req","json","c","r","uid","url","ev","message","mediaType","streamType","u8a","frameType","ptRaw","ti","dataString","dataLen","i","isKey","decoderType","u8aHead","headTimeStamp","fmt","date","opt","k","pause","index","d","data","nowAudioTime","min","max","queLen","beginTime","t","str","i8a","width","height","that","buff","size","outArray","evt","rawBaseInit","rawDecodeVideo","rawDecodeAudio","rawEncodeAudio","phone","channel","readyCb","videoCb","audioCb","speakCb","logLevel","buf","type"],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ <!-- By Sam Herbert (@sherb), for everyone. More @ http://goo.gl/7AJzbL -->
2
+ <!-- Todo: add easing -->
3
+ <svg width="57" height="57" viewBox="0 0 57 57" xmlns="http://www.w3.org/2000/svg" stroke="#fff">
4
+ <g fill="none" fill-rule="evenodd">
5
+ <g transform="translate(1 1)" stroke-width="2">
6
+ <circle cx="5" cy="50" r="5">
7
+ <animate attributeName="cy"
8
+ begin="0s" dur="2.2s"
9
+ values="50;5;50;50"
10
+ calcMode="linear"
11
+ repeatCount="indefinite" />
12
+ <animate attributeName="cx"
13
+ begin="0s" dur="2.2s"
14
+ values="5;27;49;5"
15
+ calcMode="linear"
16
+ repeatCount="indefinite" />
17
+ </circle>
18
+ <circle cx="27" cy="5" r="5">
19
+ <animate attributeName="cy"
20
+ begin="0s" dur="2.2s"
21
+ from="5" to="5"
22
+ values="5;50;50;5"
23
+ calcMode="linear"
24
+ repeatCount="indefinite" />
25
+ <animate attributeName="cx"
26
+ begin="0s" dur="2.2s"
27
+ from="27" to="27"
28
+ values="27;49;5;27"
29
+ calcMode="linear"
30
+ repeatCount="indefinite" />
31
+ </circle>
32
+ <circle cx="49" cy="50" r="5">
33
+ <animate attributeName="cy"
34
+ begin="0s" dur="2.2s"
35
+ values="50;50;5;50"
36
+ calcMode="linear"
37
+ repeatCount="indefinite" />
38
+ <animate attributeName="cx"
39
+ from="49" to="49"
40
+ begin="0s" dur="2.2s"
41
+ values="49;5;27;49"
42
+ calcMode="linear"
43
+ repeatCount="indefinite" />
44
+ </circle>
45
+ </g>
46
+ </g>
47
+ </svg>
@@ -0,0 +1 @@
1
+ <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1603434493465" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3484" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M732.8 434.4c0 16.8 11.2 28.8 28.8 28.8s28.8-11.2 28.8-28.8c-0.8-94.4-76.8-171.2-172-172-17.6 0-28.8 11.2-28.8 28.8s11.2 28.8 28.8 28.8c63.2 0.8 114.4 52 114.4 114.4z m0 0" p-id="3485" fill="#2DFF0A"></path><path d="M847.2 434.4c0 16.8 11.2 28.8 28.8 28.8s28.8-11.2 28.8-28.8c0-157.6-128.8-285.6-285.6-285.6-17.6 0-28.8 11.2-28.8 28.8s11.2 28.8 28.8 28.8c125.6 0 228 102.4 228 228z m-500-28c6.4 40 41.6 192.8 204.8 268 7.2 3.2 16 2.4 22.4-2.4 23.2-16.8 76-54.4 87.2-62.4 16.8-12 46.4-23.2 71.2 0.8l130.4 121.6s19.2 31.2 5.6 48c-37.6 45.6-123.2 140.8-123.2 140.8s-16 19.2-48 8c-52-18.4-228.8-108-370.4-276.8-140-164.8-176.8-306.4-203.2-405.6-8.8-32.8-4-61.6 20.8-73.6 32-14.4 170.4-79.2 170.4-79.2s32-8.8 45.6 16c13.6 24.8 91.2 131.2 100.8 148 11.2 19.2 4 36-5.6 44.8-12 10.4-80.8 68-104 87.2-4 4-6.4 10.4-4.8 16.8z m0 0" p-id="3486" fill="#2DFF0A"></path></svg>
@@ -0,0 +1,9 @@
1
+ <svg width="64" height="41" xmlns="http://www.w3.org/2000/svg">
2
+ <g transform="translate(0 1)" fill="none" fill-rule="evenodd">
3
+ <ellipse fill="#F5F5F5" cx="32" cy="33" rx="32" ry="7"/>
4
+ <g fill-rule="nonzero" stroke="#D9D9D9">
5
+ <path d="M55 12.76L44.854 1.258C44.367.474 43.656 0 42.907 0H21.093c-.749 0-1.46.474-1.947 1.257L9 12.761V22h46v-9.24z"/>
6
+ <path d="M41.613 15.931c0-1.605.994-2.93 2.227-2.931H55v18.137C55 33.26 53.68 35 52.05 35h-40.1C10.32 35 9 33.259 9 31.137V13h11.16c1.233 0 2.227 1.323 2.227 2.928v.022c0 1.605 1.005 2.901 2.237 2.901h14.752c1.232 0 2.237-1.308 2.237-2.913v-.007z" fill="#FAFAFA"/>
7
+ </g>
8
+ </g>
9
+ </svg>
@@ -0,0 +1,6 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" width="32" height="32" fill="white">
2
+ <path opacity=".25" d="M16 0 A16 16 0 0 0 16 32 A16 16 0 0 0 16 0 M16 4 A12 12 0 0 1 16 28 A12 12 0 0 1 16 4"/>
3
+ <path d="M16 0 A16 16 0 0 1 32 16 L28 16 A12 12 0 0 0 16 4z">
4
+ <animateTransform attributeName="transform" type="rotate" from="0 16 16" to="360 16 16" dur="0.8s" repeatCount="indefinite" />
5
+ </path>
6
+ </svg>
@@ -0,0 +1,22 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
3
+ <svg version="1.1" id="图层_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
4
+ viewBox="0 0 128 128" style="enable-background:new 0 0 128 128;" xml:space="preserve">
5
+ <style type="text/css">
6
+ .st0{fill:#4C4C4C;}
7
+ </style>
8
+ <g>
9
+ <path class="st0" d="M110.8,44L88.4,55.5l-2.9-5.2l25.2-13.2c2.9-1.7,5.7,0,5.7,3.4v47c0,3.4-2.9,5.2-5.7,3.4L86.1,78.4l2.9-5.2
10
+ l21.8,11.5V44z M110.8,44L88.4,55.5l-2.9-5.2l25.2-13.2c2.9-1.7,5.7,0,5.7,3.4v47c0,3.4-2.9,5.2-5.7,3.4L86.1,78.4l2.9-5.2
11
+ l21.8,11.5V44z M110.8,41.1"/>
12
+ <path class="st0" d="M17.2,41.4v45.3c0,3.4,2.3,5.7,5.7,5.7h55c3.4,0,5.7-2.3,5.7-5.7V41.4c0-3.4-2.3-5.7-5.7-5.7H23
13
+ C19.5,35.6,17.2,37.9,17.2,41.4L17.2,41.4z M11.5,41.4c0-6.3,5.2-11.5,11.5-11.5h55c6.3,0,11.5,5.2,11.5,11.5v45.3
14
+ c0,6.3-5.2,11.5-11.5,11.5H23c-6.3,0-11.5-5.2-11.5-11.5V41.4z M11.5,41.4"/>
15
+ <g>
16
+ <path class="st0" d="M50.5,84.6c-11.4,0-20.6-9.2-20.6-20.6c0-11.4,9.2-20.6,20.6-20.6c11.4,0,20.6,9.2,20.6,20.6
17
+ C71.1,75.4,61.9,84.6,50.5,84.6L50.5,84.6z M33.7,64c0,9.3,7.5,16.8,16.8,16.8c3.9,0,7.5-1.4,10.4-3.6L37.3,53.6
18
+ C35.1,56.5,33.7,60.1,33.7,64L33.7,64z M50.5,47.2c-3.9,0-7.5,1.4-10.4,3.6l23.5,23.5c2.3-2.9,3.6-6.5,3.6-10.4
19
+ C67.2,54.7,59.7,47.2,50.5,47.2L50.5,47.2z M50.5,47.2"/>
20
+ </g>
21
+ </g>
22
+ </svg>
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "mn-video-player-v2",
3
+ "version": "1.4.9",
4
+ "description": "MN Video Player for WebSocket streaming",
5
+ "main": "./dist/mn-video-player.umd.js",
6
+ "module": "./dist/mn-video-player.es.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/mn-video-player-v2.es.js",
12
+ "require": "./dist/mn-video-player-v2.umd.js"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist",
17
+ "dist/assets"
18
+ ],
19
+ "scripts": {
20
+ "build": "vite build && tsc --emitDeclarationOnly",
21
+ "dev": "vite build --watch",
22
+ "prepublishOnly": "npm run build",
23
+ "demo": "vite --config vite.demo.config.ts"
24
+ },
25
+ "keywords": [
26
+ "video",
27
+ "player",
28
+ "websocket",
29
+ "streaming",
30
+ "mn-player"
31
+ ],
32
+ "author": "",
33
+ "license": "ISC",
34
+ "devDependencies": {
35
+ "@types/jquery": "^3.5.33",
36
+ "@types/node": "^25.0.7",
37
+ "@vitest/coverage-v8": "^4.0.17",
38
+ "jsdom": "^27.4.0",
39
+ "typescript": "^5.9.3",
40
+ "vite": "^7.3.1",
41
+ "vite-plugin-mkcert": "^1.17.9",
42
+ "vitest": "^4.0.17"
43
+ },
44
+ "dependencies": {
45
+ "jquery": "^3.7.1"
46
+ }
47
+ }