// var fileref = null; // fileref = document.createElement( 'script' ) // fileref.setAttribute( "type", "text/javascript" ); // fileref.setAttribute( "src", "./unit2.js" ); // document.getElementsByTagName( "head" )[0].appendChild( fileref ); // fileref = document.createElement( 'script' ); // fileref.setAttribute( "type", "text/javascript" ); // fileref.setAttribute( "src", "./unit3.js" ); // document.getElementsByTagName( "head" )[0].appendChild( fileref ); //fileref = document.createElement( 'script' ); //fileref.setAttribute( "type", "text/javascript" ); //fileref.setAttribute( "src", "./js/audio_worker.js" ); //document.getElementsByTagName( "head" )[0].appendChild( fileref ); var g_rec = []; var g_totalAudioData = ""; if ( ( !ArrayBuffer.prototype.slice ) || ( ArrayBuffer.prototype.slice == "undifined" ) ) { //Returns a new ArrayBuffer whose contents are a copy of this ArrayBuffer's //bytes from `begin`, inclusive, up to `end`, exclusive ArrayBuffer.prototype.slice = function (begin, end) { //If `begin` is unspecified, Chrome assumes 0, so we do the same if (begin === void 0) { begin = 0; } //If `end` is unspecified, the new ArrayBuffer contains all //bytes from `begin` to the end of this ArrayBuffer. if (end === void 0) { end = this.byteLength; } //Chrome converts the values to integers via flooring begin = Math.floor(begin); end = Math.floor(end); //If either `begin` or `end` is negative, it refers to an //index from the end of the array, as opposed to from the beginning. if (begin < 0) { begin += this.byteLength; } if (end < 0) { end += this.byteLength; } //The range specified by the `begin` and `end` values is clamped to the //valid index range for the current array. begin = Math.min(Math.max(0, begin), this.byteLength); end = Math.min(Math.max(0, end), this.byteLength); //If the computed length of the new ArrayBuffer would be negative, it //is clamped to zero. if (end - begin <= 0) { return new ArrayBuffer(0); } var result = new ArrayBuffer(end - begin); var resultBytes = new Uint8Array(result); var sourceBytes = new Uint8Array(this, begin, end - begin); resultBytes.set(sourceBytes); return result; }; } //define var DATAH264 = 0; var DATAJPEG = 2; var DATAH265 = 4; var DATATYPE_G711U = 5; var DATATYPE_AAC = 6; var DATAG711U = 1; var DATAAAC = 2; var FRAME_I = 1; var FRAME_P = 0; var SES = 0;//Server Send Event var WS_WR = 1;//Websocket And Worker var WS = 2;//Websocket // var P_ONE_DEC_ONE_WS = 0; var P_MLT_DEC_MLT_WS = 1; var P_MLT_DEC_ONE_WS = 2; var S_ONE_DEC_ONE_WS = 3;//acturally same as 0 function _codec_para() { this.worker_num = 1; this.vc = [];//video container format is { width: 1920, height: 1088, id: divid, framesize: 512K }; this.uid = [];//something like this 1483093469437 this.decode = []; this.droplatencydecoded = false; } function parseHexString( str ) { var buffer_length = parseInt( ( str.length / 2 ) ); if ( str.length / 2 ) buffer_length += 1; var result = new Uint8Array( buffer_length ); var pos = 0; var converted = 0; while( str.length > converted ) { result[ pos ] = parseInt( str.substring( converted, converted + 2 ), 16 ); pos ++; converted += 2; } //console.log( "0x " + result[0].toString(16) + result[1].toString(16) + result[2].toString(16) + result[3].toString(16) ); return result; } function isHeaderPreamble( byte ) { if ( ( byte[ 0 ] == 0x57 )&&( byte[ 1 ] == 0x57 )&&( byte[ 2 ] == 0 )&&( byte[ 3 ] == 0 ) ) return true; else return false; } function getHeaderDataType( byte ) { return byte[22]; } function getHeaderChannel( byte ) { return byte[ 17 ]; } function mywaiting( delay ) { var start = new Date().getTime(); while (new Date().getTime() < start + delay) { }; } function plusZero( nNum ) { return ( ( nNum < 10 ) ? ( "0" + nNum ) : nNum ); } function getHeaderTimeString( utc_sec ) { var dt = new Date( 0 ); dt.setUTCSeconds( utc_sec ); var retString; var yyyy = dt.getUTCFullYear(); var mm = plusZero( dt.getUTCMonth() + 1 ); var dd = plusZero( dt.getUTCDate() ); var hh = plusZero( dt.getUTCHours() ); var mi = plusZero( dt.getUTCMinutes() ); var ss = plusZero( dt.getUTCSeconds() ); var spaceStr = " "; retString = yyyy + "/" + mm + "/" + dd + spaceStr + hh + ":" + mi + ":" + ss; return retString; } function getHeaderTime( byte ) { var total_sec = 0; var utc_sec = ( ( byte[12] << 24 ) | ( byte[ 11 ] << 16 ) | ( byte[ 10 ] << 8 ) | byte[ 9 ] ); var tz_info = byte[ 23 ]; var tz_sec = 0; if ( tz_info > 0 ) { var hr = ( tz_info & 0x78 ) >> 3; var min = 0; var mincase = ( tz_info & 0x07 ); switch ( mincase ) { case 0x03: min = 45; break; case 0x02: min = 30; break; case 0x01: min = 15; break; default: min = 0; break; } tz_sec = ( hr * 3600 )+( min * 60 ); if( tz_info & 0x80 ) { total_sec = ( utc_sec - tz_sec ); } else { total_sec = ( utc_sec + tz_sec ); } } else total_sec = utc_sec; return total_sec; // var dt = new Date( 0 ); // dt.setUTCSeconds( total_sec ); // // var retString; // var yyyy = dt.getUTCFullYear(); // var mm = plusZero( dt.getUTCMonth() + 1 ); // var dd = plusZero( dt.getUTCDate() ); // var hh = plusZero( dt.getUTCHours() ); // var mi = plusZero( dt.getUTCMinutes() ); // var ss = plusZero( dt.getUTCSeconds() ); // // var spaceStr = " "; // retString = yyyy + "/" + mm + "/" + dd + spaceStr + hh + ":" + mi + ":" + ss; // return retString; } function getHeaderId( byte ) { return byte[17]; } //NALU_VPS_NUT = 32, // video parameter set //NALU_SPS_NUT = 33, // sequence parameter set function H265_NALU( x ) { return ( ( ( x )& 0x7E ) >> 1 ); } function isH26XData( byte , shift )//we could lock the streaming by add our own encrpt in the front. { if (( byte[ shift + 0] == 0 ) && ( byte[ shift + 1] == 0 ) && ( byte[ shift + 2] == 0 ) && ( byte[ shift + 3] == 1 )) return true; else return false; } function isMobBs( )//is mobile browser { if( navigator.userAgent.match(/Android/i) || navigator.userAgent.match(/webOS/i) || navigator.userAgent.match(/iPhone/i) || navigator.userAgent.match(/iPad/i) || navigator.userAgent.match(/iPod/i) || navigator.userAgent.match(/BlackBerry/i) || navigator.userAgent.match(/Windows Phone/i) ) { return true; } else { return false; } } function detectBrowser() { var uni_browser = {}; var uagent = navigator.userAgent.toLowerCase(), match = ''; uni_browser.chrome = /webkit/.test(uagent) && /chrome/.test(uagent) && !/edge/.test(uagent); uni_browser.firefox = /mozilla/.test(uagent) && /firefox/.test(uagent); uni_browser.msie = /msie/.test(uagent) || /trident/.test(uagent) || /edge/.test(uagent); uni_browser.safari = /safari/.test(uagent) && /applewebkit/.test(uagent) && !/chrome/.test(uagent); uni_browser.opr = /mozilla/.test(uagent) && /applewebkit/.test(uagent) && /chrome/.test(uagent) && /safari/.test(uagent) && /opr/.test(uagent); uni_browser.version = ''; for (x in uni_browser) { if (uni_browser[x]) { match = uagent.match( new RegExp("(" + (x === "msie" ? "msie|edge" : x) + ")( |\/)([0-9]+)") ); if (match) { uni_browser.version = match[3]; } else { match = uagent.match(new RegExp("rv:([0-9]+)")); uni_browser.version = match ? match[1] : ""; } break; } } uni_browser.opera = uni_browser.opr; delete uni_browser.opr; return uni_browser; } function getDefaultStreamMode() { var browser = detectBrowser(); if ( browser.opera ) return WS_WR; else if ( browser.msie ) return WS;//Include IE and Edge 2018.07.27 Edge with Worker cause crush. else if ( browser.chrome ) return WS_WR; else if ( browser.firefox ) { if ( browser.version >= 54.0 )//Since 54 became multi-thread base browser. return WS_WR; else return WS; } else if ( browser.safari ) return WS_WR; else return WS; } function _recvCalc() { this.dataType = DATAH264; this.decodedTimestamp = 0; this.decodedTimespec = 0; this.decodedSpendMsec = 0; this.decodedFPS_Cnt = 0; this.lastDecodedFPS = 0; this.decodedTP = 0; this.lastDecodedTP = 0; this.width = 0; this.height = 0; this.string = ""; this.receivedTimestamp = 0; this.receivedTimespec = 0; this.receivedSpendMsec = 0; this.receivedFPS_Cnt = 0; this.lastReceivedFPS = 0; this.receivedTP = 0; this.lastReceivedTP = 0; this.receivedString = ""; this.decodedString = ""; this.latencyString = ""; this.dropedString = ""; this.iframe_bottleneck = 0; } function _codecInformation() { this.videoType = DATAH265; this.audioType = DATATYPE_G711U; this.sampleRate = 8000; this.bitRate = 16000; this.width = 1920; this.height = 1080; this.snapshot = 0; this.recorder = 0; this.ctx = null; this.FPS = 30; this.decodeStatus = 0; this.snapshotFile = null; this.recorderFile = null; } function getDecodedCalcString( rCalc ) { if(( rCalc.dataType == DATAH264 ) || ( rCalc.dataType == DATAJPEG ) || ( rCalc.dataType == DATAH265 )) { //retstring =( rCalc.dataType == DATAH264 ? " H264" : " H265" ); if( rCalc.dataType == DATAH264 ) retstring =" H264"; else if( rCalc.dataType == DATAJPEG ) retstring =" JPEG"; else if( rCalc.dataType == DATAH265 ) retstring =" H265"; retstring += ( " " + rCalc.lastDecodedFPS + "FPS" ); retstring += (rCalc.width != 0 ? (" " + rCalc.width + "X" + rCalc.height):""); retstring += (" " + rCalc.decodedSpendMsec + "ms" ); //retstring += " " +Math.floor( ((rCalc.lastDecodedTP*8)/1024) ) + "Kbps"; } else { retstring = " Unknow stream tpye"; } //console.log( retstring ); return retstring; } function getReceivedCalcString( rCalc ) { retstring = ( " " + rCalc.lastReceivedFPS + "FPS" ); retstring += (" " + rCalc.receivedSpendMsec + "ms" ); return retstring; } function calcDecodedFpsAndTp( rCalc, frameInfo ) { nbytes = frameInfo.nbytes; rCalc.decodedTimestamp = frameInfo.timestamp; //console.log("calcDecodedFpsAndTp rCalc.decodedTimespec:"+rCalc.decodedTimespec); if ( rCalc.decodedTimespec == 0 ) { rCalc.decodedTimespec = new Date().getTime(); if( rCalc.decodedFPS_Cnt == 1 ) rCalc.decodedFPS_Cnt += 1; else rCalc.decodedFPS_Cnt = 1; rCalc.decodedTP = nbytes; } else { rCalc.decodedSpendMsec = new Date().getTime() - rCalc.decodedTimespec; //console.log("calcDecodedFpsAndTp rCalc.decodedSpendMsec:"+rCalc.decodedSpendMsec); rCalc.decodedFPS_Cnt++; rCalc.decodedTP += nbytes; rCalc.width = frameInfo.width; rCalc.height = frameInfo.height; if( rCalc.decodedSpendMsec >= 1000 )//OVER 1SEC { rCalc.decodedFPS_Cnt -= 1; rCalc.lastDecodedTP = rCalc.decodedTP - nbytes; if( rCalc.lastDecodedFPS != rCalc.decodedFPS_Cnt ) rCalc.lastDecodedFPS = rCalc.decodedFPS_Cnt; //rCalc.lastDecodedFPS = rCalc.decodedFPS_Cnt; rCalc.decodedFPS_Cnt = 1; rCalc.decodedString = getDecodedCalcString( rCalc ); rCalc.decodedTimespec = rCalc.decodedSpendMsec = 0; } } } function calcReceivedFpsAndTp( rCalc, frameInfo ) { nbytes = frameInfo.nbytes; rCalc.receivedTimestamp = frameInfo.timestamp; //console.log("calcReceivedFpsAndTp rCalc.receivedTimespec:"+rCalc.receivedTimespec); if ( rCalc.receivedTimespec == 0 ) { rCalc.receivedTimespec = new Date().getTime(); if( rCalc.receivedFPS_Cnt == 1 ) rCalc.receivedFPS_Cnt += 1; else rCalc.receivedFPS_Cnt = 1; rCalc.receivedTP = nbytes; } else { rCalc.receivedSpendMsec = new Date().getTime() - rCalc.receivedTimespec; //console.log("calcReceivedFpsAndTp rCalc.receivedSpendMsec:"+rCalc.receivedSpendMsec); rCalc.receivedFPS_Cnt++; rCalc.receivedTP += nbytes; if( rCalc.receivedSpendMsec >= 1000 )//OVER 1SEC { rCalc.receivedFPS_Cnt -= 1; rCalc.lastReceivedTP = rCalc.receivedTP - nbytes; if( rCalc.lastReceivedFPS != rCalc.receivedFPS_Cnt ) rCalc.lastReceivedFPS = rCalc.receivedFPS_Cnt; //rCalc.lastReceivedFPS = rCalc.receivedFPS_Cnt; rCalc.receivedFPS_Cnt = 1; rCalc.receivedString = getReceivedCalcString( rCalc ); rCalc.receivedTimespec = rCalc.receivedSpendMsec = 0; } } } var g_Ctx = null; var g_DecodeStatus = 0; var g_SanpShot = 0; var g_Record = 0; var g_SanpShotFile = null; var g_RecordFile = null; var g_VideoType = null; var g_AudioType = null; var g_SampleRate = null; var g_BitRate = null; var g_Fps = null; var g_Width = null; var g_Height = null; function ws_worker_close(decCore, workerNum) { decCore.ws_worker[workerNum].postMessage("close"); mywaiting(300); decCore.ws_worker[workerNum].terminate(); mywaiting(300); decCore.ws_worker[workerNum] = null; } function _codec( para ) { var decCore = this; decCore.yuvCanvas = []; decCore.worker = []; //h.264 decoder worker. decCore.ws_worker = []; //websocket worker. decCore.ws = []; //decCore.audio_worker = []; decCore.eventSrc = []; decCore.lastJsonTimeString = ""; decCore.lastJsonTime = 0; decCore.iframeCnt = []; decCore.streamMode = getDefaultStreamMode(); decCore.isMob = isMobBs(); decCore.regServerCmdCb = []; decCore.disconnectCb = []; decCore.byte_handle = []; decCore.valid_byte_received = []; decCore.streamInfo = []; decCore.blank_timer = 0; decCore.rCalc = []; decCore.codecInfo = new _codecInformation(); decCore.calcDecodedFpsAndTp = calcDecodedFpsAndTp; decCore.calcReceivedFpsAndTp = calcReceivedFpsAndTp; decCore.dropLatencyDecoded = para.droplatencydecoded; decCore.playback_info = null; decCore.buffering_activated = false; decCore.buffering_ctrl = []; decCore.activate_buffering = function() { decCore.buffering_activated = true; }; decCore.disable_buffering = function() { decCore.buffering_activated = false; decCore.buffering_ctrl = []; }; decCore.init_ffdecodecWorker = 0; decCore.Queue = []; //decCore.h264ModuleFS = 524288; function uni_event_struct( eventType, url ) { this.eventType = eventType; this.url = url; this.evtStatus = 0; this.evt = null; }; for ( var i = 0; i < para.worker_num; i++ ) { decCore.eventSrc[ i ] = new uni_event_struct( 1, "" ); } decCore.para = para; decCore.refpath = window.location.origin + window.location.pathname decCore.refpath = decCore.refpath.substring( 0, decCore.refpath.lastIndexOf( "/" ) ); for ( var i = 0; i < para.worker_num; i++ ) { //console.log("para.worker_num:"+para.worker_num+" i:"+i); decCore.para.decode[ i ] = DATAH264;//default decCore.yuvCanvas[ i ] = new YUVCanvas( { width: para.vc[ i ].width, height: para.vc[ i ].height, contextOptions: null } ); decCore.byte_handle[ i ] = true; decCore.valid_byte_received[ i ] = false; decCore.rCalc[ i ] = new _recvCalc; } decCore.init_worker = function( workerNum ) { decCore.initDecodeWorker ( workerNum, decCore.refpath, decCore.para.vc[ workerNum ], decCore.para.decode[ workerNum ] ); }; decCore.initDecodeWorker = function ( workerNum, refpath, vc , dec ) { //hevc or h264 var tmp = function () { var waitCount = 1; var RuntimeInitializedTime = 0; importScripts( "sCriPtSrc" ); // register all compiled codecs var onRuntimeInitialized = function() { if (typeof Module.asm == "undefined") { console.log("typeof Module.asm == undefined\n"); waitCount++; RuntimeInitializedTime = setTimeout(onRuntimeInitialized, (1000*waitCount)); return; } this.ctx = null; this.snapshot = 0; this.recorder = 0; this.decodeOnEnd = true; this.decodedFrame = null; this._SnapShot = null; this._RecordStart = null; this._Record_Stop = null; this.objectUrl = null; var blobSelf = this; function innerWorkerDecode(e) { blobSelf.decodeOnEnd = false; var MD = e.data; var codecinfo = MD.info; var data = MD.data; if(blobSelf.ctx == null) { //console.log("codecinfo.audioType:"+codecinfo.audioType); blobSelf.ctx = _decode_init( codecinfo.videoType, codecinfo.audioType, codecinfo.width, codecinfo.height, codecinfo.sampleRate, codecinfo.bitRate, codecinfo.FPS); } if((codecinfo.snapshot == 0) && (blobSelf._SnapShot != null) && (blobSelf.ctx)) { blobSelf._SnapShot = null; blobSelf.objectUrl = null; } else if((codecinfo.snapshot == 1) && (blobSelf._SnapShot == null) && (blobSelf.ctx)) { blobSelf.snapshot++; blobSelf._SnapShot = Module.cwrap('SnapShot','number', ['number', 'string']); if(_SnapShot) var ret = blobSelf._SnapShot(blobSelf.ctx, codecinfo.snapshotFile); } if((codecinfo.recorder == 0) && (blobSelf._RecordStart != null) && (blobSelf.ctx)) { blobSelf._RecordStart = null; blobSelf._RecordStop = null; blobSelf.objectUrl = null; } else if((codecinfo.recorder == 1) && (blobSelf._RecordStart == null) && (blobSelf.ctx)) { //console.log("blobSelf.recorder:"+blobSelf.recorder); //console.log("worker codecinfo.recorder == 1"); blobSelf.recorder++; blobSelf._RecordStart = Module.cwrap('RecordStart','number', ['number', 'string']); if(blobSelf._RecordStart) var ret = blobSelf._RecordStart(blobSelf.ctx, codecinfo.recorderFile); } else if((blobSelf.recorder == 1) && (codecinfo.recorder == 2) && (blobSelf.ctx)) { //console.log("blobSelf.recorder:"+blobSelf.recorder); //console.log("worker codecinfo.recorder == 2"); blobSelf._Record_Stop = Module.cwrap('Record_Stop', 'number', ['number']); if(blobSelf._Record_Stop) { var iRet = blobSelf._Record_Stop(blobSelf.ctx); if(iRet == 0) blobSelf.recorder++; } } var av_pktData = Module._malloc(data.pktSize); Module.writeArrayToMemory( data.pktData, av_pktData); var skip = 0; var decoded_frame = null; if(blobSelf.ctx) decoded_frame = _decode_video(blobSelf.ctx, av_pktData, data.pktSize, data.dataType, skip); Module._free(av_pktData); if(decoded_frame) { var frame_width = Module.getValue(decoded_frame + 68, 'i32'); //console.log("frame_width:"+frame_width); var frame_height = Module.getValue(decoded_frame + 72, 'i32'); //console.log("frame_height:"+frame_height); if((frame_width == 0)|| (frame_height == 0)) { blobSelf.decodeOnEnd = true; return null; //Is audio } if ( ( frame_width == 1080 ) && ( frame_height == 1920 ) ) { frame_width = 1088; frame_height = 1920; } else if ( ( frame_width == 1944 ) && ( frame_height == 2592 ) ) { frame_width = 1952; frame_height = 2592; } if(blobSelf.snapshot > 0) { try { //console.log("readfile codecinfo.snapshotFile:"+codecinfo.snapshotFile); var data = Module.FS.readFile(codecinfo.snapshotFile); if(data) { blobSelf.objectUrl = URL.createObjectURL(new Blob([data], { type: "image/jpeg" })); //console.log("snapshot objectUrl:"+objectUrl); blobSelf.snapshot = 0; } } catch (e) { //console.log("readFile error!"); } } if((blobSelf.recorder == 2) && (codecinfo.recorder == 2)) { try { //console.log("blobSelf.recorder:"+blobSelf.recorder); //console.log("readfile codecinfo.recorderFile:"+codecinfo.recorderFile); var data = Module.FS.readFile(codecinfo.recorderFile); if(data) { blobSelf.objectUrl = URL.createObjectURL(new Blob([data], { type: "video/mp4" })); //console.log("recorder objectUrl:"+objectUrl); blobSelf.recorder = 0; } } catch (e) { //console.log("readFile error!"); } } // copy Y channel to canvas var frameYDataPtr = Module.getValue(decoded_frame, '*'); var frameUDataPtr = Module.getValue(decoded_frame + 4, '*'); var frameVDataPtr = Module.getValue(decoded_frame + 8, '*'); blobSelf.decodeOnEnd = true; return { frame_width: frame_width, frame_height: frame_height, frameYDataPtr: frameYDataPtr, frameUDataPtr: frameUDataPtr, frameVDataPtr: frameVDataPtr, frameYData: new Uint8Array(Module.HEAPU8.buffer.slice(frameYDataPtr, frameYDataPtr + frame_width * frame_height)), frameUData: new Uint8Array(Module.HEAPU8.buffer.slice(frameUDataPtr, frameUDataPtr + frame_width / 2 * frame_height / 2)), frameVData: new Uint8Array(Module.HEAPU8.buffer.slice(frameVDataPtr, frameVDataPtr + frame_width / 2 * frame_height / 2)), frameTime: null, downloadUrl: blobSelf.objectUrl, }; } else console.log("no decoded_frame"); } blobSelf.onmessage = function (e) { if ( e.data != null ) { var MD = e.data; var data = MD.data; var codecinfo = MD.info; if(blobSelf.decodeOnEnd == true) blobSelf.decodedFrame = innerWorkerDecode(e); if(blobSelf.decodedFrame) { //decodedFrame.frameTime = decodedFrame.frameTime; decodedFrame.downloadUrl = decodedFrame.downloadUrl, blobSelf.postMessage( blobSelf.decodedFrame, [ blobSelf.decodedFrame.frameYData.buffer, blobSelf.decodedFrame.frameUData.buffer, blobSelf.decodedFrame.frameVData.buffer, ] ); } } } } RuntimeInitializedTime = setTimeout(onRuntimeInitialized, 1000); }.toString(); var tmp2 = tmp.replace( "sCriPtSrc", ( refpath + "/unit3.js" )); var tmp3 = tmp2.replace( "asmjsdecode", ( ( dec == DATAH264 ) ? "h264" : "hevc" ) ); var tmp4 = tmp3.replace( "_pktDataSize_", ( ( detectBrowser().safari ) ? 524288 : 1048576 ) ); tmp = tmp2 = tmp3 = null; var blob = new Blob( [ '(',tmp4, ')()' ],{ type: 'text/javascript' } ); var blobURL = window.URL.createObjectURL( blob ); decCore.worker[ workerNum ] = new Worker( blobURL ); //Original Version decCore.worker[ workerNum ].onmessage = function (e) { var skip = 0; var decodedFrame = e.data; try { //console.log("decCore.codecInfo.snapshot:"+decCore.codecInfo.snapshot); if(decCore.codecInfo.snapshot == 1) { //console.log("decodedFrame.downloadUrl:"+decodedFrame.downloadUrl); if((decodedFrame.downloadUrl != "") && (decodedFrame.downloadUrl != undefined)) { const objectUrl = decodedFrame.downloadUrl;//URL.createObjectURL(new Blob([data], { type: "image/jpeg" }));//URL.createObjectURL(blob); const a = document.createElement('a'); a.setAttribute('href', objectUrl); a.setAttribute('download', decCore.codecInfo.snapshotFile); document.body.appendChild(a); a.click(); document.body.removeChild(a); decCore.codecInfo.snapshot = 0; decCore.codecInfo.snapshotFile = null; } } } catch (e) { console.log("download error!"); } try { //console.log("decCore.codecInfo.recorder:"+decCore.codecInfo.recorder); if(decCore.codecInfo.recorder == 2) { //console.log("decodedFrame.downloadUrl:"+decodedFrame.downloadUrl); if((decodedFrame.downloadUrl != "") && (decodedFrame.downloadUrl != undefined)) { const objectUrl = decodedFrame.downloadUrl;//URL.createObjectURL(new Blob([data], { type: "image/jpeg" }));//URL.createObjectURL(blob); const a = document.createElement('a'); a.setAttribute('href', objectUrl); a.setAttribute('download', decCore.codecInfo.recorderFile); document.body.appendChild(a); a.click(); document.body.removeChild(a); decCore.codecInfo.recorder = 0; decCore.codecInfo.recorderFile = null; } } } catch (e) { console.log("download error!"); } if (!decCore.resetCalled) { if(decodedFrame) { decodedFrame.frameTime = decodedFrame.pktTime; decCore.yuvCanvas[ workerNum ].canvasElement.drawing = true; decCore.yuvCanvas[ workerNum ].drawNextOuptutPictureGL({ yData: decodedFrame.frameYData, yDataPerRow: decodedFrame.frame_width, yRowCnt: decodedFrame.frame_height, uData: decodedFrame.frameUData, uDataPerRow: decodedFrame.frame_width / 2, uRowCnt: decodedFrame.frame_height / 2, vData: decodedFrame.frameVData, vDataPerRow: decodedFrame.frame_width / 2, vRowCnt: decodedFrame.frame_height / 2 }); decCore.yuvCanvas[ workerNum ].canvasElement.drawing = false; decCore.calcDecodedFpsAndTp( decCore.rCalc[ workerNum ], { width: decodedFrame.frame_width, height: decodedFrame.frame_height, nbytes: 0, timestamp: decodedFrame.frameTime } ); } } };//.bind( decCore ); /*seems not effect diable*/ decCore.worker[ workerNum ].onclose = function () { console.log('Your worker instance has been closed'); }; decCore.worker[ workerNum ].onerror = function () { decCore.init_worker( workerNum );//retry }; // Won't be needing this anymore //Edge can't revoke //window.URL.revokeObjectURL(blobURL); }; //function innerWorkerDecode2(pktSize, pktData, dataType) function innerWorkerDecode2() { try { if(decCore.codecInfo.snapshot) { console.log("read file 1"); console.log("file name:"+decCore.codecInfo.snapshotFile); var data = Module.FS.readFile(decCore.codecInfo.snapshotFile); console.log("read file 2"); if(data) { console.log("read file 3"); const objectUrl = URL.createObjectURL(new Blob([data], { type: "image/jpeg" }));//URL.createObjectURL(blob); console.log("read file 4"); const a = document.createElement('a'); console.log("read file 5"); a.setAttribute('href', objectUrl); console.log("read file 6"); a.setAttribute('download', decCore.codecInfo.snapshotFile); console.log("read file 7"); document.body.appendChild(a); console.log("read file 8"); a.click(); console.log("read file 9"); document.body.removeChild(a); console.log("read file 10"); decCore.codecInfo.snapshotFile = null; decCore.codecInfo.snapshot = 0; } } } catch (e) { console.log("readFile error!"); } /* var av_pktData = Module._malloc(pktSize); Module.writeArrayToMemory( pktData, av_pktData); var decoded_frame = null; //console.log("innerWorkerDecode2 pktSize2:"+pktSize); //console.log("innerWorkerDecode2 avType:"+ avType+" dataType:"+dataType); if((g_Ctx) && g_DecodeStatus == 2) { //console.log("decCore.DecodeClose"); //_decode_close(g_Ctx); g_VideoType = g_AudioType = g_Width = g_Height = g_SampleRate = g_BitRate = g_Fps = 0; g_Ctx = null; } else if((g_Ctx) && g_DecodeStatus != 2) { decoded_frame = _decode_video(g_Ctx, av_pktData, pktSize, dataType); } else if(g_DecodeStatus == 1) { console.log("g_Ctx:"+g_Ctx+" g_DecodeStatus:"+g_DecodeStatus); //if((g_Width > 0) && (g_Height > 0) && (g_Ctx == null) && (g_DecodeStatus == 1)) g_Ctx = _decode_init(3, 5, 1920, 1080, 32000, 16000, 30, 0); if(g_Ctx) { console.log("get g_Ctx"); g_DecodeStatus = 3; } } if(decoded_frame) { var frame_width = Module.getValue(decoded_frame + 68, 'i32'); var frame_height = Module.getValue(decoded_frame + 72, 'i32'); if((frame_width == 0)|| (frame_height == 0)) return null; if ( ( frame_width == 1080 ) && ( frame_height == 1920 ) ) { frame_width = 1088; frame_height = 1920; } else if ( ( frame_width == 1944 ) && ( frame_height == 2592 ) ) { frame_width = 1952; frame_height = 2592; } // copy Y channel to canvas var frameYDataPtr = Module.getValue(decoded_frame, '*'); var frameUDataPtr = Module.getValue(decoded_frame + 4, '*'); var frameVDataPtr = Module.getValue(decoded_frame + 8, '*'); return { frame_width: frame_width, frame_height: frame_height, frameYDataPtr: frameYDataPtr, frameUDataPtr: frameUDataPtr, frameVDataPtr: frameVDataPtr, frameYData: new Uint8Array(Module.HEAPU8.buffer.slice(frameYDataPtr, frameYDataPtr + frame_width * frame_height)), frameUData: new Uint8Array(Module.HEAPU8.buffer.slice(frameUDataPtr, frameUDataPtr + frame_width / 2 * frame_height / 2)), frameVData: new Uint8Array(Module.HEAPU8.buffer.slice(frameVDataPtr, frameVDataPtr + frame_width / 2 * frame_height / 2)), frameTime: null, }; } Module._free(av_pktData);*/ }; decCore.DecodeInit = function(Video_type, Audio_type, width, height, fps, sample_rate, bit_rate) { console.log("width:"+width+" height:"+height+" fps:"+fps); //console.log("Video_type:%d, Audio_type:%d, sample_rate:%d, bit_rate:%d\n", Video_type, Audio_type, sample_rate, bit_rate); decCore.codecInfo.videoType = Video_type; decCore.codecInfo.audioType = DATATYPE_G711U; //Set audio type always MULAW by Sue, 2023/11/20 decCore.codecInfo.width = width; decCore.codecInfo.height = height; decCore.codecInfo.FPS = fps; decCore.codecInfo.sampleRate = sample_rate; decCore.codecInfo.bitRate = bit_rate; decCore.codecInfo.decodeStatus = 1; g_DecodeStatus = 1; }; decCore.DecodeClose = function() { decCore.codecInfo.decodeStatus = 2; } decCore.SnapShot = function() { var todays = new Date(); decCore.codecInfo.snapshotFile = String(todays.getFullYear())+('0'+String(eval(parseInt(todays.getMonth())+1))).substr(-2)+('0'+String(todays.getDate())).substr(-2)+('0'+String(todays.getHours())).substr(-2)+('0'+String(todays.getMinutes())).substr(-2)+('0'+String(todays.getSeconds())).substr(-2)+".jpeg"; //console.log("SnapShot filename:" + decCore.codecInfo.snapshotFile); decCore.codecInfo.snapshot = 1; //console.log("snapshot decCore.codecInfo.snapshot:"+decCore.codecInfo.snapshot); }; decCore.RecordStart = function() { console.log("RecordStart"); var todays = new Date(); decCore.codecInfo.recorderFile = String(todays.getFullYear())+('0'+String(eval(parseInt(todays.getMonth())+1))).substr(-2)+('0'+String(todays.getDate())).substr(-2)+('0'+String(todays.getHours())).substr(-2)+('0'+String(todays.getMinutes())).substr(-2)+('0'+String(todays.getSeconds())).substr(-2)+".mp4"; decCore.codecInfo.recorder = 1; }; decCore.RecordStop = function() { decCore.codecInfo.recorder = 2; }; decCore.decodeWorker = function ( workerNum, pktSize, pktData, pktTime, pktType, dataType) { var ret = 0; var transferableData = { pktTime: typeof pktTime != "undefined" ? pktTime : 0, pktSize: pktSize, pktData: pktData, byteOffset:pktData.byteOffset, dataType: dataType, } //console.log("decodeWorker dataType:"+dataType+" pktData:"+pktData); /*if((dataType == DATAH264) || (dataType == DATAH265) || (dataType == DATAJPEG)) { decCore.calcReceivedFpsAndTp( decCore.rCalc[ workerNum ], { nbytes: pktSize, timestamp: typeof pktTime != "undefined" ? pktTime : 0 } ); //Checking the decoded calc { if ( decCore.rCalc[ workerNum ].decodedTimestamp == 0 )//Not any decoded yet, so we should only feed the i frame { //console.log("pktType:"+pktType); if ((pktType != FRAME_I) && (dataType != DATAJPEG)) return ret; } else { _latency = decCore.rCalc[ workerNum ].receivedTimestamp - decCore.rCalc[ workerNum ].decodedTimestamp; //console.log( "decCore.decodeWorker decCore.rCalc[ "+workerNum+" ].receivedTimestamp:" + decCore.rCalc[ workerNum ].receivedTimestamp ); //console.log( "decCore.decodeWorker decCore.rCalc[ "+workerNum+" ].decodedTimestamp:" + decCore.rCalc[ workerNum ].decodedTimestamp ); decCore.rCalc[ workerNum ].latencyString = _latency + "ms"; if ( decCore.dropLatencyDecoded == true ) { if ( _latency > 2000 )//Over 2 second { decCore.rCalc[ workerNum ].iframe_bottleneck = 10; //console.log( "decode latency:" + _latency ); } if ( decCore.rCalc[ workerNum ].iframe_bottleneck ) { //console.log("pktType:"+pktType); if ( pktType != FRAME_I ) { //console.log("pktType != FRAME_I"); //return ret; } else decCore.rCalc[ workerNum ].iframe_bottleneck -= 1; } } } } }*/ //2017.03.06 for browser //original //console.log( "decCore.worker[" + workerNum + "].porstMessage" ); if ( ( decCore.worker[ workerNum ] != null ) && ( decCore.worker[ workerNum ] != "undefined" ) && ( typeof( decCore.worker[ workerNum ] ) != "undefined" ) ) decCore.worker[ workerNum ].postMessage( { 'info': decCore.codecInfo, 'data': transferableData } ); else ret = -1; return ret; }; decCore.reg_server_cmd_cb = function ( cmd_name, cb_func ) { //console.log("cmd_name:"+cmd_name); //{ multiswitchcmd: "wslivecmd?switch&streamtype=0&channel=" + ( i < 10 ? ("0" + i):i ), singleswitchcmd: "wslivecmd?switch&streamtype=1&channel=" + ( i < 10 ? ("0" + i):i )}; var reg_item = { name: "", func: function(){}, }; reg_item.name = cmd_name; reg_item.func = cb_func; if ( decCore.regServerCmdCb.length ) { for ( var i = 0; i < decCore.regServerCmdCb.length; i++ ) { if ( decCore.regServerCmdCb[ i ].name == cmd_name ) return; } } decCore.regServerCmdCb[ decCore.regServerCmdCb.length ] = reg_item; }; decCore.rm_certain_server_cmd_cb = function ( cmd_name ) { for( var search_cnt = 0; search_cnt < decCore.regServerCmdCb.length; search_cnt++ ) { if ( decCore.regServerCmdCb[ search_cnt ].name == cmd_name ) decCore.regServerCmdCb.splice( search_cnt, 1 ); } }; decCore.rm_server_cmd_cb = function() { console.log("decCore.rm_server_cmd_cb"); decCore.regServerCmdCb = []; }; decCore.drawBlank = function( workerNum ) { var nodata = new Uint8Array(1); decCore.yuvCanvas[ workerNum ].drawNextOuptutPictureGL({ yData: nodata, yDataPerRow: 1, yRowCnt: 1, uData: nodata, uDataPerRow: 1, uRowCnt: 1, vData: nodata, vDataPerRow: 1, vRowCnt: 1 }); decCore.rCalc[ workerNum ] = new _recvCalc; decCore.rCalc[ workerNum ].dataType = decCore.para.decode[ workerNum ]; }; decCore.terminate_worker = function( workerNum ) { try{ if ( decCore.worker[ workerNum ] != null ) { if ( decCore.ws_worker[ workerNum ] != "undefined" ) { if ( typeof( decCore.worker[ workerNum ] ) != "undefined" ) decCore.worker[ workerNum ].terminate(); } } decCore.worker[ workerNum ] = null; } catch(e) { console.log( "Catch error terminate_worker:" + workerNum ); }; }; decCore.ws_send = function( workerNum, val ) { switch ( decCore.streamMode ) { case WS: { if (( decCore.ws[ workerNum ] != null ) && ( decCore.ws[ workerNum ] != "undefined" )) { if( typeof val == "string" ) { decCore.ws[ workerNum ].send( val ); } } } break; case WS_WR: { if (( decCore.ws_worker[ workerNum ] != null ) && ( decCore.ws_worker[ workerNum ] != "undefined" )) { if ( typeof val == "string" ) decCore.ws_worker[ workerNum ].postMessage( val ); } } break; } }; decCore.disable_byte_handle = function( workerNum ) { decCore.byte_handle[ workerNum ] = false; if ( decCore.dropLatencyDecoded == true ) { decCore.rCalc[ workerNum ] = new _recvCalc; if ( decCore.iframeCnt[ workerNum ] <= 0 ) decCore.iframeCnt[ workerNum ] = 1; } }; decCore.enable_byte_handle = function( workerNum ) { decCore.byte_handle[ workerNum ] = true; }; decCore.get_recv_information = function( workerNum ) { return decCore.rCalc[ workerNum ].receivedString; }; decCore.get_dec_information = function( workerNum ) { return decCore.rCalc[ workerNum ].decodedString; }; decCore.get_latency_information = function( workerNum ) { return decCore.rCalc[ workerNum ].latencyString; }; decCore.switch_event = function( workerNum, eventType ) { { decCore.eventSrc[ workerNum ].eventType = eventType switch( decCore.streamMode ) { case WS: { switch ( eventType ) { case P_ONE_DEC_ONE_WS: decCore.ws[ workerNum ].onmessage = decCore.one_dec_wr_one_ws_wr; break; case P_MLT_DEC_MLT_WS: decCore.ws[ workerNum ].onmessage = decCore.multi_dec_wr_multi_ws_wr; break; case P_MLT_DEC_ONE_WS: decCore.ws[ workerNum ].onmessage = decCore.multi_dec_wr_one_ws_wr; break; case S_ONE_DEC_ONE_WS: decCore.ws[ workerNum ].onmessage = decCore.one_dec_wr_one_ws_wr; break; } } break; case WS_WR: { if ( decCore.ws_worker[ workerNum ] == null ) { console.log( workerNum + " ws_worker is null!" ); return; } switch ( eventType ) { case P_ONE_DEC_ONE_WS: decCore.ws_worker[ workerNum ].onmessage = decCore.one_dec_wr_one_ws_wr; break; case P_MLT_DEC_MLT_WS: decCore.ws_worker[ workerNum ].onmessage = decCore.multi_dec_wr_multi_ws_wr; break; case P_MLT_DEC_ONE_WS: decCore.ws_worker[ workerNum ].onmessage = decCore.multi_dec_wr_one_ws_wr; break; case S_ONE_DEC_ONE_WS: decCore.ws_worker[ workerNum ].onmessage = decCore.one_dec_wr_one_ws_wr; break; } } break; } } }; decCore.init_event = function ( eventType, workerNum, url ){ //console.log( "init_event: " + workerNum ); decCore.eventSrc[ workerNum ].url = url; decCore.eventSrc[ workerNum ].eventType = eventType; if ( decCore.isMob ) { decCore.iframeCnt[ workerNum ] = 1; } else { decCore.iframeCnt[ workerNum ] = 1; } switch ( decCore.streamMode ) { case WS: { var wspath = window.location.origin; if ( wspath.indexOf( "https" ) != -1 ) wspath = wspath.replace( "https", "wss" ); else wspath = wspath.replace( "http", "ws" ); decCore.ws[ workerNum ] = new WebSocket( ( wspath + ( url.substring( url.indexOf( "/"), url.length ) ) ) ); decCore.ws[ workerNum ].binaryType = 'arraybuffer'; switch ( eventType ) { case P_ONE_DEC_ONE_WS: decCore.ws[ workerNum ].onmessage = decCore.one_dec_wr_one_ws_wr; break; case P_MLT_DEC_MLT_WS: decCore.ws[ workerNum ].onmessage = decCore.multi_dec_wr_multi_ws_wr; break; case P_MLT_DEC_ONE_WS: decCore.ws[ workerNum ].onmessage = decCore.multi_dec_wr_one_ws_wr; break; case S_ONE_DEC_ONE_WS: decCore.ws[ workerNum ].onmessage = decCore.one_dec_wr_one_ws_wr; break; } decCore.ws[ workerNum ].onerror = function () { try { //if ( navigator.userAgent != "Firefox" ) // decCore.ws[ workerNum ].send( "wsclose" ); mywaiting( 300 ); decCore.ws[ workerNum ].close(); mywaiting( 300 ); decCore.ws[ workerNum ] = null; }catch(e){}; } mywaiting( 100 ); } break; case WS_WR: { var ws_blob_str = function() { var ws = null; var ws_blob = this; this.onmessage = function ( e ) { if ( e.data.search( "close" ) != -1 ) { console.log( e.data ); ws.send("wsclose"); } else if ( e.data.search( "wsplaybackcmd" ) != -1 ) { console.log( e.data ); ws.send( e.data ); } else if ( e.data.search( "wslivecmd") != -1 ) { console.log( e.data ); ws.send( e.data ); } else { console.log( e.data ); init( e.data ); } }; function init( url ) { ws = new WebSocket( url ); ws.binaryType = 'arraybuffer'; ws.onmessage = function ( e ) { ws_blob.postMessage( e.data ); } ws.onerror = function ( e ) { ws_blob.postMessage( "wsonerror" ); try{ //ws.send("wsclose"); ws.close(); }catch(e){}; } ws.onclose = function ( e ) { //setTimeout(function () { ws_worker_close(decCore, workerNum); //}, 1000); } } }.toString(); var blob = new Blob( [ '(',ws_blob_str, ')()' ],{ type: 'text/javascript' } ); var blobURL = window.URL.createObjectURL( blob ); decCore.ws_worker[ workerNum ] = new Worker( blobURL ); var wspath = window.location.origin; if ( wspath.indexOf( "https" ) != -1 ) wspath = wspath.replace( "https", "wss" ); else wspath = wspath.replace( "http", "ws" ); decCore.ws_worker[ workerNum ].postMessage( ( wspath + ( url.substring( url.indexOf( "/"), url.length ) ) ) );//start websocket switch ( eventType ) { case P_ONE_DEC_ONE_WS: decCore.ws_worker[ workerNum ].onmessage = decCore.one_dec_wr_one_ws_wr; break; case P_MLT_DEC_MLT_WS: decCore.ws_worker[ workerNum ].onmessage = decCore.multi_dec_wr_multi_ws_wr; break; case P_MLT_DEC_ONE_WS: decCore.ws_worker[ workerNum ].onmessage = decCore.multi_dec_wr_one_ws_wr; break; case S_ONE_DEC_ONE_WS: decCore.ws_worker[ workerNum ].onmessage = decCore.one_dec_wr_one_ws_wr; break; } decCore.ws_worker[ workerNum ].onerror = function ( e ) { //console.log( e ); try{ //console.log( "workerNum:" + workerNum + " onerror" ); ws_worker_close(decCore, workerNum); decCore.init_event(eventType, workerNum, url); }catch(e){}; } } break; case SES: { decCore.eventSrc[ workerNum ].evt = new EventSource( url ); switch ( eventType ) { case P_ONE_DEC_ONE_WS: decCore.eventSrc[ workerNum ].evt.onmessage = decCore.singleWorkerEvt; break; case P_MLT_DEC_MLT_WS: decCore.eventSrc[ workerNum ].evt.onmessage = decCore.multiWorkerEvt; break; case P_MLT_DEC_ONE_WS: decCore.eventSrc[ workerNum ].evt.onmessage = decCore.singleEvtMultiWorkerJSONContent; break; case S_ONE_DEC_ONE_WS: decCore.eventSrc[ workerNum ].evt.onmessage = decCore.singleEvtWorkerJSONContent; break; } decCore.eventSrc[ workerNum ].evt.onerror = function( event ) { //console.log( "onerror: " + this.url ); var txt; if( ( typeof( event ) != "undefined" ) && ( event != null ) && ( typeof( event.target ) != "undefined" ) && ( event.target != null ) ) { switch( event.target.readyState ){ // if reconnecting case EventSource.CONNECTING: txt = "Reconnect...."; break; // if error was fatal case EventSource.CLOSED: txt = "Closed, will not retry."; //close event connection event.target.onmessage = null; event.target.close(); break; } } }; //decCore.eventSrc[ workerNum ].evt.onopen = function( ) //{ // console.log( "Onopen: " + this ); //}; } break; } }; decCore.blank_timer_proc = function() { if ( decCore.blank_timer ) { clearTimeout( decCore.blank_timer ); } for( var i = 0; i < decCore.para.worker_num; i++ ) { if ( decCore.valid_byte_received[ i ] == true ) decCore.valid_byte_received[ i ] = false; else { if ( decCore.byte_handle[ i ] ) decCore.drawBlank( i ); } } decCore.blank_timer = setTimeout( decCore.blank_timer_proc, 1000 ); }; decCore.init_blank_timer = function() { if ( decCore.blank_timer == 0 ) decCore.blank_timer = setTimeout( decCore.blank_timer_proc, 1000 ); }; decCore.delete_blank_timer = function() { if ( decCore.blank_timer ) { clearTimeout( decCore.blank_timer ); decCore.blank_timer = 0; } }; decCore.terminate_event = function ( workerNum, blank ){ try{ if ( decCore.ws.length > workerNum ) { if ( decCore.ws[ workerNum ] != null ) { if ( decCore.ws[ workerNum ] != "undefined" ) { if ( typeof( decCore.ws[ workerNum ] ) != "undefined" ) { console.log( "ws close: " + workerNum ); //decCore.ws[ workerNum ].send("wsclose"); mywaiting( 300 ); decCore.ws[ workerNum ].close(); mywaiting( 300 ); decCore.ws[ workerNum ] = null; } } } } if ( decCore.ws_worker.length > workerNum ) { if ( decCore.ws_worker[ workerNum ] != null ) { if ( decCore.ws_worker[ workerNum ] != "undefined" ) { if ( typeof( decCore.ws_worker[ workerNum ] ) != "undefined" ) { decCore.ws_worker[ workerNum ].postMessage( "close" ); mywaiting( 300 ); decCore.ws_worker[ workerNum ].terminate(); mywaiting( 300 ); decCore.ws_worker[ workerNum ] = null; } } } } if ( decCore.eventSrc.length > workerNum ) { if ( decCore.eventSrc[ workerNum ] != null ) { if ( decCore.eventSrc[ workerNum ] != "undefined" ) { if ( ( decCore.eventSrc[ workerNum ].evt )&&( typeof( decCore.eventSrc[ workerNum ].evt ) == "object" ) ) { decCore.eventSrc[ workerNum ].evt.close(); decCore.eventSrc[ workerNum ].evt.onmessage = null; decCore.eventSrc[ workerNum ].evt = null; } } } } if( ( typeof( blank ) != "undefined" ) ) { if ( blank == 1 ) decCore.drawBlank( workerNum ); } else decCore.drawBlank( workerNum ); if ( decCore.buffering_activated ) decCore.buffering_ctrl = []; } catch(e) { console.log( "terminate_event error:" + workerNum ); }; }; decCore.isUniH264Data = function ( byte ) { console.log( "0x" + byte[0].toString(16) + byte[1].toString(16) + byte[2].toString(16) + byte[3].toString(16) + byte[4].toString(16) ); var ret = false; var header = new Uint8Array( 3 ); header[ 0 ] = byte[ 4 ] & 0x0F; //console.log( "shift index:" + header[ 0 ].toString(16) ); //console.log( "frame type:" + byte[ header[ 0 ] ].toString(16) ); header[ 1 ] = ~( byte[ header[ 0 ] ] ); //console.log( "~frame type:" + header[ 1 ].toString(16) ); header[ 2 ] = ( header[ 1 ] >> ( header[ 0 ] )) | header[ 1 ] << ( 8 - ( header[ 0 ] ) ); //console.log( "result:" + header[ 2 ].toString(16) ); switch( header[ 2 ] ) { case 0x21: case 0x41: case 0x61: case 0x67: case 0x68: case 0x65: case 0x27: case 0x28: case 0x25: byte[ 4 ] = header[ 2 ]; byte[ 0 ] = byte[ 1 ] = byte[ 2 ] = 0x0; byte[ 3 ] = 0x01; ret = true; break; } //console.log( "0x" + byte[0].toString(16) + byte[1].toString(16) + byte[2].toString(16) + byte[3].toString(16) + byte[4].toString(16) ); return ret; }; decCore.singleEvtWorkerJSONContent = function ( event ) { console.log("singleEvtWorkerJSONContent"); var obj = JSON.parse( event.data ); decCore.lastJsonTimeString = obj.time; if ( ( obj.h264 ) && ( ( typeof( obj.h264 ) != "undefined" ) ) ) { console.log("obj.h264:"+obj.h264); var byte = parseHexString( obj.h264 ); if ( decCore.isUniH264Data( byte ) ) decCore.decodeWorker( 0 , byte.length, byte ); } }; decCore.one_dec_wr_one_ws_wr = function ( e ) { if ( typeof e.data == "string" ) { var dataType; var dataSize; var dataBuffer; var frame_timestamp = Date.now(); //console.log("e.data:"+e.data); if ( e.data == "wsonerror" ) { if (( e.srcElement != null ) && ( typeof e.srcElement != "undefined" )) e.srcElement.onerror(); else if (( e.target != null ) && ( typeof e.target != "undefined" )) e.target.onerror(); } else if ( e.data.search( "wsservercmd?" ) != -1 )////from server { var cmd = e.data.replace( "wsservercmd?", "" ); //console.log("cmd: "+cmd); var cmdarray = cmd.split( "&" ); for ( var cmdcount = 0; cmdcount < cmdarray.length; cmdcount++ ) { var cmditem = cmdarray[ cmdcount ].split( "=" ); //console.log("cmdcount:"+cmdcount+" cmditem[0]: "+cmditem[0]); //console.log("cmdcount:"+cmdcount+" cmditem[1]: "+cmditem[1]); if(cmditem[1].search("G711") != -1) { //console.log("search G711"); //dataType = DATAG711U; dataType = DATATYPE_G711U; } else if(cmditem[1].search("AAC") != -1) { //console.log("search AAC"); //dataType = DATAAAC; dataType = DATATYPE_AAC; } if(cmditem[0].search("audio_0_type") != -1) { dataSize = cmditem[1].length; dataBuffer = cmditem[1]; //console.log("audio_0_type Buffer:"+dataBuffer); //console.log("audio_0_type Size:"+dataSize); } if(cmditem[0].search("audio_0_data") != -1) { //console.log("cmditem[1]:"+cmditem[1]); g_totalAudioData += cmditem[1]; //if (g_totalAudioData.length < ( AUDIO_LOWWATER ) ) //if(g_totalAudioData.length <= 2048) // return; dataBuffer = parseHexString(g_totalAudioData); dataSize = dataBuffer.length; //console.log("audio_0_data decoded:"+decoded); //console.log("audio_0_data dataSize:"+dataSize); //console.log("string decoded.length:"+decoded.length); } //now we can seach the register callback, if the name matched, put the value into the call back function for ( var registered_len = 0; registered_len < decCore.regServerCmdCb.length; registered_len++ ) { if ( decCore.regServerCmdCb[ registered_len ].name == cmditem[ 0 ] ) { decCore.regServerCmdCb[ registered_len ].func( cmditem[ 1 ] ); } else if ( cmditem[ 0 ].search( decCore.regServerCmdCb[ registered_len ].name ) != -1 )//not 100% match perhaps array { decCore.regServerCmdCb[ registered_len ].func( cmditem ); } } } if(dataSize > 24) { //let form = document.querySelector('form'); //form.file.value = "D:\fakepath\audio.aac"; //let fileReader = new FileReader(); //let file = form.file.files[0]; //fileReader.readAsArrayBuffer(file); if(decCore.decodeWorker(0, dataSize, dataBuffer, frame_timestamp, 0, dataType) != 0) { console.log( e ); if (( e.srcElement != null ) && ( typeof e.srcElement != "undefined" )) e.srcElement.onerror(); else if (( e.target != null ) && ( typeof e.target != "undefined" )) e.target.onerror(); } g_totalAudioData = ""; } } } else { if ( decCore.byte_handle[ 0 ] == false ) return; var byte = new Uint8Array( e.data ); //console.log("byte:"+byte); if ( ( isHeaderPreamble( byte ) ) && ( byte.length > 24 ) ) { var dataType = getHeaderDataType( byte ); //console.log("dataType:"+dataType); var ch_id = getHeaderId( byte ); var dec_id = 0; //var frame_type = FRAME_P; //var frame_timestamp = Date.now(); //decCore.lastJsonTime = getHeaderTime( byte ); //decCore.lastJsonTimeString = getHeaderTimeString( decCore.lastJsonTime ); decCore.valid_byte_received[ dec_id ] = true; if ( decCore.buffering_activated ) { _frame_t = getHeaderTime( byte ); if ( typeof decCore.buffering_ctrl[ dec_id ] == "undefined" ) { decCore.buffering_ctrl[ dec_id ] = { ch: ch_id, v_times: [], a_time: 0, v_pass: false, v_array : [], }; } if ( ( dataType == DATAH264 ) || ( dataType == DATAH265 ) ) { if ( decCore.buffering_ctrl[ dec_id ].ch != ch_id ) { decCore.buffering_ctrl[ dec_id ].ch = ch_id decCore.buffering_ctrl[ dec_id ].v_times = []; decCore.buffering_ctrl[ dec_id ].v_array = []; decCore.buffering_ctrl[ dec_id ].v_times.push( _frame_t ); decCore.buffering_ctrl[ dec_id ].v_array.push( byte ); return; } else { decCore.buffering_ctrl[ dec_id ].v_times.push( _frame_t ); decCore.buffering_ctrl[ dec_id ].v_array.push( byte ); if ( ( ( decCore.buffering_ctrl[ dec_id ].v_times[ 0 ] /*+ 1*/ ) < decCore.buffering_ctrl[ dec_id ].v_times[ decCore.buffering_ctrl[ dec_id ].v_times.length - 1 ] ) || //over 1sec ( decCore.buffering_ctrl[ dec_id ].v_times[ 0 ] > decCore.buffering_ctrl[ dec_id ].v_times[ decCore.buffering_ctrl[ dec_id ].v_times.length - 1 ] ) )//reverse { byte = decCore.buffering_ctrl[ dec_id ].v_array.shift(); } } } else { if ( decCore.buffering_ctrl[ dec_id ].a_time != _frame_t ) decCore.buffering_ctrl[ dec_id ].a_time = _frame_t; } } var frame_timestamp = Date.now(); var frame_type = FRAME_P; dataType = getHeaderDataType( byte ); //console.log("getHeaderDataType dataType:"+dataType); ch_id = getHeaderId( byte ); decCore.lastJsonTime = getHeaderTime( byte ); decCore.lastJsonTimeString = getHeaderTimeString( decCore.lastJsonTime ); //dec_id = ch_id % decCore.para.worker_num; /* chirun test var saveByteArray = (function () { var a = document.createElement("a"); document.body.appendChild(a); a.style = "display: none"; return function (data, name) { var blob = new Blob(data, {type: "octet/stream"}), url = window.URL.createObjectURL(blob); a.href = url; a.download = name; a.click(); window.URL.revokeObjectURL(url); }; }()); */ if ( dataType == DATAH264 ) { //console.log("dataType == DATAH264"); //console.log(byte.slice( 24 )); /* g_rec.push(byte.slice( 24 )); g_rec.push(byte.slice( 24 )); if(g_rec.length> 300) { console.log("g_rec.length " + g_rec.length); saveByteArray(g_rec, 'example.h264'); g_rec.length = 0; } */ decCore.rCalc[ 0 ].dataType = DATAH264; if ( decCore.para.decode[ 0 ] != DATAH264 ) { decCore.terminate_worker( 0 ); decCore.para.decode[ 0 ] = DATAH264; decCore.init_worker( 0 ); } if ( isH26XData( byte, 24 ) ) { if ( byte[ 28 ] == 0x67 ) frame_type = FRAME_I; if ( decCore.iframeCnt[ 0 ] > 0 ) { if ( frame_type == FRAME_I ) { //console.log( "dec_id: " + 0 + "ch_id: " + ch_id );s console.log("decCore.iframeCnt[ 0 ]:"+decCore.iframeCnt[ 0 ]); decCore.iframeCnt[ 0 ] -= 1; if ( decCore.iframeCnt[ 0 ] > 0 ) return; } else return; } if ( decCore.decodeWorker( 0, byte.length - 24 , byte.slice( 24 ), frame_timestamp, frame_type , dataType) != 0 ) { console.log( e ); if (( e.srcElement != null ) && ( typeof e.srcElement != "undefined" )) e.srcElement.onerror(); else if (( e.target != null ) && ( typeof e.target != "undefined" )) e.target.onerror(); } } } else if ( dataType == DATAH265 ) { decCore.rCalc[ 0 ].dataType = DATAH265; if ( decCore.para.decode[ 0 ] != DATAH265 ) { decCore.terminate_worker( 0 ); decCore.drawBlank( 0 ); decCore.para.decode[ 0 ] = DATAH265; decCore.init_worker( 0 ); } if ( isH26XData( byte, 24 ) ) { //console.log( "0x" + byte[24].toString(16) + byte[25].toString(16) + byte[26].toString(16) + byte[27].toString(16) + byte[28].toString(16) ); if ( ( H265_NALU( byte[ 24 + 4 ] ) == 32 ) || ( H265_NALU( byte[ 24 + 4 ] ) == 33 ) ) frame_type = FRAME_I; if ( decCore.iframeCnt[ 0 ] > 0 ) { if ( frame_type == FRAME_I ) { //console.log( "dec_id: " + 0 + "ch_id: " + ch_id ); decCore.iframeCnt[ 0 ] -= 1; if ( decCore.iframeCnt[ 0 ] > 0 ) return; } else return; } if ( decCore.decodeWorker( 0, byte.length - 24 , byte.slice( 24 ), frame_timestamp, frame_type, dataType) != 0 ) { console.log( e ); if (( e.srcElement != null ) && ( typeof e.srcElement != "undefined" )) e.srcElement.onerror(); else if (( e.target != null ) && ( typeof e.target != "undefined" )) e.target.onerror(); } } } else if(dataType == DATAJPEG) { //console.log("dataType == DATAJPEG"); decCore.rCalc[ 0 ].dataType = DATAJPEG; if ( decCore.para.decode[ 0 ] != DATAJPEG ) { //console.log("decCore.para.decode[ 0 ] != DATAJPEG"); decCore.terminate_worker( 0 ); decCore.drawBlank( 0 ); decCore.para.decode[ 0 ] = DATAJPEG; decCore.init_worker( 0 ); } //if ( isH26XData( byte, 24 ) ) { //console.log( "0x" + byte[24].toString(16) + byte[25].toString(16) + byte[26].toString(16) + byte[27].toString(16) + byte[28].toString(16) ); if ( decCore.decodeWorker( 0, byte.length - 24 , byte.slice( 24 ), frame_timestamp, frame_type, dataType) != 0 ) { console.log( e ); if (( e.srcElement != null ) && ( typeof e.srcElement != "undefined" )) e.srcElement.onerror(); else if (( e.target != null ) && ( typeof e.target != "undefined" )) e.target.onerror(); } } } else if ( dataType == DATAG711U ) { //console.log("decoded.length:"+decoded.length); for ( _registered_len = 0; _registered_len < decCore.regServerCmdCb.length; _registered_len++ ) { if ( decCore.regServerCmdCb[ _registered_len ].name == ( "audio_" + getHeaderChannel( byte ) ) ) { decCore.regServerCmdCb[ _registered_len ].func( { length : byte.length - 24, data: byte.slice( 24 ) } ); //decCore.regServerCmdCb[ _registered_len ].func( { length : decoded.length, data: decoded } ); break; } } /*if ( decCore.decodeWorker( 0, byte.length - 24 , byte.slice( 24 ), frame_timestamp, frame_type, dataType) != 0 ) { console.log( e ); if (( e.srcElement != null ) && ( typeof e.srcElement != "undefined" )) e.srcElement.onerror(); else if (( e.target != null ) && ( typeof e.target != "undefined" )) e.target.onerror(); }*/ } } //else // console.log( byte ); } }; decCore.singleEvtMultiWorkerJSONContent = function ( event ) { var actNum = event.lastEventId % decCore.para.worker_num; var obj = JSON.parse( event.data ); decCore.lastJsonTimeString = obj.time; if ( ( obj.h264 ) && ( ( typeof( obj.h264 ) != "undefined" ) ) ) { var byte = parseHexString( obj.h264 );//need testing if ( decCore.isUniH264Data( byte ) ) decCore.decodeWorker( actNum , byte.length, byte ); } }; decCore.multi_dec_wr_one_ws_wr = function ( e ) { if ( typeof e.data == "string" ) { console.log("decCore.multi_dec_wr_one_ws_wr string"); if ( e.data == "wsonerror" ) { if (( e.srcElement != null ) && ( typeof e.srcElement != "undefined" )) e.srcElement.onerror(); else if (( e.target != null ) && ( typeof e.target != "undefined" )) e.target.onerror(); } else if ( e.data.search( "wsservercmd?" ) != -1 )////from server { var cmd = e.data.replace( "wsservercmd?", "" ); var cmdarray = cmd.split( "&" ); for ( var cmdcount = 0; cmdcount < cmdarray.length; cmdcount++ ) { var cmditem = cmdarray[ cmdcount ].split( "=" ); //now we can seach the register callback, if the name matched, put the value into the call back function for ( var registered_len = 0; registered_len < decCore.regServerCmdCb.length; registered_len++ ) { if ( decCore.regServerCmdCb[ registered_len ].name == cmditem[ 0 ] ) decCore.regServerCmdCb[ registered_len ].func( cmditem[ 1 ] ); else if ( cmditem[ 0 ].search( decCore.regServerCmdCb[ registered_len ].name ) != -1 )//not 100% match perhaps array { decCore.regServerCmdCb[ registered_len ].func( cmditem ); } } } } else if ( e.data.search( "wsserverinfo?" ) != -1 )//just information from server not command { console.log( e.data ); if ( e.data.search( "wsserverinfo?playbackinfo=fps" ) != -1 ) { _info = e.data.replace( "wsserverinfo?playbackinfo=fps", "" ); _info_array = _info.split( "&" ); for ( _i = 0; _i < _info_array.length; _i++ ) { _info_item = _info_array[ _i ].split( "=" ); if ( _info_item[ 0 ] ) { _info_item_des = _info_item[ 0 ].split( "_" ); _ch = parseInt( _info_item_des[ 1 ], 10 ); if ( typeof _ch == "number" ) { if ( decCore.playback_info == null ) decCore.playback_info = []; if ( typeof decCore.playback_info[ _ch ] == "undefined" ) decCore.playback_info[ _ch ] = { v: 0, a: 0 }; if ( _info_item_des[ 2 ] == "v" ) decCore.playback_info[ _ch ].v = parseInt( _info_item[ 1 ], 10 ); if ( _info_item_des[ 2 ] == "a" ) decCore.playback_info[ _ch ].a = parseInt( _info_item[ 1 ], 10 ); } } } } else if ( e.data.search( "wsserverinfo?playbackinfo=state" ) != -1 ) { } } } else { var byte = new Uint8Array( e.data ); if ( ( isHeaderPreamble( byte ) ) && ( byte.length > 24 ) ) { var dataType = getHeaderDataType( byte ); var ch_id = getHeaderId( byte ); //var frame_timestamp = Date.now(); var dec_id = ch_id % decCore.para.worker_num; if ( decCore.byte_handle[ dec_id ] == false ) { //console.log( "dec_id: " + dec_id ); return; } decCore.valid_byte_received[ dec_id ] = true; if ( decCore.buffering_activated ) { _frame_t = getHeaderTime( byte ); if ( typeof decCore.buffering_ctrl[ dec_id ] == "undefined" ) { decCore.buffering_ctrl[ dec_id ] = { ch: ch_id, v_times: [], a_time: 0, v_pass: false, v_array : [], }; } if ( ( dataType == DATAH264 ) || ( dataType == DATAH265 ) ) { if ( decCore.buffering_ctrl[ dec_id ].ch != ch_id ) { decCore.buffering_ctrl[ dec_id ].ch = ch_id decCore.buffering_ctrl[ dec_id ].v_times = []; decCore.buffering_ctrl[ dec_id ].v_array = []; decCore.buffering_ctrl[ dec_id ].v_times.push( _frame_t ); decCore.buffering_ctrl[ dec_id ].v_array.push( byte ); return; } else { decCore.buffering_ctrl[ dec_id ].v_times.push( _frame_t ); decCore.buffering_ctrl[ dec_id ].v_array.push( byte ); if ( ( ( decCore.buffering_ctrl[ dec_id ].v_times[ 0 ] /*+ 1*/ ) < decCore.buffering_ctrl[ dec_id ].v_times[ decCore.buffering_ctrl[ dec_id ].v_times.length - 1 ] ) || //over 1sec ( decCore.buffering_ctrl[ dec_id ].v_times[ 0 ] > decCore.buffering_ctrl[ dec_id ].v_times[ decCore.buffering_ctrl[ dec_id ].v_times.length - 1 ] ) )//reverse { byte = decCore.buffering_ctrl[ dec_id ].v_array.shift(); } } } else { if ( decCore.buffering_ctrl[ dec_id ].a_time != _frame_t ) decCore.buffering_ctrl[ dec_id ].a_time = _frame_t; } } var frame_timestamp = Date.now(); var frame_type = FRAME_P; dataType = getHeaderDataType( byte ); ch_id = getHeaderId( byte ); dec_id = ch_id % decCore.para.worker_num; console.log( "ch_id:" + ch_id + " dec_id:" + dec_id ); decCore.lastJsonTime = getHeaderTime( byte ); decCore.lastJsonTimeString = getHeaderTimeString( decCore.lastJsonTime ); if ( dataType == DATAH264 ) { console.log("dataType == DATAH264....1"); if ( decCore.para.decode[ dec_id ] != DATAH264 ) { decCore.terminate_worker( dec_id ); decCore.para.decode[ dec_id ] = DATAH264; decCore.init_worker( dec_id ); } decCore.rCalc[ dec_id ].dataType = DATAH264; if ( isH26XData( byte, 24 ) ) { if ( byte[ 28 ] == 0x67 ) frame_type = FRAME_I; if ( decCore.iframeCnt[ dec_id ] > 0 ) { if ( frame_type == FRAME_I ) { //console.log( "dec_id: " + dec_id + "ch_id: " + ch_id ); decCore.iframeCnt[ dec_id ] -= 1; if ( decCore.iframeCnt[ dec_id ] > 0 ) return; } else return; } if ( decCore.decodeWorker( dec_id, byte.length - 24 , byte.slice( 24 ), frame_timestamp, frame_type ) != 0 ) { console.log( e ); if (( e.srcElement != null ) && ( typeof e.srcElement != "undefined" )) e.srcElement.onerror(); else if (( e.target != null ) && ( typeof e.target != "undefined" )) e.target.onerror(); } } else console.log( "~~~" ); } else if ( dataType == DATAH265 ) { console.log("dataType == DATAH265....1"); decCore.rCalc[ dec_id ].dataType = DATAH265; if ( decCore.para.decode[ dec_id ] != DATAH265 ) { decCore.terminate_worker( dec_id ); decCore.drawBlank( dec_id ); decCore.para.decode[ dec_id ] = DATAH265; decCore.init_worker( dec_id ); } if ( isH26XData( byte, 24 ) ) { if ( ( H265_NALU( byte[ 24 + 4 ] ) == 32 ) || ( H265_NALU( byte[ 24 + 4 ] ) == 33 ) ) frame_type = FRAME_I; if ( decCore.iframeCnt[ dec_id ] > 0 ) { if ( frame_type == FRAME_I ) { //console.log( "dec_id: " + dec_id + "ch_id: " + ch_id ); decCore.iframeCnt[ dec_id ] -= 1; if ( decCore.iframeCnt[ dec_id ] > 0 ) return; } else return; } if ( decCore.decodeWorker( ch_id % decCore.para.worker_num, byte.length - 24 , byte.slice( 24 ), frame_timestamp, frame_type ) != 0 ) { console.log( e ); if (( e.srcElement != null ) && ( typeof e.srcElement != "undefined" )) e.srcElement.onerror(); else if (( e.target != null ) && ( typeof e.target != "undefined" )) e.target.onerror(); } } } else if ( dataType == DATAG711U ) { console.log("dataType == DATAG711U....1"); for ( _registered_len = 0; _registered_len < decCore.regServerCmdCb.length; _registered_len++ ) { if ( decCore.regServerCmdCb[ _registered_len ].name == ( "audio_" + getHeaderChannel( byte ) ) ) { decCore.regServerCmdCb[ _registered_len ].func( { length : byte.length - 24, data: byte.slice( 24 ) } ); break; } } } } //else // console.log( byte ); } } decCore.multiWorkerEvt = function( event ) { var actNum = event.lastEventId % decCore.para.worker_num; var byte = parseHexString( event.data ); if ( decCore.isUniH264Data( byte ) ) { if( decCore.iframeCnt[ actNum ] > 0 ) { if( byte[ 4 ] == 0x67 ) { decCore.iframeCnt[ actNum ] -= 1; decCore.decodeWorker( actNum , byte.length, byte ); } } else decCore.decodeWorker( actNum, byte.length, byte ); } }; decCore.multi_dec_wr_multi_ws_wr = function (e) { if ( typeof e.data == "string" ) { if ( e.data == "wsonerror" ) { if (( e.srcElement != null ) && ( typeof e.srcElement != "undefined" )) e.srcElement.onerror(); else if (( e.target != null ) && ( typeof e.target != "undefined" )) e.target.onerror(); } else if ( e.data.search( "wsservercmd?" ) != -1 )////from server { var cmd = e.data.replace( "wsservercmd?", "" ); var cmdarray = cmd.split( "&" ); for ( var cmdcount = 0; cmdcount < cmdarray.length; cmdcount++ ) { var cmditem = cmdarray[ cmdcount ].split( "=" ); //now we can seach the register callback, if the name matched, put the value into the call back function for ( var registered_len = 0; registered_len < decCore.regServerCmdCb.length; registered_len++ ) { if ( decCore.regServerCmdCb[ registered_len ].name == cmditem[ 0 ] ) decCore.regServerCmdCb[ registered_len ].func( cmditem[ 1 ] ); else if ( cmditem[ 0 ].search( decCore.regServerCmdCb[ registered_len ].name ) != -1 )//not 100% match perhaps array { decCore.regServerCmdCb[ registered_len ].func( cmditem ); } } } } else if ( e.data.search( "wsserverinfo?" ) != -1 )//just information from server not command { console.log( e.data ); if ( e.data.search( "wsserverinfo?playbackinfo=fps" ) != -1 ) { _info = e.data.replace( "wsserverinfo?playbackinfo=fps", "" ); _info_array = _info.split( "&" ); for ( _i = 0; _i < _info_array.length; _i++ ) { _info_item = _info_array[ _i ].split( "=" ); if ( _info_item[ 0 ] ) { _info_item_des = _info_item[ 0 ].split( "_" ); _ch = parseInt( _info_item_des[ 1 ], 10 ); if ( typeof _ch == "number" ) { if ( decCore.playback_info == null ) decCore.playback_info = []; if ( typeof decCore.playback_info[ _ch ] == "undefined" ) decCore.playback_info[ _ch ] = { v: 0, a: 0 }; if ( _info_item_des[ 2 ] == "v" ) decCore.playback_info[ _ch ].v = parseInt( _info_item[ 1 ], 10 ); if ( _info_item_des[ 2 ] == "a" ) decCore.playback_info[ _ch ].a = parseInt( _info_item[ 1 ], 10 ); } } } } else if ( e.data.search( "wsserverinfo?playbackinfo=state" ) != -1 ) { } } //console.log( e ); //console.log( e.srcElement ); } else { var byte = new Uint8Array( e.data ); if ( ( isHeaderPreamble( byte ) )&&( byte.length > 24 ) ) { var dataType = getHeaderDataType( byte ); var ch_id = getHeaderId( byte ); //var frame_type = FRAME_P; //var frame_timestamp = Date.now(); var dec_id = ch_id % decCore.para.worker_num; if ( decCore.byte_handle[ dec_id ] == false ) return; decCore.valid_byte_received[ dec_id ] = true; if ( decCore.buffering_activated ) { _frame_t = getHeaderTime( byte ); if ( typeof decCore.buffering_ctrl[ dec_id ] == "undefined" ) { decCore.buffering_ctrl[ dec_id ] = { ch: ch_id, v_times: [], a_time: 0, v_pass: false, v_array : [], }; } if ( ( dataType == DATAH264 ) || ( dataType == DATAH265 ) ) { if ( decCore.buffering_ctrl[ dec_id ].ch != ch_id ) { decCore.buffering_ctrl[ dec_id ].ch = ch_id decCore.buffering_ctrl[ dec_id ].v_times = []; decCore.buffering_ctrl[ dec_id ].v_array = []; decCore.buffering_ctrl[ dec_id ].v_times.push( _frame_t ); decCore.buffering_ctrl[ dec_id ].v_array.push( byte ); return; } else { decCore.buffering_ctrl[ dec_id ].v_times.push( _frame_t ); decCore.buffering_ctrl[ dec_id ].v_array.push( byte ); if ( ( ( decCore.buffering_ctrl[ dec_id ].v_times[ 0 ] /*+ 1*/ ) < decCore.buffering_ctrl[ dec_id ].v_times[ decCore.buffering_ctrl[ dec_id ].v_times.length - 1 ] ) || //over 1sec ( decCore.buffering_ctrl[ dec_id ].v_times[ 0 ] > decCore.buffering_ctrl[ dec_id ].v_times[ decCore.buffering_ctrl[ dec_id ].v_times.length - 1 ] ) )//reverse { byte = decCore.buffering_ctrl[ dec_id ].v_array.shift(); } } } else { if ( decCore.buffering_ctrl[ dec_id ].a_time != _frame_t ) decCore.buffering_ctrl[ dec_id ].a_time = _frame_t; } } var frame_timestamp = Date.now(); var frame_type = FRAME_P; decCore.lastJsonTime = getHeaderTime( byte ); decCore.lastJsonTimeString = getHeaderTimeString( decCore.lastJsonTime ); dataType = getHeaderDataType( byte ); ch_id = getHeaderId( byte ); dec_id = ch_id % decCore.para.worker_num; //console.log( "ch_id:" + ch_id + " dec_id:" + dec_id ); if ( dataType == DATAH264 ) { console.log("dataType == DATAH264.....2"); if ( decCore.para.decode[ dec_id ] != DATAH264 ) { decCore.terminate_worker( dec_id ); decCore.para.decode[ dec_id ] = DATAH264; decCore.init_worker( dec_id ); } decCore.rCalc[ dec_id ].dataType = DATAH264; if ( isH26XData( byte, 24 ) ) { if ( byte[ 28 ] == 0x67 ) frame_type = FRAME_I; if ( decCore.iframeCnt[ dec_id ] > 0 ) { if ( frame_type == FRAME_I ) { //console.log( "dec_id: " + dec_id + "ch_id: " + ch_id ); decCore.iframeCnt[ dec_id ] -= 1; if ( decCore.iframeCnt[ dec_id ] > 0 ) return; } else return; } if ( decCore.decodeWorker( dec_id, byte.length - 24 , byte.slice( 24 ), frame_timestamp, frame_type ) != 0 ) { console.log( e ); if (( e.srcElement != null ) && ( typeof e.srcElement != "undefined" )) e.srcElement.onerror(); else if (( e.target != null ) && ( typeof e.target != "undefined" )) e.target.onerror(); } } } else if ( dataType == DATAH265 ) { decCore.rCalc[ dec_id ].dataType = DATAH265; if ( decCore.para.decode[ dec_id ] != DATAH265 ) { decCore.terminate_worker( dec_id ); decCore.drawBlank( dec_id ); decCore.para.decode[ dec_id ] = DATAH265; decCore.init_worker( dec_id ); } if ( isH26XData( byte, 24 ) ) { if ( ( H265_NALU( byte[ 24 + 4 ] ) == 32 ) || ( H265_NALU( byte[ 24 + 4 ] ) == 33 ) ) frame_type = FRAME_I; if ( decCore.iframeCnt[ dec_id ] > 0 ) { if ( frame_type == FRAME_I ) { //console.log( "dec_id: " + dec_id + "ch_id: " + ch_id ); decCore.iframeCnt[ dec_id ] -= 1; if ( decCore.iframeCnt[ dec_id ] > 0 ) return; } else return; } if ( decCore.decodeWorker( dec_id, byte.length - 24 , byte.slice( 24 ), frame_timestamp, frame_type ) != 0 ) { console.log( e ); if (( e.srcElement != null ) && ( typeof e.srcElement != "undefined" )) e.srcElement.onerror(); else if (( e.target != null ) && ( typeof e.target != "undefined" )) e.target.onerror(); } } } else if ( dataType == DATAG711U )// search is there register audio cb function { console.log("dataType == DATAG711U.....2"); for ( _registered_len = 0; _registered_len < decCore.regServerCmdCb.length; _registered_len++ ) { if ( decCore.regServerCmdCb[ _registered_len ].name == ( "audio_" + getHeaderChannel( byte ) ) ) { decCore.regServerCmdCb[ _registered_len ].func( { length : byte.length - 24, data: byte.slice( 24 ) } ); break; } } } } //else // console.log( "Preamble Error!" ); } }; decCore.singleWorkerEvt = function( event ) { var byte = parseHexString( event.data ) if ( decCore.isUniH264Data( byte ) ) { if( decCore.iframeCnt[ 0 ] > 0 ) { if( byte[ 4 ] == 0x67 ) { decCore.iframeCnt[ 0 ] -= 1; decCore.decodeWorker( 0 , byte.length, byte ); } } else decCore.decodeWorker( 0 , byte.length, byte ); } }; decCore.get_vc_element = function( workerNum ) { return decCore.yuvCanvas[ workerNum ].canvasElement; }; decCore.set_vc_element_size = function( workerNum, setting_width, setting_height ) { decCore.yuvCanvas[ workerNum ].canvasElement.style.width = ( setting_width + "px" ); decCore.yuvCanvas[ workerNum ].canvasElement.style.height = ( setting_height + "px" ); }; decCore.terminateYUV = function() { for ( var i = 0; i < decCore.para.worker_num; i++ ) decCore.yuvCanvas[ i ] = null; }; decCore.setDropLatencyDecoded = function( on_off ) { decCore.dropLatencyDecoded = on_off; if ( decCore.dropLatencyDecoded == true ) { for ( _i = 0; _i < decCore.rCalc.length; _i++ ) decCore.rCalc[ _i ] = new _recvCalc; for ( _i = 0; _i < decCore.worker.length; _i++ ) { if ( decCore.iframeCnt[ _i ] <= 0 ) decCore.iframeCnt[ _i ] = 1; } } }; for ( var i = 0; i < para.worker_num; i++ ) decCore.init_worker( i ); }