diff --git a/sdk/demo/demo.html b/sdk/demo/demo.html index c75a26601820b1d69baf3616c5a9965e56202494..1ad258c9380403e89afc128259e3e25cd0a63d2d 100644 --- a/sdk/demo/demo.html +++ b/sdk/demo/demo.html @@ -575,7 +575,7 @@ Copyright 2022 Huawei Cloud Computing Technology Co., Ltd. ...cloudPhoneParams, channelType: channelType, ticket: '256random'.padStart(256, '0'), - aes_key: '7f3545e9bd914d93a18409e6370dff33', + aes_key: '', auth_ts: new Date().getTime(), _debug: true, auto_rotate: true, @@ -833,15 +833,6 @@ Copyright 2022 Huawei Cloud Computing Technology Co., Ltd. buttonModalEle.style.display = 'none'; } - function setResolution() { - var dom = document.getElementById('resolution'); - if (!dom) { - return; - } - var resolution = dom.options[dom.selectedIndex || 0].value; - cloudapp.setResolution(CloudApp.RESOLUTIONS[resolution]); - } - function encodeUTF8(textStr) { var encodedStr = encodeURIComponent(textStr); var encodedArray = []; diff --git a/sdk/server.crt b/sdk/server.crt new file mode 100644 index 0000000000000000000000000000000000000000..8bc689b4a52550e3e19d463a2cb45f6377386c1a --- /dev/null +++ b/sdk/server.crt @@ -0,0 +1,89 @@ +-----BEGIN CERTIFICATE----- +MIIGBzCCBO+gAwIBAgIQBCVQRkPlmhgZOz1v0QumczANBgkqhkiG9w0BAQsFADBu +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMS0wKwYDVQQDEyRFbmNyeXB0aW9uIEV2ZXJ5d2hlcmUg +RFYgVExTIENBIC0gRzIwHhcNMjQxMjMwMDAwMDAwWhcNMjUwMzMwMjM1OTU5WjAi +MSAwHgYDVQQDExdody5kZW1vLmppbmhhb2tqLmNvbS5jbjCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBAPg985O12HOzDLHwZw2UnnR2yckLTXSCkqcWMDg4 +7sdWOvOtW0fj6Jysmbn2LTSQH2tKIgfO7AoEH79WnQEK+obyeDgWE/A6zUgkHZj9 +FV3yq5q0zINqt8s+bFq3HB3spO2FioaZcIhqDSyzgliF0WP4bZn1akzdb79ZCSKG +QVOdSb6pRAQUjXJomavuXe5g3zp6trh7EXMAQN0VlbT68tCBhUAGsTE0ON4iPE35 +xWcS7HLTl9XnENPzkpgRRmJpPDqsu/JD0Cyelptw1vWGr48IwuisADPRcun8R8EW +TkqRNTCgZ3L/DMiigXgvXHBsXKPxjl8tZ/d5VxPWE2z2XJ0CAwEAAaOCAuswggLn +MB8GA1UdIwQYMBaAFHjfkZBf7t6s9sV169VMVVPvJEq2MB0GA1UdDgQWBBTOyE18 +swZboFKklYtVNF8SSXfqhDAiBgNVHREEGzAZghdody5kZW1vLmppbmhhb2tqLmNv +bS5jbjA+BgNVHSAENzA1MDMGBmeBDAECATApMCcGCCsGAQUFBwIBFhtodHRwOi8v +d3d3LmRpZ2ljZXJ0LmNvbS9DUFMwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQG +CCsGAQUFBwMBBggrBgEFBQcDAjCBgAYIKwYBBQUHAQEEdDByMCQGCCsGAQUFBzAB +hhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wSgYIKwYBBQUHMAKGPmh0dHA6Ly9j +YWNlcnRzLmRpZ2ljZXJ0LmNvbS9FbmNyeXB0aW9uRXZlcnl3aGVyZURWVExTQ0Et +RzIuY3J0MAwGA1UdEwEB/wQCMAAwggF/BgorBgEEAdZ5AgQCBIIBbwSCAWsBaQB3 +AM8RVu7VLnyv84db2Wkum+kacWdKsBfsrAHSW3fOzDsIAAABlBWzkcwAAAQDAEgw +RgIhANYYrQA1wCVnfVkoLahKn4MNjBJOPUxtSBWB6JpMahWFAiEA+yc9Xxt+wAhI +cykEbIo5naOPK1pM6f0me7/qt62Lb1UAdgBzICIPCBaK+fPEposKsmqaSgDu9XeF +ighNBQDUpUJEWQAAAZQVs5HIAAAEAwBHMEUCIQCips8Q8ozMaQWBui1yDSlOBerU +P+cvHDZk2LEKHNKn/gIgDJBoVE5Qqpf6+YvKJKPEqUlfJhS/Xafr/qSuCHVXrlEA +dgDm0jFjQHeMwRBBBtdxuc7B0kD2loSG+7qHMh39HjeOUAAAAZQVs5HYAAAEAwBH +MEUCIHS0PTGzJxyvRv5MU6PeRqXtO/wUAQrxBHR4iG6SPXJOAiEAnU6OrVWJZBpQ +NTozJtUfR4VwaEcTqBSypt6nngZsjQMwDQYJKoZIhvcNAQELBQADggEBAHZ2FWJh +3RsDUi21emVmqYvFdUdzDd3rj9E8xnL4DfyVeK/G6Z8DzamlG3TRw0PeDSTn0sPz +dEp71UVtqKO2l5za+9w/mSdzh3nxqTQjUpIsnS+9ElcMsUsJzzSgOLosfPOd4Ht8 +14oDJezn/FdgdqSr8uWOMJXZcdLFZr19Hx/3Y1mbPb4jIptgbwhGU4Q32SgvpPqO +RV+A/96g28XgvxsouYoaoaaw30OL8GuADyuj+1XXDA3hzVdF6g9nGAWS62qedeL1 +tycqNBlbgu5ZKSot74s84Pqz8A7x1V7AowtLv5Cjnij1l2T6B35zEbJtCaZ0v+NF +wy91wnkOCbgMqkM= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEqjCCA5KgAwIBAgIQDeD/te5iy2EQn2CMnO1e0zANBgkqhkiG9w0BAQsFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH +MjAeFw0xNzExMjcxMjQ2NDBaFw0yNzExMjcxMjQ2NDBaMG4xCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xLTArBgNVBAMTJEVuY3J5cHRpb24gRXZlcnl3aGVyZSBEViBUTFMgQ0EgLSBH +MjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAO8Uf46i/nr7pkgTDqnE +eSIfCFqvPnUq3aF1tMJ5hh9MnO6Lmt5UdHfBGwC9Si+XjK12cjZgxObsL6Rg1njv +NhAMJ4JunN0JGGRJGSevbJsA3sc68nbPQzuKp5Jc8vpryp2mts38pSCXorPR+sch +QisKA7OSQ1MjcFN0d7tbrceWFNbzgL2csJVQeogOBGSe/KZEIZw6gXLKeFe7mupn +NYJROi2iC11+HuF79iAttMc32Cv6UOxixY/3ZV+LzpLnklFq98XORgwkIJL1HuvP +ha8yvb+W6JislZJL+HLFtidoxmI7Qm3ZyIV66W533DsGFimFJkz3y0GeHWuSVMbI +lfsCAwEAAaOCAU8wggFLMB0GA1UdDgQWBBR435GQX+7erPbFdevVTFVT7yRKtjAf +BgNVHSMEGDAWgBROIlQgGJXm427mD/r6uRLtBhePOTAOBgNVHQ8BAf8EBAMCAYYw +HQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMBIGA1UdEwEB/wQIMAYBAf8C +AQAwNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdp +Y2VydC5jb20wQgYDVR0fBDswOTA3oDWgM4YxaHR0cDovL2NybDMuZGlnaWNlcnQu +Y29tL0RpZ2lDZXJ0R2xvYmFsUm9vdEcyLmNybDBMBgNVHSAERTBDMDcGCWCGSAGG +/WwBAjAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5jb20vQ1BT +MAgGBmeBDAECATANBgkqhkiG9w0BAQsFAAOCAQEAoBs1eCLKakLtVRPFRjBIJ9LJ +L0s8ZWum8U8/1TMVkQMBn+CPb5xnCD0GSA6L/V0ZFrMNqBirrr5B241OesECvxIi +98bZ90h9+q/X5eMyOD35f8YTaEMpdnQCnawIwiHx06/0BfiTj+b/XQih+mqt3ZXe +xNCJqKexdiB2IWGSKcgahPacWkk/BAQFisKIFYEqHzV974S3FAz/8LIfD58xnsEN +GfzyIDkH3JrwYZ8caPTf6ZX9M1GrISN8HnWTtdNCH2xEajRa/h9ZBXjUyFKQrGk2 +n2hcLrfZSbynEC/pSw/ET7H5nWwckjmAJ1l9fcnbqkU/pf6uMQmnfl0JQjJNSg== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEgjCCA2qgAwIBAgIQBEbB7LuEYrWpF3L5qhjmezANBgkqhkiG9w0BAQsFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD +QTAeFw0yMzA4MTUwMDAwMDBaFw0zMTExMDkyMzU5NTlaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI +2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx +1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ +q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz +tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ +vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo4IBNDCC +ATAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUTiJUIBiV5uNu5g/6+rkS7QYX +jzkwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUwDgYDVR0PAQH/BAQD +AgGGMHYGCCsGAQUFBwEBBGowaDAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGln +aWNlcnQuY29tMEAGCCsGAQUFBzAChjRodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5j +b20vRGlnaUNlcnRHbG9iYWxSb290Q0EuY3J0MEIGA1UdHwQ7MDkwN6A1oDOGMWh0 +dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEdsb2JhbFJvb3RDQS5jcmww +EQYDVR0gBAowCDAGBgRVHSAAMA0GCSqGSIb3DQEBCwUAA4IBAQCVDWYaZnQ4F6Sq +Pvh0L4BW3CeDbvUrwuPypKgRvKk6RMY0hEN5CJKWtxXfQMF955d9k/7duBnEE8GM +pa4hhYiuaj5aITNR65I8QwUsOUibwLzOjTpGE9T524+I5UgbmsIVrQxZrQnT5EmR +3IDdtX+rJHASEgCTQeyEB3fR+Afiqtup45mJ502+lfLbLjJ/boMeQljP02L/JEL7 +k0WEihHGwa35Caz0z3CpFXf7FbJbcsQGl5QoySIPVXBWiDTw4Syf13zJy/uw4WO2 +gykqig+4k13VV8cppGXlzctCxvctARpBnwZgMO/OgssuDHNAsT2S9Q54bpJVC8OB +QYzCl1hF +-----END CERTIFICATE----- diff --git a/sdk/server.key b/sdk/server.key new file mode 100644 index 0000000000000000000000000000000000000000..7ad1cdb456bd7bd35e087548753c21f4b75a0cf5 --- /dev/null +++ b/sdk/server.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEA+D3zk7XYc7MMsfBnDZSedHbJyQtNdIKSpxYwODjux1Y6861b +R+PonKyZufYtNJAfa0oiB87sCgQfv1adAQr6hvJ4OBYT8DrNSCQdmP0VXfKrmrTM +g2q3yz5sWrccHeyk7YWKhplwiGoNLLOCWIXRY/htmfVqTN1vv1kJIoZBU51JvqlE +BBSNcmiZq+5d7mDfOnq2uHsRcwBA3RWVtPry0IGFQAaxMTQ43iI8TfnFZxLsctOX +1ecQ0/OSmBFGYmk8Oqy78kPQLJ6Wm3DW9YavjwjC6KwAM9Fy6fxHwRZOSpE1MKBn +cv8MyKKBeC9ccGxco/GOXy1n93lXE9YTbPZcnQIDAQABAoIBADAICJ+dcUadr8ik +G8Rwa6JcM5nfQnrXItoKfIT8WxMdt6Vbdwx3aBQcf1gQblm7wyCGxQPewSQE/UGP +2CwR/DxtIN61QuFZ90tMlZ965I37fMGf1uxckzhTmTKKOHn/xj+g9ZcqjDAQ2QC7 +sO5A4i1mLYq7BfjeZZdP+mkAMhajuEkLM4KDj7UoX11YMCoKYUwVI2SimJy+OvfP +MK98Zw4RQVD0mOXuKv45+UnF4hmm3ERTrv68tvZP1f5i0HdPFlpIMyc26tBmyNEN +5d6e1aAVpv/KJsufeemtS565BzSu6lbmGVJPQPjwohTYEyoy4d5DsXjwDJqOSk0Y +/Pl82N8CgYEA+hlSF+TGJZYvFnaZoLde+qBo8dkJ+6CqDzogOpyb08gvwkKqzUjp +cPG9Wm43j0OKUZ00LBkKBGXpJkdBGGsrx+KIHdVpo6N1MMLbAF2OiQcCqT20Wl7t +mLXYNT21ORwl2O3g83IE58W7vKsVgRGt0x5PqWUlfLIMroaDfiDSYhMCgYEA/hlq +GRSIxrYeBoUYOVbQPiDegs+DZCVlMI5Af1mjnrHoDAwrP8OwZrU6zyoZaHfNFfXQ +c8ERi29d/LWT6Osvu67U0Fp8eomiV7UPMVcpAwLnzkZvkMy9DznCWqVxvVtv7sCI +jmRad9xmXp4eh8YwaLFMgKMmPcTv4FXHOxNanI8CgYALty/vSpo1nIlsJfYgXzal +yunfmmkrTmVo/TIRTNDH5PLHyNOzdhzpW4mhONSFc4aBODn/btTXS+bWEjRsbmjI +nkX+D8c5ESkmNZqIs9k/dgKb5vYR3ayHoM0WAWQB3t2vAcWt4cN1EAAxYFpLh4Z7 +A0p8Bu7wnm6Vplt2hxcT3QKBgQCMZpaNTR9WTQLCL4B3DlT6P0czmF3NVCxZbACP +XYRfB4ZkQcUT8pjh53mbRnPLmYakf7Kygxeip+KS4/HaXTl+xteoWJc3Th15wP2o +EbUDiPN0ss6qf7ZnV07gr1HtgzyR+6h4pVKnsAyQc2YDN6s/7deLrJpQvyScHEl9 +hvAmWQKBgBenqP/ZvrCbwJPEk5YeFMLPHSmx0kHaNwxR4LVy+UjtkHDm/aAuAH3C +XXSe1rPQR51wvBSNVh7xzoyNZjrr/Gn1OImjnM7rZe9Nx/R6XMblhCPDrB8XYlBR +J+h5P4B9g0wgizWgZ+w9lLLeFTZyYWjbTg44qIucp1ZMoU8WOfrd +-----END RSA PRIVATE KEY----- diff --git a/sdk/src/3rd/video-codec-lib/X264Encoder.js b/sdk/src/3rd/video-codec-lib/X264Encoder.js index 2af68e84f90fc376b4f33479afe32b98c4746b77..6d2fb0826f2435badb5db4e1a5e12fcc09e7d988 100644 --- a/sdk/src/3rd/video-codec-lib/X264Encoder.js +++ b/sdk/src/3rd/video-codec-lib/X264Encoder.js @@ -1,12 +1,12 @@ -var Module = (() => { +var Module = (function() { var _scriptDir = typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : undefined; return ( function(Module) { Module = Module || {}; -var Module=typeof Module!="undefined"?Module:{};var readyPromiseResolve,readyPromiseReject;Module["ready"]=new Promise(function(resolve,reject){readyPromiseResolve=resolve;readyPromiseReject=reject});var moduleOverrides=Object.assign({},Module);var arguments_=[];var thisProgram="./this.program";var quit_=(status,toThrow)=>{throw toThrow};var ENVIRONMENT_IS_WEB=true;var ENVIRONMENT_IS_WORKER=false;var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var read_,readAsync,readBinary,setWindowTitle;if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){if(ENVIRONMENT_IS_WORKER){scriptDirectory=self.location.href}else if(typeof document!="undefined"&&document.currentScript){scriptDirectory=document.currentScript.src}if(_scriptDir){scriptDirectory=_scriptDir}if(scriptDirectory.indexOf("blob:")!==0){scriptDirectory=scriptDirectory.substr(0,scriptDirectory.replace(/[?#].*/,"").lastIndexOf("/")+1)}else{scriptDirectory=""}{read_=url=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText};if(ENVIRONMENT_IS_WORKER){readBinary=url=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}readAsync=(url,onload,onerror)=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=()=>{if(xhr.status==200||xhr.status==0&&xhr.response){onload(xhr.response);return}onerror()};xhr.onerror=onerror;xhr.send(null)}}setWindowTitle=title=>document.title=title}else{}var out=Module["print"]||console.log.bind(console);var err=Module["printErr"]||console.warn.bind(console);Object.assign(Module,moduleOverrides);moduleOverrides=null;if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];if(Module["quit"])quit_=Module["quit"];var POINTER_SIZE=4;function warnOnce(text){if(!warnOnce.shown)warnOnce.shown={};if(!warnOnce.shown[text]){warnOnce.shown[text]=1;err(text)}}function uleb128Encode(n){if(n<128){return[n]}return[n%128|128,n>>7]}function sigToWasmTypes(sig){var typeNames={"i":"i32","j":"i64","f":"f32","d":"f64","p":"i32"};var type={parameters:[],results:sig[0]=="v"?[]:[typeNames[sig[0]]]};for(var i=1;i{tempRet0=value};var wasmBinary;if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];var noExitRuntime=Module["noExitRuntime"]||true;if(typeof WebAssembly!="object"){abort("no native wasm support detected")}var wasmMemory;var ABORT=false;var EXITSTATUS;function assert(condition,text){if(!condition){abort(text)}}function getCFunc(ident){var func=Module["_"+ident];return func}function ccall(ident,returnType,argTypes,args,opts){var toC={"string":function(str){var ret=0;if(str!==null&&str!==undefined&&str!==0){var len=(str.length<<2)+1;ret=stackAlloc(len);stringToUTF8(str,ret,len)}return ret},"array":function(arr){var ret=stackAlloc(arr.length);writeArrayToMemory(arr,ret);return ret}};function convertReturnValue(ret){if(returnType==="string"){return UTF8ToString(ret)}if(returnType==="boolean")return Boolean(ret);return ret}var func=getCFunc(ident);var cArgs=[];var stack=0;if(args){for(var i=0;i=endIdx))++endPtr;if(endPtr-idx>16&&heapOrArray.buffer&&UTF8Decoder){return UTF8Decoder.decode(heapOrArray.subarray(idx,endPtr))}else{var str="";while(idx>10,56320|ch&1023)}}}return str}function UTF8ToString(ptr,maxBytesToRead){return ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead):""}function stringToUTF8Array(str,heap,outIdx,maxBytesToWrite){if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i=55296&&u<=57343){var u1=str.charCodeAt(++i);u=65536+((u&1023)<<10)|u1&1023}if(u<=127){if(outIdx>=endIdx)break;heap[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;heap[outIdx++]=192|u>>6;heap[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;heap[outIdx++]=224|u>>12;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;heap[outIdx++]=240|u>>18;heap[outIdx++]=128|u>>12&63;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}}heap[outIdx]=0;return outIdx-startIdx}function stringToUTF8(str,outPtr,maxBytesToWrite){return stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite)}function lengthBytesUTF8(str){var len=0;for(var i=0;i=55296&&u<=57343)u=65536+((u&1023)<<10)|str.charCodeAt(++i)&1023;if(u<=127)++len;else if(u<=2047)len+=2;else if(u<=65535)len+=3;else len+=4}return len}var UTF16Decoder=typeof TextDecoder!="undefined"?new TextDecoder("utf-16le"):undefined;function UTF16ToString(ptr,maxBytesToRead){var endPtr=ptr;var idx=endPtr>>1;var maxIdx=idx+maxBytesToRead/2;while(!(idx>=maxIdx)&&HEAPU16[idx])++idx;endPtr=idx<<1;if(endPtr-ptr>32&&UTF16Decoder){return UTF16Decoder.decode(HEAPU8.subarray(ptr,endPtr))}else{var str="";for(var i=0;!(i>=maxBytesToRead/2);++i){var codeUnit=HEAP16[ptr+i*2>>1];if(codeUnit==0)break;str+=String.fromCharCode(codeUnit)}return str}}function stringToUTF16(str,outPtr,maxBytesToWrite){if(maxBytesToWrite===undefined){maxBytesToWrite=2147483647}if(maxBytesToWrite<2)return 0;maxBytesToWrite-=2;var startPtr=outPtr;var numCharsToWrite=maxBytesToWrite>1]=codeUnit;outPtr+=2}HEAP16[outPtr>>1]=0;return outPtr-startPtr}function lengthBytesUTF16(str){return str.length*2}function UTF32ToString(ptr,maxBytesToRead){var i=0;var str="";while(!(i>=maxBytesToRead/4)){var utf32=HEAP32[ptr+i*4>>2];if(utf32==0)break;++i;if(utf32>=65536){var ch=utf32-65536;str+=String.fromCharCode(55296|ch>>10,56320|ch&1023)}else{str+=String.fromCharCode(utf32)}}return str}function stringToUTF32(str,outPtr,maxBytesToWrite){if(maxBytesToWrite===undefined){maxBytesToWrite=2147483647}if(maxBytesToWrite<4)return 0;var startPtr=outPtr;var endPtr=startPtr+maxBytesToWrite-4;for(var i=0;i=55296&&codeUnit<=57343){var trailSurrogate=str.charCodeAt(++i);codeUnit=65536+((codeUnit&1023)<<10)|trailSurrogate&1023}HEAP32[outPtr>>2]=codeUnit;outPtr+=4;if(outPtr+4>endPtr)break}HEAP32[outPtr>>2]=0;return outPtr-startPtr}function lengthBytesUTF32(str){var len=0;for(var i=0;i=55296&&codeUnit<=57343)++i;len+=4}return len}function writeArrayToMemory(array,buffer){HEAP8.set(array,buffer)}function writeAsciiToMemory(str,buffer,dontAddNull){for(var i=0;i>0]=str.charCodeAt(i)}if(!dontAddNull)HEAP8[buffer>>0]=0}var buffer,HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;function updateGlobalBufferAndViews(buf){buffer=buf;Module["HEAP8"]=HEAP8=new Int8Array(buf);Module["HEAP16"]=HEAP16=new Int16Array(buf);Module["HEAP32"]=HEAP32=new Int32Array(buf);Module["HEAPU8"]=HEAPU8=new Uint8Array(buf);Module["HEAPU16"]=HEAPU16=new Uint16Array(buf);Module["HEAPU32"]=HEAPU32=new Uint32Array(buf);Module["HEAPF32"]=HEAPF32=new Float32Array(buf);Module["HEAPF64"]=HEAPF64=new Float64Array(buf)}var INITIAL_MEMORY=Module["INITIAL_MEMORY"]||16777216;var wasmTable;var __ATPRERUN__=[];var __ATINIT__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;function keepRuntimeAlive(){return noExitRuntime}function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(__ATPRERUN__)}function initRuntime(){runtimeInitialized=true;callRuntimeCallbacks(__ATINIT__)}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}function addOnInit(cb){__ATINIT__.unshift(cb)}function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;function addRunDependency(id){runDependencies++;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}}function removeRunDependency(id){runDependencies--;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}if(runDependencies==0){if(runDependencyWatcher!==null){clearInterval(runDependencyWatcher);runDependencyWatcher=null}if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}function abort(what){{if(Module["onAbort"]){Module["onAbort"](what)}}what="Aborted("+what+")";err(what);ABORT=true;EXITSTATUS=1;what+=". Build with -sASSERTIONS for more info.";var e=new WebAssembly.RuntimeError(what);readyPromiseReject(e);throw e}var dataURIPrefix="data:application/octet-stream;base64,";function isDataURI(filename){return filename.startsWith(dataURIPrefix)}var wasmBinaryFile;wasmBinaryFile="X264Encoder.wasm";if(!isDataURI(wasmBinaryFile)){wasmBinaryFile=locateFile(wasmBinaryFile)}function getBinary(file){try{if(file==wasmBinaryFile&&wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(file)}else{throw"both async and sync fetching of the wasm failed"}}catch(err){abort(err)}}function getBinaryPromise(){if(!wasmBinary&&(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER)){if(typeof fetch=="function"){return fetch(wasmBinaryFile,{credentials:"same-origin"}).then(function(response){if(!response["ok"]){throw"failed to load wasm binary file at '"+wasmBinaryFile+"'"}return response["arrayBuffer"]()}).catch(function(){return getBinary(wasmBinaryFile)})}}return Promise.resolve().then(function(){return getBinary(wasmBinaryFile)})}function createWasm(){var info={"env":asmLibraryArg,"wasi_snapshot_preview1":asmLibraryArg};function receiveInstance(instance,module){var exports=instance.exports;Module["asm"]=exports;wasmMemory=Module["asm"]["memory"];updateGlobalBufferAndViews(wasmMemory.buffer);wasmTable=Module["asm"]["__indirect_function_table"];addOnInit(Module["asm"]["__wasm_call_ctors"]);removeRunDependency("wasm-instantiate")}addRunDependency("wasm-instantiate");function receiveInstantiationResult(result){receiveInstance(result["instance"])}function instantiateArrayBuffer(receiver){return getBinaryPromise().then(function(binary){return WebAssembly.instantiate(binary,info)}).then(function(instance){return instance}).then(receiver,function(reason){err("failed to asynchronously prepare wasm: "+reason);abort(reason)})}function instantiateAsync(){if(!wasmBinary&&typeof WebAssembly.instantiateStreaming=="function"&&!isDataURI(wasmBinaryFile)&&typeof fetch=="function"){return fetch(wasmBinaryFile,{credentials:"same-origin"}).then(function(response){var result=WebAssembly.instantiateStreaming(response,info);return result.then(receiveInstantiationResult,function(reason){err("wasm streaming compile failed: "+reason);err("falling back to ArrayBuffer instantiation");return instantiateArrayBuffer(receiveInstantiationResult)})})}else{return instantiateArrayBuffer(receiveInstantiationResult)}}if(Module["instantiateWasm"]){try{var exports=Module["instantiateWasm"](info,receiveInstance);return exports}catch(e){err("Module.instantiateWasm callback failed with error: "+e);return false}}instantiateAsync().catch(readyPromiseReject);return{}}var tempDouble;var tempI64;function callRuntimeCallbacks(callbacks){while(callbacks.length>0){callbacks.shift()(Module)}}function demangle(func){return func}function demangleAll(text){var regex=/\b_Z[\w\d_]+/g;return text.replace(regex,function(x){var y=demangle(x);return x===y?x:y+" ["+x+"]"})}var wasmTableMirror=[];function getWasmTableEntry(funcPtr){var func=wasmTableMirror[funcPtr];if(!func){if(funcPtr>=wasmTableMirror.length)wasmTableMirror.length=funcPtr+1;wasmTableMirror[funcPtr]=func=wasmTable.get(funcPtr)}return func}function jsStackTrace(){var error=new Error;if(!error.stack){try{throw new Error}catch(e){error=e}if(!error.stack){return"(no stack trace available)"}}return error.stack.toString()}function setWasmTableEntry(idx,func){wasmTable.set(idx,func);wasmTableMirror[idx]=wasmTable.get(idx)}function ___assert_fail(condition,filename,line,func){abort("Assertion failed: "+UTF8ToString(condition)+", at: "+[filename?UTF8ToString(filename):"unknown filename",line,func?UTF8ToString(func):"unknown function"])}var SYSCALLS={varargs:undefined,get:function(){SYSCALLS.varargs+=4;var ret=HEAP32[SYSCALLS.varargs-4>>2];return ret},getStr:function(ptr){var ret=UTF8ToString(ptr);return ret}};function ___syscall_fcntl64(fd,cmd,varargs){SYSCALLS.varargs=varargs;return 0}function ___syscall_fstat64(fd,buf){}function ___syscall_ioctl(fd,op,varargs){SYSCALLS.varargs=varargs;return 0}function ___syscall_lstat64(path,buf){}function ___syscall_newfstatat(dirfd,path,buf,flags){}function ___syscall_openat(dirfd,path,flags,varargs){SYSCALLS.varargs=varargs}function ___syscall_renameat(olddirfd,oldpath,newdirfd,newpath){}function ___syscall_stat64(path,buf){}function __embind_register_bigint(primitiveType,name,size,minRange,maxRange){}function getShiftFromSize(size){switch(size){case 1:return 0;case 2:return 1;case 4:return 2;case 8:return 3;default:throw new TypeError("Unknown type size: "+size)}}function embind_init_charCodes(){var codes=new Array(256);for(var i=0;i<256;++i){codes[i]=String.fromCharCode(i)}embind_charCodes=codes}var embind_charCodes=undefined;function readLatin1String(ptr){var ret="";var c=ptr;while(HEAPU8[c]){ret+=embind_charCodes[HEAPU8[c++]]}return ret}var awaitingDependencies={};var registeredTypes={};var typeDependencies={};var char_0=48;var char_9=57;function makeLegalFunctionName(name){if(undefined===name){return"_unknown"}name=name.replace(/[^a-zA-Z0-9_]/g,"$");var f=name.charCodeAt(0);if(f>=char_0&&f<=char_9){return"_"+name}return name}function createNamedFunction(name,body){name=makeLegalFunctionName(name);return function(){"use strict";return body.apply(this,arguments)}}function extendError(baseErrorType,errorName){var errorClass=createNamedFunction(errorName,function(message){this.name=errorName;this.message=message;var stack=new Error(message).stack;if(stack!==undefined){this.stack=this.toString()+"\n"+stack.replace(/^Error(:[^\n]*)?\n/,"")}});errorClass.prototype=Object.create(baseErrorType.prototype);errorClass.prototype.constructor=errorClass;errorClass.prototype.toString=function(){if(this.message===undefined){return this.name}else{return this.name+": "+this.message}};return errorClass}var BindingError=undefined;function throwBindingError(message){throw new BindingError(message)}var InternalError=undefined;function throwInternalError(message){throw new InternalError(message)}function whenDependentTypesAreResolved(myTypes,dependentTypes,getTypeConverters){myTypes.forEach(function(type){typeDependencies[type]=dependentTypes});function onComplete(typeConverters){var myTypeConverters=getTypeConverters(typeConverters);if(myTypeConverters.length!==myTypes.length){throwInternalError("Mismatched type converter count")}for(var i=0;i{if(registeredTypes.hasOwnProperty(dt)){typeConverters[i]=registeredTypes[dt]}else{unregisteredTypes.push(dt);if(!awaitingDependencies.hasOwnProperty(dt)){awaitingDependencies[dt]=[]}awaitingDependencies[dt].push(()=>{typeConverters[i]=registeredTypes[dt];++registered;if(registered===unregisteredTypes.length){onComplete(typeConverters)}})}});if(0===unregisteredTypes.length){onComplete(typeConverters)}}function registerType(rawType,registeredInstance,options={}){if(!("argPackAdvance"in registeredInstance)){throw new TypeError("registerType registeredInstance requires argPackAdvance")}var name=registeredInstance.name;if(!rawType){throwBindingError('type "'+name+'" must have a positive integer typeid pointer')}if(registeredTypes.hasOwnProperty(rawType)){if(options.ignoreDuplicateRegistrations){return}else{throwBindingError("Cannot register type '"+name+"' twice")}}registeredTypes[rawType]=registeredInstance;delete typeDependencies[rawType];if(awaitingDependencies.hasOwnProperty(rawType)){var callbacks=awaitingDependencies[rawType];delete awaitingDependencies[rawType];callbacks.forEach(cb=>cb())}}function __embind_register_bool(rawType,name,size,trueValue,falseValue){var shift=getShiftFromSize(size);name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":function(wt){return!!wt},"toWireType":function(destructors,o){return o?trueValue:falseValue},"argPackAdvance":8,"readValueFromPointer":function(pointer){var heap;if(size===1){heap=HEAP8}else if(size===2){heap=HEAP16}else if(size===4){heap=HEAP32}else{throw new TypeError("Unknown boolean type size: "+name)}return this["fromWireType"](heap[pointer>>shift])},destructorFunction:null})}function ClassHandle_isAliasOf(other){if(!(this instanceof ClassHandle)){return false}if(!(other instanceof ClassHandle)){return false}var leftClass=this.$$.ptrType.registeredClass;var left=this.$$.ptr;var rightClass=other.$$.ptrType.registeredClass;var right=other.$$.ptr;while(leftClass.baseClass){left=leftClass.upcast(left);leftClass=leftClass.baseClass}while(rightClass.baseClass){right=rightClass.upcast(right);rightClass=rightClass.baseClass}return leftClass===rightClass&&left===right}function shallowCopyInternalPointer(o){return{count:o.count,deleteScheduled:o.deleteScheduled,preservePointerOnDelete:o.preservePointerOnDelete,ptr:o.ptr,ptrType:o.ptrType,smartPtr:o.smartPtr,smartPtrType:o.smartPtrType}}function throwInstanceAlreadyDeleted(obj){function getInstanceTypeName(handle){return handle.$$.ptrType.registeredClass.name}throwBindingError(getInstanceTypeName(obj)+" instance already deleted")}var finalizationRegistry=false;function detachFinalizer(handle){}function runDestructor($$){if($$.smartPtr){$$.smartPtrType.rawDestructor($$.smartPtr)}else{$$.ptrType.registeredClass.rawDestructor($$.ptr)}}function releaseClassHandle($$){$$.count.value-=1;var toDelete=0===$$.count.value;if(toDelete){runDestructor($$)}}function downcastPointer(ptr,ptrClass,desiredClass){if(ptrClass===desiredClass){return ptr}if(undefined===desiredClass.baseClass){return null}var rv=downcastPointer(ptr,ptrClass,desiredClass.baseClass);if(rv===null){return null}return desiredClass.downcast(rv)}var registeredPointers={};function getInheritedInstanceCount(){return Object.keys(registeredInstances).length}function getLiveInheritedInstances(){var rv=[];for(var k in registeredInstances){if(registeredInstances.hasOwnProperty(k)){rv.push(registeredInstances[k])}}return rv}var deletionQueue=[];function flushPendingDeletes(){while(deletionQueue.length){var obj=deletionQueue.pop();obj.$$.deleteScheduled=false;obj["delete"]()}}var delayFunction=undefined;function setDelayFunction(fn){delayFunction=fn;if(deletionQueue.length&&delayFunction){delayFunction(flushPendingDeletes)}}function init_embind(){Module["getInheritedInstanceCount"]=getInheritedInstanceCount;Module["getLiveInheritedInstances"]=getLiveInheritedInstances;Module["flushPendingDeletes"]=flushPendingDeletes;Module["setDelayFunction"]=setDelayFunction}var registeredInstances={};function getBasestPointer(class_,ptr){if(ptr===undefined){throwBindingError("ptr should not be undefined")}while(class_.baseClass){ptr=class_.upcast(ptr);class_=class_.baseClass}return ptr}function getInheritedInstance(class_,ptr){ptr=getBasestPointer(class_,ptr);return registeredInstances[ptr]}function makeClassHandle(prototype,record){if(!record.ptrType||!record.ptr){throwInternalError("makeClassHandle requires ptr and ptrType")}var hasSmartPtrType=!!record.smartPtrType;var hasSmartPtr=!!record.smartPtr;if(hasSmartPtrType!==hasSmartPtr){throwInternalError("Both smartPtrType and smartPtr must be specified")}record.count={value:1};return attachFinalizer(Object.create(prototype,{$$:{value:record}}))}function RegisteredPointer_fromWireType(ptr){var rawPointer=this.getPointee(ptr);if(!rawPointer){this.destructor(ptr);return null}var registeredInstance=getInheritedInstance(this.registeredClass,rawPointer);if(undefined!==registeredInstance){if(0===registeredInstance.$$.count.value){registeredInstance.$$.ptr=rawPointer;registeredInstance.$$.smartPtr=ptr;return registeredInstance["clone"]()}else{var rv=registeredInstance["clone"]();this.destructor(ptr);return rv}}function makeDefaultHandle(){if(this.isSmartPointer){return makeClassHandle(this.registeredClass.instancePrototype,{ptrType:this.pointeeType,ptr:rawPointer,smartPtrType:this,smartPtr:ptr})}else{return makeClassHandle(this.registeredClass.instancePrototype,{ptrType:this,ptr:ptr})}}var actualType=this.registeredClass.getActualType(rawPointer);var registeredPointerRecord=registeredPointers[actualType];if(!registeredPointerRecord){return makeDefaultHandle.call(this)}var toType;if(this.isConst){toType=registeredPointerRecord.constPointerType}else{toType=registeredPointerRecord.pointerType}var dp=downcastPointer(rawPointer,this.registeredClass,toType.registeredClass);if(dp===null){return makeDefaultHandle.call(this)}if(this.isSmartPointer){return makeClassHandle(toType.registeredClass.instancePrototype,{ptrType:toType,ptr:dp,smartPtrType:this,smartPtr:ptr})}else{return makeClassHandle(toType.registeredClass.instancePrototype,{ptrType:toType,ptr:dp})}}function attachFinalizer(handle){if("undefined"===typeof FinalizationRegistry){attachFinalizer=handle=>handle;return handle}finalizationRegistry=new FinalizationRegistry(info=>{releaseClassHandle(info.$$)});attachFinalizer=handle=>{var $$=handle.$$;var hasSmartPtr=!!$$.smartPtr;if(hasSmartPtr){var info={$$:$$};finalizationRegistry.register(handle,info,handle)}return handle};detachFinalizer=handle=>finalizationRegistry.unregister(handle);return attachFinalizer(handle)}function ClassHandle_clone(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.preservePointerOnDelete){this.$$.count.value+=1;return this}else{var clone=attachFinalizer(Object.create(Object.getPrototypeOf(this),{$$:{value:shallowCopyInternalPointer(this.$$)}}));clone.$$.count.value+=1;clone.$$.deleteScheduled=false;return clone}}function ClassHandle_delete(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete){throwBindingError("Object already scheduled for deletion")}detachFinalizer(this);releaseClassHandle(this.$$);if(!this.$$.preservePointerOnDelete){this.$$.smartPtr=undefined;this.$$.ptr=undefined}}function ClassHandle_isDeleted(){return!this.$$.ptr}function ClassHandle_deleteLater(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete){throwBindingError("Object already scheduled for deletion")}deletionQueue.push(this);if(deletionQueue.length===1&&delayFunction){delayFunction(flushPendingDeletes)}this.$$.deleteScheduled=true;return this}function init_ClassHandle(){ClassHandle.prototype["isAliasOf"]=ClassHandle_isAliasOf;ClassHandle.prototype["clone"]=ClassHandle_clone;ClassHandle.prototype["delete"]=ClassHandle_delete;ClassHandle.prototype["isDeleted"]=ClassHandle_isDeleted;ClassHandle.prototype["deleteLater"]=ClassHandle_deleteLater}function ClassHandle(){}function ensureOverloadTable(proto,methodName,humanName){if(undefined===proto[methodName].overloadTable){var prevFunc=proto[methodName];proto[methodName]=function(){if(!proto[methodName].overloadTable.hasOwnProperty(arguments.length)){throwBindingError("Function '"+humanName+"' called with an invalid number of arguments ("+arguments.length+") - expects one of ("+proto[methodName].overloadTable+")!")}return proto[methodName].overloadTable[arguments.length].apply(this,arguments)};proto[methodName].overloadTable=[];proto[methodName].overloadTable[prevFunc.argCount]=prevFunc}}function exposePublicSymbol(name,value,numArguments){if(Module.hasOwnProperty(name)){if(undefined===numArguments||undefined!==Module[name].overloadTable&&undefined!==Module[name].overloadTable[numArguments]){throwBindingError("Cannot register public name '"+name+"' twice")}ensureOverloadTable(Module,name,name);if(Module.hasOwnProperty(numArguments)){throwBindingError("Cannot register multiple overloads of a function with the same number of arguments ("+numArguments+")!")}Module[name].overloadTable[numArguments]=value}else{Module[name]=value;if(undefined!==numArguments){Module[name].numArguments=numArguments}}}function RegisteredClass(name,constructor,instancePrototype,rawDestructor,baseClass,getActualType,upcast,downcast){this.name=name;this.constructor=constructor;this.instancePrototype=instancePrototype;this.rawDestructor=rawDestructor;this.baseClass=baseClass;this.getActualType=getActualType;this.upcast=upcast;this.downcast=downcast;this.pureVirtualFunctions=[]}function upcastPointer(ptr,ptrClass,desiredClass){while(ptrClass!==desiredClass){if(!ptrClass.upcast){throwBindingError("Expected null or instance of "+desiredClass.name+", got an instance of "+ptrClass.name)}ptr=ptrClass.upcast(ptr);ptrClass=ptrClass.baseClass}return ptr}function constNoSmartPtrRawPointerToWireType(destructors,handle){if(handle===null){if(this.isReference){throwBindingError("null is not a valid "+this.name)}return 0}if(!handle.$$){throwBindingError('Cannot pass "'+embindRepr(handle)+'" as a '+this.name)}if(!handle.$$.ptr){throwBindingError("Cannot pass deleted object as a pointer of type "+this.name)}var handleClass=handle.$$.ptrType.registeredClass;var ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);return ptr}function genericPointerToWireType(destructors,handle){var ptr;if(handle===null){if(this.isReference){throwBindingError("null is not a valid "+this.name)}if(this.isSmartPointer){ptr=this.rawConstructor();if(destructors!==null){destructors.push(this.rawDestructor,ptr)}return ptr}else{return 0}}if(!handle.$$){throwBindingError('Cannot pass "'+embindRepr(handle)+'" as a '+this.name)}if(!handle.$$.ptr){throwBindingError("Cannot pass deleted object as a pointer of type "+this.name)}if(!this.isConst&&handle.$$.ptrType.isConst){throwBindingError("Cannot convert argument of type "+(handle.$$.smartPtrType?handle.$$.smartPtrType.name:handle.$$.ptrType.name)+" to parameter type "+this.name)}var handleClass=handle.$$.ptrType.registeredClass;ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);if(this.isSmartPointer){if(undefined===handle.$$.smartPtr){throwBindingError("Passing raw pointer to smart pointer is illegal")}switch(this.sharingPolicy){case 0:if(handle.$$.smartPtrType===this){ptr=handle.$$.smartPtr}else{throwBindingError("Cannot convert argument of type "+(handle.$$.smartPtrType?handle.$$.smartPtrType.name:handle.$$.ptrType.name)+" to parameter type "+this.name)}break;case 1:ptr=handle.$$.smartPtr;break;case 2:if(handle.$$.smartPtrType===this){ptr=handle.$$.smartPtr}else{var clonedHandle=handle["clone"]();ptr=this.rawShare(ptr,Emval.toHandle(function(){clonedHandle["delete"]()}));if(destructors!==null){destructors.push(this.rawDestructor,ptr)}}break;default:throwBindingError("Unsupporting sharing policy")}}return ptr}function nonConstNoSmartPtrRawPointerToWireType(destructors,handle){if(handle===null){if(this.isReference){throwBindingError("null is not a valid "+this.name)}return 0}if(!handle.$$){throwBindingError('Cannot pass "'+embindRepr(handle)+'" as a '+this.name)}if(!handle.$$.ptr){throwBindingError("Cannot pass deleted object as a pointer of type "+this.name)}if(handle.$$.ptrType.isConst){throwBindingError("Cannot convert argument of type "+handle.$$.ptrType.name+" to parameter type "+this.name)}var handleClass=handle.$$.ptrType.registeredClass;var ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);return ptr}function simpleReadValueFromPointer(pointer){return this["fromWireType"](HEAP32[pointer>>2])}function RegisteredPointer_getPointee(ptr){if(this.rawGetPointee){ptr=this.rawGetPointee(ptr)}return ptr}function RegisteredPointer_destructor(ptr){if(this.rawDestructor){this.rawDestructor(ptr)}}function RegisteredPointer_deleteObject(handle){if(handle!==null){handle["delete"]()}}function init_RegisteredPointer(){RegisteredPointer.prototype.getPointee=RegisteredPointer_getPointee;RegisteredPointer.prototype.destructor=RegisteredPointer_destructor;RegisteredPointer.prototype["argPackAdvance"]=8;RegisteredPointer.prototype["readValueFromPointer"]=simpleReadValueFromPointer;RegisteredPointer.prototype["deleteObject"]=RegisteredPointer_deleteObject;RegisteredPointer.prototype["fromWireType"]=RegisteredPointer_fromWireType}function RegisteredPointer(name,registeredClass,isReference,isConst,isSmartPointer,pointeeType,sharingPolicy,rawGetPointee,rawConstructor,rawShare,rawDestructor){this.name=name;this.registeredClass=registeredClass;this.isReference=isReference;this.isConst=isConst;this.isSmartPointer=isSmartPointer;this.pointeeType=pointeeType;this.sharingPolicy=sharingPolicy;this.rawGetPointee=rawGetPointee;this.rawConstructor=rawConstructor;this.rawShare=rawShare;this.rawDestructor=rawDestructor;if(!isSmartPointer&®isteredClass.baseClass===undefined){if(isConst){this["toWireType"]=constNoSmartPtrRawPointerToWireType;this.destructorFunction=null}else{this["toWireType"]=nonConstNoSmartPtrRawPointerToWireType;this.destructorFunction=null}}else{this["toWireType"]=genericPointerToWireType}}function replacePublicSymbol(name,value,numArguments){if(!Module.hasOwnProperty(name)){throwInternalError("Replacing nonexistant public symbol")}if(undefined!==Module[name].overloadTable&&undefined!==numArguments){Module[name].overloadTable[numArguments]=value}else{Module[name]=value;Module[name].argCount=numArguments}}function dynCallLegacy(sig,ptr,args){var f=Module["dynCall_"+sig];return args&&args.length?f.apply(null,[ptr].concat(args)):f.call(null,ptr)}function dynCall(sig,ptr,args){if(sig.includes("j")){return dynCallLegacy(sig,ptr,args)}var rtn=getWasmTableEntry(ptr).apply(null,args);return rtn}function getDynCaller(sig,ptr){var argCache=[];return function(){argCache.length=0;Object.assign(argCache,arguments);return dynCall(sig,ptr,argCache)}}function embind__requireFunction(signature,rawFunction){signature=readLatin1String(signature);function makeDynCaller(){if(signature.includes("j")){return getDynCaller(signature,rawFunction)}return getWasmTableEntry(rawFunction)}var fp=makeDynCaller();if(typeof fp!="function"){throwBindingError("unknown function pointer with signature "+signature+": "+rawFunction)}return fp}var UnboundTypeError=undefined;function getTypeName(type){var ptr=___getTypeName(type);var rv=readLatin1String(ptr);_free(ptr);return rv}function throwUnboundTypeError(message,types){var unboundTypes=[];var seen={};function visit(type){if(seen[type]){return}if(registeredTypes[type]){return}if(typeDependencies[type]){typeDependencies[type].forEach(visit);return}unboundTypes.push(type);seen[type]=true}types.forEach(visit);throw new UnboundTypeError(message+": "+unboundTypes.map(getTypeName).join([", "]))}function __embind_register_class(rawType,rawPointerType,rawConstPointerType,baseClassRawType,getActualTypeSignature,getActualType,upcastSignature,upcast,downcastSignature,downcast,name,destructorSignature,rawDestructor){name=readLatin1String(name);getActualType=embind__requireFunction(getActualTypeSignature,getActualType);if(upcast){upcast=embind__requireFunction(upcastSignature,upcast)}if(downcast){downcast=embind__requireFunction(downcastSignature,downcast)}rawDestructor=embind__requireFunction(destructorSignature,rawDestructor);var legalFunctionName=makeLegalFunctionName(name);exposePublicSymbol(legalFunctionName,function(){throwUnboundTypeError("Cannot construct "+name+" due to unbound types",[baseClassRawType])});whenDependentTypesAreResolved([rawType,rawPointerType,rawConstPointerType],baseClassRawType?[baseClassRawType]:[],function(base){base=base[0];var baseClass;var basePrototype;if(baseClassRawType){baseClass=base.registeredClass;basePrototype=baseClass.instancePrototype}else{basePrototype=ClassHandle.prototype}var constructor=createNamedFunction(legalFunctionName,function(){if(Object.getPrototypeOf(this)!==instancePrototype){throw new BindingError("Use 'new' to construct "+name)}if(undefined===registeredClass.constructor_body){throw new BindingError(name+" has no accessible constructor")}var body=registeredClass.constructor_body[arguments.length];if(undefined===body){throw new BindingError("Tried to invoke ctor of "+name+" with invalid number of parameters ("+arguments.length+") - expected ("+Object.keys(registeredClass.constructor_body).toString()+") parameters instead!")}return body.apply(this,arguments)});var instancePrototype=Object.create(basePrototype,{constructor:{value:constructor}});constructor.prototype=instancePrototype;var registeredClass=new RegisteredClass(name,constructor,instancePrototype,rawDestructor,baseClass,getActualType,upcast,downcast);var referenceConverter=new RegisteredPointer(name,registeredClass,true,false,false);var pointerConverter=new RegisteredPointer(name+"*",registeredClass,false,false,false);var constPointerConverter=new RegisteredPointer(name+" const*",registeredClass,false,true,false);registeredPointers[rawType]={pointerType:pointerConverter,constPointerType:constPointerConverter};replacePublicSymbol(legalFunctionName,constructor);return[referenceConverter,pointerConverter,constPointerConverter]})}function heap32VectorToArray(count,firstElement){var array=[];for(var i=0;i>2])}return array}function runDestructors(destructors){while(destructors.length){var ptr=destructors.pop();var del=destructors.pop();del(ptr)}}function craftInvokerFunction(humanName,argTypes,classType,cppInvokerFunc,cppTargetFunc){var argCount=argTypes.length;if(argCount<2){throwBindingError("argTypes array size mismatch! Must at least get return value and 'this' types!")}var isClassMethodFunc=argTypes[1]!==null&&classType!==null;var needsDestructorStack=false;for(var i=1;i0);var rawArgTypes=heap32VectorToArray(argCount,rawArgTypesAddr);invoker=embind__requireFunction(invokerSignature,invoker);whenDependentTypesAreResolved([],[rawClassType],function(classType){classType=classType[0];var humanName="constructor "+classType.name;if(undefined===classType.registeredClass.constructor_body){classType.registeredClass.constructor_body=[]}if(undefined!==classType.registeredClass.constructor_body[argCount-1]){throw new BindingError("Cannot register multiple constructors with identical number of parameters ("+(argCount-1)+") for class '"+classType.name+"'! Overload resolution is currently only performed using the parameter count, not actual type info!")}classType.registeredClass.constructor_body[argCount-1]=()=>{throwUnboundTypeError("Cannot construct "+classType.name+" due to unbound types",rawArgTypes)};whenDependentTypesAreResolved([],rawArgTypes,function(argTypes){argTypes.splice(1,0,null);classType.registeredClass.constructor_body[argCount-1]=craftInvokerFunction(humanName,argTypes,null,invoker,rawConstructor);return[]});return[]})}function __embind_register_class_function(rawClassType,methodName,argCount,rawArgTypesAddr,invokerSignature,rawInvoker,context,isPureVirtual){var rawArgTypes=heap32VectorToArray(argCount,rawArgTypesAddr);methodName=readLatin1String(methodName);rawInvoker=embind__requireFunction(invokerSignature,rawInvoker);whenDependentTypesAreResolved([],[rawClassType],function(classType){classType=classType[0];var humanName=classType.name+"."+methodName;if(methodName.startsWith("@@")){methodName=Symbol[methodName.substring(2)]}if(isPureVirtual){classType.registeredClass.pureVirtualFunctions.push(methodName)}function unboundTypesHandler(){throwUnboundTypeError("Cannot call "+humanName+" due to unbound types",rawArgTypes)}var proto=classType.registeredClass.instancePrototype;var method=proto[methodName];if(undefined===method||undefined===method.overloadTable&&method.className!==classType.name&&method.argCount===argCount-2){unboundTypesHandler.argCount=argCount-2;unboundTypesHandler.className=classType.name;proto[methodName]=unboundTypesHandler}else{ensureOverloadTable(proto,methodName,humanName);proto[methodName].overloadTable[argCount-2]=unboundTypesHandler}whenDependentTypesAreResolved([],rawArgTypes,function(argTypes){var memberFunction=craftInvokerFunction(humanName,argTypes,classType,rawInvoker,context);if(undefined===proto[methodName].overloadTable){memberFunction.argCount=argCount-2;proto[methodName]=memberFunction}else{proto[methodName].overloadTable[argCount-2]=memberFunction}return[]});return[]})}var emval_free_list=[];var emval_handle_array=[{},{value:undefined},{value:null},{value:true},{value:false}];function __emval_decref(handle){if(handle>4&&0===--emval_handle_array[handle].refcount){emval_handle_array[handle]=undefined;emval_free_list.push(handle)}}function count_emval_handles(){var count=0;for(var i=5;i{if(!handle){throwBindingError("Cannot use deleted val. handle = "+handle)}return emval_handle_array[handle].value},toHandle:value=>{switch(value){case undefined:return 1;case null:return 2;case true:return 3;case false:return 4;default:{var handle=emval_free_list.length?emval_free_list.pop():emval_handle_array.length;emval_handle_array[handle]={refcount:1,value:value};return handle}}}};function __embind_register_emval(rawType,name){name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":function(handle){var rv=Emval.toValue(handle);__emval_decref(handle);return rv},"toWireType":function(destructors,value){return Emval.toHandle(value)},"argPackAdvance":8,"readValueFromPointer":simpleReadValueFromPointer,destructorFunction:null})}function embindRepr(v){if(v===null){return"null"}var t=typeof v;if(t==="object"||t==="array"||t==="function"){return v.toString()}else{return""+v}}function floatReadValueFromPointer(name,shift){switch(shift){case 2:return function(pointer){return this["fromWireType"](HEAPF32[pointer>>2])};case 3:return function(pointer){return this["fromWireType"](HEAPF64[pointer>>3])};default:throw new TypeError("Unknown float type: "+name)}}function __embind_register_float(rawType,name,size){var shift=getShiftFromSize(size);name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":function(value){return value},"toWireType":function(destructors,value){return value},"argPackAdvance":8,"readValueFromPointer":floatReadValueFromPointer(name,shift),destructorFunction:null})}function integerReadValueFromPointer(name,shift,signed){switch(shift){case 0:return signed?function readS8FromPointer(pointer){return HEAP8[pointer]}:function readU8FromPointer(pointer){return HEAPU8[pointer]};case 1:return signed?function readS16FromPointer(pointer){return HEAP16[pointer>>1]}:function readU16FromPointer(pointer){return HEAPU16[pointer>>1]};case 2:return signed?function readS32FromPointer(pointer){return HEAP32[pointer>>2]}:function readU32FromPointer(pointer){return HEAPU32[pointer>>2]};default:throw new TypeError("Unknown integer type: "+name)}}function __embind_register_integer(primitiveType,name,size,minRange,maxRange){name=readLatin1String(name);if(maxRange===-1){maxRange=4294967295}var shift=getShiftFromSize(size);var fromWireType=value=>value;if(minRange===0){var bitshift=32-8*size;fromWireType=value=>value<>>bitshift}var isUnsignedType=name.includes("unsigned");var checkAssertions=(value,toTypeName)=>{};var toWireType;if(isUnsignedType){toWireType=function(destructors,value){checkAssertions(value,this.name);return value>>>0}}else{toWireType=function(destructors,value){checkAssertions(value,this.name);return value}}registerType(primitiveType,{name:name,"fromWireType":fromWireType,"toWireType":toWireType,"argPackAdvance":8,"readValueFromPointer":integerReadValueFromPointer(name,shift,minRange!==0),destructorFunction:null})}function __embind_register_memory_view(rawType,dataTypeIndex,name){var typeMapping=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array];var TA=typeMapping[dataTypeIndex];function decodeMemoryView(handle){handle=handle>>2;var heap=HEAPU32;var size=heap[handle];var data=heap[handle+1];return new TA(buffer,data,size)}name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":decodeMemoryView,"argPackAdvance":8,"readValueFromPointer":decodeMemoryView},{ignoreDuplicateRegistrations:true})}function __embind_register_std_string(rawType,name){name=readLatin1String(name);var stdStringIsUTF8=name==="std::string";registerType(rawType,{name:name,"fromWireType":function(value){var length=HEAPU32[value>>2];var payload=value+4;var str;if(stdStringIsUTF8){var decodeStartPtr=payload;for(var i=0;i<=length;++i){var currentBytePtr=payload+i;if(i==length||HEAPU8[currentBytePtr]==0){var maxRead=currentBytePtr-decodeStartPtr;var stringSegment=UTF8ToString(decodeStartPtr,maxRead);if(str===undefined){str=stringSegment}else{str+=String.fromCharCode(0);str+=stringSegment}decodeStartPtr=currentBytePtr+1}}}else{var a=new Array(length);for(var i=0;i>2]=length;if(stdStringIsUTF8&&valueIsOfTypeString){stringToUTF8(value,ptr,length+1)}else{if(valueIsOfTypeString){for(var i=0;i255){_free(ptr);throwBindingError("String has UTF-16 code units that do not fit in 8 bits")}HEAPU8[ptr+i]=charCode}}else{for(var i=0;iHEAPU16;shift=1}else if(charSize===4){decodeString=UTF32ToString;encodeString=stringToUTF32;lengthBytesUTF=lengthBytesUTF32;getHeap=()=>HEAPU32;shift=2}registerType(rawType,{name:name,"fromWireType":function(value){var length=HEAPU32[value>>2];var HEAP=getHeap();var str;var decodeStartPtr=value+4;for(var i=0;i<=length;++i){var currentBytePtr=value+4+i*charSize;if(i==length||HEAP[currentBytePtr>>shift]==0){var maxReadBytes=currentBytePtr-decodeStartPtr;var stringSegment=decodeString(decodeStartPtr,maxReadBytes);if(str===undefined){str=stringSegment}else{str+=String.fromCharCode(0);str+=stringSegment}decodeStartPtr=currentBytePtr+charSize}}_free(value);return str},"toWireType":function(destructors,value){if(!(typeof value=="string")){throwBindingError("Cannot pass non-string to C++ string type "+name)}var length=lengthBytesUTF(value);var ptr=_malloc(4+length+charSize);HEAPU32[ptr>>2]=length>>shift;encodeString(value,ptr+4,length+charSize);if(destructors!==null){destructors.push(_free,ptr)}return ptr},"argPackAdvance":8,"readValueFromPointer":simpleReadValueFromPointer,destructorFunction:function(ptr){_free(ptr)}})}function __embind_register_void(rawType,name){name=readLatin1String(name);registerType(rawType,{isVoid:true,name:name,"argPackAdvance":0,"fromWireType":function(){return undefined},"toWireType":function(destructors,o){return undefined}})}function _abort(){abort("")}function _emscripten_memcpy_big(dest,src,num){HEAPU8.copyWithin(dest,src,src+num)}function getHeapMax(){return 2147483648}function emscripten_realloc_buffer(size){try{wasmMemory.grow(size-buffer.byteLength+65535>>>16);updateGlobalBufferAndViews(wasmMemory.buffer);return 1}catch(e){}}function _emscripten_resize_heap(requestedSize){var oldSize=HEAPU8.length;requestedSize=requestedSize>>>0;var maxHeapSize=getHeapMax();if(requestedSize>maxHeapSize){return false}let alignUp=(x,multiple)=>x+(multiple-x%multiple)%multiple;for(var cutDown=1;cutDown<=4;cutDown*=2){var overGrownHeapSize=oldSize*(1+.2/cutDown);overGrownHeapSize=Math.min(overGrownHeapSize,requestedSize+100663296);var newSize=Math.min(maxHeapSize,alignUp(Math.max(requestedSize,overGrownHeapSize),65536));var replacement=emscripten_realloc_buffer(newSize);if(replacement){return true}}return false}function _fd_close(fd){return 52}function _fd_read(fd,iov,iovcnt,pnum){return 52}function _fd_seek(fd,offset_low,offset_high,whence,newOffset){return 70}var printCharBuffers=[null,[],[]];function printChar(stream,curr){var buffer=printCharBuffers[stream];if(curr===0||curr===10){(stream===1?out:err)(UTF8ArrayToString(buffer,0));buffer.length=0}else{buffer.push(curr)}}function _fd_write(fd,iov,iovcnt,pnum){var num=0;for(var i=0;i>2];var len=HEAPU32[iov+4>>2];iov+=8;for(var j=0;j>2]=num;return 0}function _h264_write_polyfill(){err("missing function: h264_write_polyfill");abort(-1)}function _setTempRet0(val){setTempRet0(val)}embind_init_charCodes();BindingError=Module["BindingError"]=extendError(Error,"BindingError");InternalError=Module["InternalError"]=extendError(Error,"InternalError");init_ClassHandle();init_embind();init_RegisteredPointer();UnboundTypeError=Module["UnboundTypeError"]=extendError(Error,"UnboundTypeError");init_emval();var ASSERTIONS=false;var asmLibraryArg={"__assert_fail":___assert_fail,"__syscall_fcntl64":___syscall_fcntl64,"__syscall_fstat64":___syscall_fstat64,"__syscall_ioctl":___syscall_ioctl,"__syscall_lstat64":___syscall_lstat64,"__syscall_newfstatat":___syscall_newfstatat,"__syscall_openat":___syscall_openat,"__syscall_renameat":___syscall_renameat,"__syscall_stat64":___syscall_stat64,"_embind_register_bigint":__embind_register_bigint,"_embind_register_bool":__embind_register_bool,"_embind_register_class":__embind_register_class,"_embind_register_class_constructor":__embind_register_class_constructor,"_embind_register_class_function":__embind_register_class_function,"_embind_register_emval":__embind_register_emval,"_embind_register_float":__embind_register_float,"_embind_register_integer":__embind_register_integer,"_embind_register_memory_view":__embind_register_memory_view,"_embind_register_std_string":__embind_register_std_string,"_embind_register_std_wstring":__embind_register_std_wstring,"_embind_register_void":__embind_register_void,"abort":_abort,"emscripten_memcpy_big":_emscripten_memcpy_big,"emscripten_resize_heap":_emscripten_resize_heap,"fd_close":_fd_close,"fd_read":_fd_read,"fd_seek":_fd_seek,"fd_write":_fd_write,"h264_write_polyfill":_h264_write_polyfill,"setTempRet0":_setTempRet0};var asm=createWasm();var ___wasm_call_ctors=Module["___wasm_call_ctors"]=function(){return(___wasm_call_ctors=Module["___wasm_call_ctors"]=Module["asm"]["__wasm_call_ctors"]).apply(null,arguments)};var _h264_write=Module["_h264_write"]=function(){return(_h264_write=Module["_h264_write"]=Module["asm"]["h264_write"]).apply(null,arguments)};var _free=Module["_free"]=function(){return(_free=Module["_free"]=Module["asm"]["free"]).apply(null,arguments)};var _malloc=Module["_malloc"]=function(){return(_malloc=Module["_malloc"]=Module["asm"]["malloc"]).apply(null,arguments)};var ___getTypeName=Module["___getTypeName"]=function(){return(___getTypeName=Module["___getTypeName"]=Module["asm"]["__getTypeName"]).apply(null,arguments)};var ___embind_register_native_and_builtin_types=Module["___embind_register_native_and_builtin_types"]=function(){return(___embind_register_native_and_builtin_types=Module["___embind_register_native_and_builtin_types"]=Module["asm"]["__embind_register_native_and_builtin_types"]).apply(null,arguments)};var ___errno_location=Module["___errno_location"]=function(){return(___errno_location=Module["___errno_location"]=Module["asm"]["__errno_location"]).apply(null,arguments)};var stackSave=Module["stackSave"]=function(){return(stackSave=Module["stackSave"]=Module["asm"]["stackSave"]).apply(null,arguments)};var stackRestore=Module["stackRestore"]=function(){return(stackRestore=Module["stackRestore"]=Module["asm"]["stackRestore"]).apply(null,arguments)};var stackAlloc=Module["stackAlloc"]=function(){return(stackAlloc=Module["stackAlloc"]=Module["asm"]["stackAlloc"]).apply(null,arguments)};var dynCall_iij=Module["dynCall_iij"]=function(){return(dynCall_iij=Module["dynCall_iij"]=Module["asm"]["dynCall_iij"]).apply(null,arguments)};var dynCall_jii=Module["dynCall_jii"]=function(){return(dynCall_jii=Module["dynCall_jii"]=Module["asm"]["dynCall_jii"]).apply(null,arguments)};var dynCall_jiji=Module["dynCall_jiji"]=function(){return(dynCall_jiji=Module["dynCall_jiji"]=Module["asm"]["dynCall_jiji"]).apply(null,arguments)};var calledRun;function ExitStatus(status){this.name="ExitStatus";this.message="Program terminated with exit("+status+")";this.status=status}dependenciesFulfilled=function runCaller(){if(!calledRun)run();if(!calledRun)dependenciesFulfilled=runCaller};function run(args){args=args||arguments_;if(runDependencies>0){return}preRun();if(runDependencies>0){return}function doRun(){if(calledRun)return;calledRun=true;Module["calledRun"]=true;if(ABORT)return;initRuntime();readyPromiseResolve(Module);if(Module["onRuntimeInitialized"])Module["onRuntimeInitialized"]();postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(function(){setTimeout(function(){Module["setStatus"]("")},1);doRun()},1)}else{doRun()}}Module["run"]=run;function procExit(code){EXITSTATUS=code;if(!keepRuntimeAlive()){if(Module["onExit"])Module["onExit"](code);ABORT=true}quit_(code,new ExitStatus(code))}if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}run(); +var Module=typeof Module!=="undefined"?Module:{};var readyPromiseResolve,readyPromiseReject;Module["ready"]=new Promise(function(resolve,reject){readyPromiseResolve=resolve;readyPromiseReject=reject});var moduleOverrides={};var key;for(key in Module){if(Module.hasOwnProperty(key)){moduleOverrides[key]=Module[key]}}var arguments_=[];var thisProgram="./this.program";var quit_=function(status,toThrow){throw toThrow};var ENVIRONMENT_IS_WEB=true;var ENVIRONMENT_IS_WORKER=false;var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var read_,readAsync,readBinary,setWindowTitle;if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){if(ENVIRONMENT_IS_WORKER){scriptDirectory=self.location.href}else if(document.currentScript){scriptDirectory=document.currentScript.src}if(_scriptDir){scriptDirectory=_scriptDir}if(scriptDirectory.indexOf("blob:")!==0){scriptDirectory=scriptDirectory.substr(0,scriptDirectory.lastIndexOf("/")+1)}else{scriptDirectory=""}{read_=function shell_read(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText};if(ENVIRONMENT_IS_WORKER){readBinary=function readBinary(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}readAsync=function readAsync(url,onload,onerror){var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=function xhr_onload(){if(xhr.status==200||xhr.status==0&&xhr.response){onload(xhr.response);return}onerror()};xhr.onerror=onerror;xhr.send(null)}}setWindowTitle=function(title){document.title=title}}else{}var out=Module["print"]||console.log.bind(console);var err=Module["printErr"]||console.warn.bind(console);for(key in moduleOverrides){if(moduleOverrides.hasOwnProperty(key)){Module[key]=moduleOverrides[key]}}moduleOverrides=null;if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];if(Module["quit"])quit_=Module["quit"];var STACK_ALIGN=16;function dynamicAlloc(size){var ret=HEAP32[DYNAMICTOP_PTR>>2];var end=ret+size+15&-16;HEAP32[DYNAMICTOP_PTR>>2]=end;return ret}function getNativeTypeSize(type){switch(type){case"i1":case"i8":return 1;case"i16":return 2;case"i32":return 4;case"i64":return 8;case"float":return 4;case"double":return 8;default:{if(type[type.length-1]==="*"){return 4}else if(type[0]==="i"){var bits=Number(type.substr(1));assert(bits%8===0,"getNativeTypeSize invalid bits "+bits+", type "+type);return bits/8}else{return 0}}}}function warnOnce(text){if(!warnOnce.shown)warnOnce.shown={};if(!warnOnce.shown[text]){warnOnce.shown[text]=1;err(text)}}function convertJsFunctionToWasm(func,sig){if(typeof WebAssembly.Function==="function"){var typeNames={"i":"i32","j":"i64","f":"f32","d":"f64"};var type={parameters:[],results:sig[0]=="v"?[]:[typeNames[sig[0]]]};for(var i=1;i>0]=value;break;case"i8":HEAP8[ptr>>0]=value;break;case"i16":HEAP16[ptr>>1]=value;break;case"i32":HEAP32[ptr>>2]=value;break;case"i64":tempI64=[value>>>0,(tempDouble=value,+Math_abs(tempDouble)>=1?tempDouble>0?(Math_min(+Math_floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math_ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[ptr>>2]=tempI64[0],HEAP32[ptr+4>>2]=tempI64[1];break;case"float":HEAPF32[ptr>>2]=value;break;case"double":HEAPF64[ptr>>3]=value;break;default:abort("invalid type for setValue: "+type)}}var wasmMemory;var wasmTable=new WebAssembly.Table({"initial":318,"maximum":318+0,"element":"anyfunc"});var ABORT=false;var EXITSTATUS=0;function assert(condition,text){if(!condition){abort("Assertion failed: "+text)}}function getCFunc(ident){var func=Module["_"+ident];assert(func,"Cannot call unknown function "+ident+", make sure it is exported");return func}function ccall(ident,returnType,argTypes,args,opts){var toC={"string":function(str){var ret=0;if(str!==null&&str!==undefined&&str!==0){var len=(str.length<<2)+1;ret=stackAlloc(len);stringToUTF8(str,ret,len)}return ret},"array":function(arr){var ret=stackAlloc(arr.length);writeArrayToMemory(arr,ret);return ret}};function convertReturnValue(ret){if(returnType==="string")return UTF8ToString(ret);if(returnType==="boolean")return Boolean(ret);return ret}var func=getCFunc(ident);var cArgs=[];var stack=0;if(args){for(var i=0;i=endIdx))++endPtr;if(endPtr-idx>16&&heap.subarray&&UTF8Decoder){return UTF8Decoder.decode(heap.subarray(idx,endPtr))}else{var str="";while(idx>10,56320|ch&1023)}}}return str}function UTF8ToString(ptr,maxBytesToRead){return ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead):""}function stringToUTF8Array(str,heap,outIdx,maxBytesToWrite){if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i=55296&&u<=57343){var u1=str.charCodeAt(++i);u=65536+((u&1023)<<10)|u1&1023}if(u<=127){if(outIdx>=endIdx)break;heap[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;heap[outIdx++]=192|u>>6;heap[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;heap[outIdx++]=224|u>>12;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;heap[outIdx++]=240|u>>18;heap[outIdx++]=128|u>>12&63;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}}heap[outIdx]=0;return outIdx-startIdx}function stringToUTF8(str,outPtr,maxBytesToWrite){return stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite)}function lengthBytesUTF8(str){var len=0;for(var i=0;i=55296&&u<=57343)u=65536+((u&1023)<<10)|str.charCodeAt(++i)&1023;if(u<=127)++len;else if(u<=2047)len+=2;else if(u<=65535)len+=3;else len+=4}return len}var UTF16Decoder=typeof TextDecoder!=="undefined"?new TextDecoder("utf-16le"):undefined;function UTF16ToString(ptr,maxBytesToRead){var endPtr=ptr;var idx=endPtr>>1;var maxIdx=idx+maxBytesToRead/2;while(!(idx>=maxIdx)&&HEAPU16[idx])++idx;endPtr=idx<<1;if(endPtr-ptr>32&&UTF16Decoder){return UTF16Decoder.decode(HEAPU8.subarray(ptr,endPtr))}else{var i=0;var str="";while(1){var codeUnit=HEAP16[ptr+i*2>>1];if(codeUnit==0||i==maxBytesToRead/2)return str;++i;str+=String.fromCharCode(codeUnit)}}}function stringToUTF16(str,outPtr,maxBytesToWrite){if(maxBytesToWrite===undefined){maxBytesToWrite=2147483647}if(maxBytesToWrite<2)return 0;maxBytesToWrite-=2;var startPtr=outPtr;var numCharsToWrite=maxBytesToWrite>1]=codeUnit;outPtr+=2}HEAP16[outPtr>>1]=0;return outPtr-startPtr}function lengthBytesUTF16(str){return str.length*2}function UTF32ToString(ptr,maxBytesToRead){var i=0;var str="";while(!(i>=maxBytesToRead/4)){var utf32=HEAP32[ptr+i*4>>2];if(utf32==0)break;++i;if(utf32>=65536){var ch=utf32-65536;str+=String.fromCharCode(55296|ch>>10,56320|ch&1023)}else{str+=String.fromCharCode(utf32)}}return str}function stringToUTF32(str,outPtr,maxBytesToWrite){if(maxBytesToWrite===undefined){maxBytesToWrite=2147483647}if(maxBytesToWrite<4)return 0;var startPtr=outPtr;var endPtr=startPtr+maxBytesToWrite-4;for(var i=0;i=55296&&codeUnit<=57343){var trailSurrogate=str.charCodeAt(++i);codeUnit=65536+((codeUnit&1023)<<10)|trailSurrogate&1023}HEAP32[outPtr>>2]=codeUnit;outPtr+=4;if(outPtr+4>endPtr)break}HEAP32[outPtr>>2]=0;return outPtr-startPtr}function lengthBytesUTF32(str){var len=0;for(var i=0;i=55296&&codeUnit<=57343)++i;len+=4}return len}function writeArrayToMemory(array,buffer){HEAP8.set(array,buffer)}function writeAsciiToMemory(str,buffer,dontAddNull){for(var i=0;i>0]=str.charCodeAt(i)}if(!dontAddNull)HEAP8[buffer>>0]=0}var WASM_PAGE_SIZE=65536;function alignUp(x,multiple){if(x%multiple>0){x+=multiple-x%multiple}return x}var buffer,HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;function updateGlobalBufferAndViews(buf){buffer=buf;Module["HEAP8"]=HEAP8=new Int8Array(buf);Module["HEAP16"]=HEAP16=new Int16Array(buf);Module["HEAP32"]=HEAP32=new Int32Array(buf);Module["HEAPU8"]=HEAPU8=new Uint8Array(buf);Module["HEAPU16"]=HEAPU16=new Uint16Array(buf);Module["HEAPU32"]=HEAPU32=new Uint32Array(buf);Module["HEAPF32"]=HEAPF32=new Float32Array(buf);Module["HEAPF64"]=HEAPF64=new Float64Array(buf)}var STACK_BASE=5775184,DYNAMIC_BASE=5775184,DYNAMICTOP_PTR=532144;var INITIAL_INITIAL_MEMORY=Module["INITIAL_MEMORY"]||16777216;if(Module["wasmMemory"]){wasmMemory=Module["wasmMemory"]}else{wasmMemory=new WebAssembly.Memory({"initial":INITIAL_INITIAL_MEMORY/WASM_PAGE_SIZE,"maximum":2147483648/WASM_PAGE_SIZE})}if(wasmMemory){buffer=wasmMemory.buffer}INITIAL_INITIAL_MEMORY=buffer.byteLength;updateGlobalBufferAndViews(buffer);HEAP32[DYNAMICTOP_PTR>>2]=DYNAMIC_BASE;function callRuntimeCallbacks(callbacks){while(callbacks.length>0){var callback=callbacks.shift();if(typeof callback=="function"){callback(Module);continue}var func=callback.func;if(typeof func==="number"){if(callback.arg===undefined){Module["dynCall_v"](func)}else{Module["dynCall_vi"](func,callback.arg)}}else{func(callback.arg===undefined?null:callback.arg)}}}var __ATPRERUN__=[];var __ATINIT__=[];var __ATMAIN__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;var runtimeExited=false;function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(__ATPRERUN__)}function initRuntime(){runtimeInitialized=true;callRuntimeCallbacks(__ATINIT__)}function preMain(){callRuntimeCallbacks(__ATMAIN__)}function exitRuntime(){runtimeExited=true}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}var Math_abs=Math.abs;var Math_ceil=Math.ceil;var Math_floor=Math.floor;var Math_min=Math.min;var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;function addRunDependency(id){runDependencies++;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}}function removeRunDependency(id){runDependencies--;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}if(runDependencies==0){if(runDependencyWatcher!==null){clearInterval(runDependencyWatcher);runDependencyWatcher=null}if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}Module["preloadedImages"]={};Module["preloadedAudios"]={};function abort(what){if(Module["onAbort"]){Module["onAbort"](what)}what+="";out(what);err(what);ABORT=true;EXITSTATUS=1;what="abort("+what+"). Build with -s ASSERTIONS=1 for more info.";throw new WebAssembly.RuntimeError(what)}function hasPrefix(str,prefix){return String.prototype.startsWith?str.startsWith(prefix):str.indexOf(prefix)===0}var dataURIPrefix="data:application/octet-stream;base64,";function isDataURI(filename){return hasPrefix(filename,dataURIPrefix)}var fileURIPrefix="file://";var wasmBinaryFile="X264Encoder.wasm";if(!isDataURI(wasmBinaryFile)){wasmBinaryFile=locateFile(wasmBinaryFile)}function getBinary(){try{if(wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(wasmBinaryFile)}else{throw"both async and sync fetching of the wasm failed"}}catch(err){abort(err)}}function getBinaryPromise(){if(!wasmBinary&&(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER)&&typeof fetch==="function"){return fetch(wasmBinaryFile,{credentials:"same-origin"}).then(function(response){if(!response["ok"]){throw"failed to load wasm binary file at '"+wasmBinaryFile+"'"}return response["arrayBuffer"]()}).catch(function(){return getBinary()})}return new Promise(function(resolve,reject){resolve(getBinary())})}function createWasm(){var info={"env":asmLibraryArg,"wasi_snapshot_preview1":asmLibraryArg};function receiveInstance(instance,module){var exports=instance.exports;Module["asm"]=exports;removeRunDependency("wasm-instantiate")}addRunDependency("wasm-instantiate");function receiveInstantiatedSource(output){receiveInstance(output["instance"])}function instantiateArrayBuffer(receiver){return getBinaryPromise().then(function(binary){return WebAssembly.instantiate(binary,info)}).then(receiver,function(reason){err("failed to asynchronously prepare wasm: "+reason);abort(reason)})}function instantiateAsync(){if(!wasmBinary&&typeof WebAssembly.instantiateStreaming==="function"&&!isDataURI(wasmBinaryFile)&&typeof fetch==="function"){fetch(wasmBinaryFile,{credentials:"same-origin"}).then(function(response){var result=WebAssembly.instantiateStreaming(response,info);return result.then(receiveInstantiatedSource,function(reason){err("wasm streaming compile failed: "+reason);err("falling back to ArrayBuffer instantiation");return instantiateArrayBuffer(receiveInstantiatedSource)})})}else{return instantiateArrayBuffer(receiveInstantiatedSource)}}if(Module["instantiateWasm"]){try{var exports=Module["instantiateWasm"](info,receiveInstance);return exports}catch(e){err("Module.instantiateWasm callback failed with error: "+e);return false}}instantiateAsync();return{}}var tempDouble;var tempI64;__ATINIT__.push({func:function(){___wasm_call_ctors()}});function demangle(func){return func}function demangleAll(text){var regex=/\b_Z[\w\d_]+/g;return text.replace(regex,function(x){var y=demangle(x);return x===y?x:y+" ["+x+"]"})}function jsStackTrace(){var err=new Error;if(!err.stack){try{throw new Error}catch(e){err=e}if(!err.stack){return"(no stack trace available)"}}return err.stack.toString()}function ___assert_fail(condition,filename,line,func){abort("Assertion failed: "+UTF8ToString(condition)+", at: "+[filename?UTF8ToString(filename):"unknown filename",line,func?UTF8ToString(func):"unknown function"])}var PATH={splitPath:function(filename){var splitPathRe=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;return splitPathRe.exec(filename).slice(1)},normalizeArray:function(parts,allowAboveRoot){var up=0;for(var i=parts.length-1;i>=0;i--){var last=parts[i];if(last==="."){parts.splice(i,1)}else if(last===".."){parts.splice(i,1);up++}else if(up){parts.splice(i,1);up--}}if(allowAboveRoot){for(;up;up--){parts.unshift("..")}}return parts},normalize:function(path){var isAbsolute=path.charAt(0)==="/",trailingSlash=path.substr(-1)==="/";path=PATH.normalizeArray(path.split("/").filter(function(p){return!!p}),!isAbsolute).join("/");if(!path&&!isAbsolute){path="."}if(path&&trailingSlash){path+="/"}return(isAbsolute?"/":"")+path},dirname:function(path){var result=PATH.splitPath(path),root=result[0],dir=result[1];if(!root&&!dir){return"."}if(dir){dir=dir.substr(0,dir.length-1)}return root+dir},basename:function(path){if(path==="/")return"/";var lastSlash=path.lastIndexOf("/");if(lastSlash===-1)return path;return path.substr(lastSlash+1)},extname:function(path){return PATH.splitPath(path)[3]},join:function(){var paths=Array.prototype.slice.call(arguments,0);return PATH.normalize(paths.join("/"))},join2:function(l,r){return PATH.normalize(l+"/"+r)}};var SYSCALLS={mappings:{},buffers:[null,[],[]],printChar:function(stream,curr){var buffer=SYSCALLS.buffers[stream];if(curr===0||curr===10){(stream===1?out:err)(UTF8ArrayToString(buffer,0));buffer.length=0}else{buffer.push(curr)}},varargs:undefined,get:function(){SYSCALLS.varargs+=4;var ret=HEAP32[SYSCALLS.varargs-4>>2];return ret},getStr:function(ptr){var ret=UTF8ToString(ptr);return ret},get64:function(low,high){return low}};function ___sys_fcntl64(fd,cmd,varargs){SYSCALLS.varargs=varargs;return 0}function ___sys_fstat64(fd,buf){}function ___sys_ioctl(fd,op,varargs){SYSCALLS.varargs=varargs;return 0}function ___sys_madvise1(addr,length,advice){return 0}function ___sys_open(path,flags,varargs){SYSCALLS.varargs=varargs}function ___sys_rename(old_path,new_path){}function ___sys_stat64(path,buf){}function getShiftFromSize(size){switch(size){case 1:return 0;case 2:return 1;case 4:return 2;case 8:return 3;default:throw new TypeError("Unknown type size: "+size)}}function embind_init_charCodes(){var codes=new Array(256);for(var i=0;i<256;++i){codes[i]=String.fromCharCode(i)}embind_charCodes=codes}var embind_charCodes=undefined;function readLatin1String(ptr){var ret="";var c=ptr;while(HEAPU8[c]){ret+=embind_charCodes[HEAPU8[c++]]}return ret}var awaitingDependencies={};var registeredTypes={};var typeDependencies={};var char_0=48;var char_9=57;function makeLegalFunctionName(name){if(undefined===name){return"_unknown"}name=name.replace(/[^a-zA-Z0-9_]/g,"$");var f=name.charCodeAt(0);if(f>=char_0&&f<=char_9){return"_"+name}else{return name}}function createNamedFunction(name,body){name=makeLegalFunctionName(name);return function(){"use strict";return body.apply(this,arguments)}}function extendError(baseErrorType,errorName){var errorClass=createNamedFunction(errorName,function(message){this.name=errorName;this.message=message;var stack=new Error(message).stack;if(stack!==undefined){this.stack=this.toString()+"\n"+stack.replace(/^Error(:[^\n]*)?\n/,"")}});errorClass.prototype=Object.create(baseErrorType.prototype);errorClass.prototype.constructor=errorClass;errorClass.prototype.toString=function(){if(this.message===undefined){return this.name}else{return this.name+": "+this.message}};return errorClass}var BindingError=undefined;function throwBindingError(message){throw new BindingError(message)}var InternalError=undefined;function throwInternalError(message){throw new InternalError(message)}function whenDependentTypesAreResolved(myTypes,dependentTypes,getTypeConverters){myTypes.forEach(function(type){typeDependencies[type]=dependentTypes});function onComplete(typeConverters){var myTypeConverters=getTypeConverters(typeConverters);if(myTypeConverters.length!==myTypes.length){throwInternalError("Mismatched type converter count")}for(var i=0;i>shift])},destructorFunction:null})}function ClassHandle_isAliasOf(other){if(!(this instanceof ClassHandle)){return false}if(!(other instanceof ClassHandle)){return false}var leftClass=this.$$.ptrType.registeredClass;var left=this.$$.ptr;var rightClass=other.$$.ptrType.registeredClass;var right=other.$$.ptr;while(leftClass.baseClass){left=leftClass.upcast(left);leftClass=leftClass.baseClass}while(rightClass.baseClass){right=rightClass.upcast(right);rightClass=rightClass.baseClass}return leftClass===rightClass&&left===right}function shallowCopyInternalPointer(o){return{count:o.count,deleteScheduled:o.deleteScheduled,preservePointerOnDelete:o.preservePointerOnDelete,ptr:o.ptr,ptrType:o.ptrType,smartPtr:o.smartPtr,smartPtrType:o.smartPtrType}}function throwInstanceAlreadyDeleted(obj){function getInstanceTypeName(handle){return handle.$$.ptrType.registeredClass.name}throwBindingError(getInstanceTypeName(obj)+" instance already deleted")}var finalizationGroup=false;function detachFinalizer(handle){}function runDestructor($$){if($$.smartPtr){$$.smartPtrType.rawDestructor($$.smartPtr)}else{$$.ptrType.registeredClass.rawDestructor($$.ptr)}}function releaseClassHandle($$){$$.count.value-=1;var toDelete=0===$$.count.value;if(toDelete){runDestructor($$)}}function attachFinalizer(handle){if("undefined"===typeof FinalizationGroup){attachFinalizer=function(handle){return handle};return handle}finalizationGroup=new FinalizationGroup(function(iter){for(var result=iter.next();!result.done;result=iter.next()){var $$=result.value;if(!$$.ptr){console.warn("object already deleted: "+$$.ptr)}else{releaseClassHandle($$)}}});attachFinalizer=function(handle){finalizationGroup.register(handle,handle.$$,handle.$$);return handle};detachFinalizer=function(handle){finalizationGroup.unregister(handle.$$)};return attachFinalizer(handle)}function ClassHandle_clone(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.preservePointerOnDelete){this.$$.count.value+=1;return this}else{var clone=attachFinalizer(Object.create(Object.getPrototypeOf(this),{$$:{value:shallowCopyInternalPointer(this.$$)}}));clone.$$.count.value+=1;clone.$$.deleteScheduled=false;return clone}}function ClassHandle_delete(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete){throwBindingError("Object already scheduled for deletion")}detachFinalizer(this);releaseClassHandle(this.$$);if(!this.$$.preservePointerOnDelete){this.$$.smartPtr=undefined;this.$$.ptr=undefined}}function ClassHandle_isDeleted(){return!this.$$.ptr}var delayFunction=undefined;var deletionQueue=[];function flushPendingDeletes(){while(deletionQueue.length){var obj=deletionQueue.pop();obj.$$.deleteScheduled=false;obj["delete"]()}}function ClassHandle_deleteLater(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete){throwBindingError("Object already scheduled for deletion")}deletionQueue.push(this);if(deletionQueue.length===1&&delayFunction){delayFunction(flushPendingDeletes)}this.$$.deleteScheduled=true;return this}function init_ClassHandle(){ClassHandle.prototype["isAliasOf"]=ClassHandle_isAliasOf;ClassHandle.prototype["clone"]=ClassHandle_clone;ClassHandle.prototype["delete"]=ClassHandle_delete;ClassHandle.prototype["isDeleted"]=ClassHandle_isDeleted;ClassHandle.prototype["deleteLater"]=ClassHandle_deleteLater}function ClassHandle(){}var registeredPointers={};function ensureOverloadTable(proto,methodName,humanName){if(undefined===proto[methodName].overloadTable){var prevFunc=proto[methodName];proto[methodName]=function(){if(!proto[methodName].overloadTable.hasOwnProperty(arguments.length)){throwBindingError("Function '"+humanName+"' called with an invalid number of arguments ("+arguments.length+") - expects one of ("+proto[methodName].overloadTable+")!")}return proto[methodName].overloadTable[arguments.length].apply(this,arguments)};proto[methodName].overloadTable=[];proto[methodName].overloadTable[prevFunc.argCount]=prevFunc}}function exposePublicSymbol(name,value,numArguments){if(Module.hasOwnProperty(name)){if(undefined===numArguments||undefined!==Module[name].overloadTable&&undefined!==Module[name].overloadTable[numArguments]){throwBindingError("Cannot register public name '"+name+"' twice")}ensureOverloadTable(Module,name,name);if(Module.hasOwnProperty(numArguments)){throwBindingError("Cannot register multiple overloads of a function with the same number of arguments ("+numArguments+")!")}Module[name].overloadTable[numArguments]=value}else{Module[name]=value;if(undefined!==numArguments){Module[name].numArguments=numArguments}}}function RegisteredClass(name,constructor,instancePrototype,rawDestructor,baseClass,getActualType,upcast,downcast){this.name=name;this.constructor=constructor;this.instancePrototype=instancePrototype;this.rawDestructor=rawDestructor;this.baseClass=baseClass;this.getActualType=getActualType;this.upcast=upcast;this.downcast=downcast;this.pureVirtualFunctions=[]}function upcastPointer(ptr,ptrClass,desiredClass){while(ptrClass!==desiredClass){if(!ptrClass.upcast){throwBindingError("Expected null or instance of "+desiredClass.name+", got an instance of "+ptrClass.name)}ptr=ptrClass.upcast(ptr);ptrClass=ptrClass.baseClass}return ptr}function constNoSmartPtrRawPointerToWireType(destructors,handle){if(handle===null){if(this.isReference){throwBindingError("null is not a valid "+this.name)}return 0}if(!handle.$$){throwBindingError('Cannot pass "'+_embind_repr(handle)+'" as a '+this.name)}if(!handle.$$.ptr){throwBindingError("Cannot pass deleted object as a pointer of type "+this.name)}var handleClass=handle.$$.ptrType.registeredClass;var ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);return ptr}function genericPointerToWireType(destructors,handle){var ptr;if(handle===null){if(this.isReference){throwBindingError("null is not a valid "+this.name)}if(this.isSmartPointer){ptr=this.rawConstructor();if(destructors!==null){destructors.push(this.rawDestructor,ptr)}return ptr}else{return 0}}if(!handle.$$){throwBindingError('Cannot pass "'+_embind_repr(handle)+'" as a '+this.name)}if(!handle.$$.ptr){throwBindingError("Cannot pass deleted object as a pointer of type "+this.name)}if(!this.isConst&&handle.$$.ptrType.isConst){throwBindingError("Cannot convert argument of type "+(handle.$$.smartPtrType?handle.$$.smartPtrType.name:handle.$$.ptrType.name)+" to parameter type "+this.name)}var handleClass=handle.$$.ptrType.registeredClass;ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);if(this.isSmartPointer){if(undefined===handle.$$.smartPtr){throwBindingError("Passing raw pointer to smart pointer is illegal")}switch(this.sharingPolicy){case 0:if(handle.$$.smartPtrType===this){ptr=handle.$$.smartPtr}else{throwBindingError("Cannot convert argument of type "+(handle.$$.smartPtrType?handle.$$.smartPtrType.name:handle.$$.ptrType.name)+" to parameter type "+this.name)}break;case 1:ptr=handle.$$.smartPtr;break;case 2:if(handle.$$.smartPtrType===this){ptr=handle.$$.smartPtr}else{var clonedHandle=handle["clone"]();ptr=this.rawShare(ptr,__emval_register(function(){clonedHandle["delete"]()}));if(destructors!==null){destructors.push(this.rawDestructor,ptr)}}break;default:throwBindingError("Unsupporting sharing policy")}}return ptr}function nonConstNoSmartPtrRawPointerToWireType(destructors,handle){if(handle===null){if(this.isReference){throwBindingError("null is not a valid "+this.name)}return 0}if(!handle.$$){throwBindingError('Cannot pass "'+_embind_repr(handle)+'" as a '+this.name)}if(!handle.$$.ptr){throwBindingError("Cannot pass deleted object as a pointer of type "+this.name)}if(handle.$$.ptrType.isConst){throwBindingError("Cannot convert argument of type "+handle.$$.ptrType.name+" to parameter type "+this.name)}var handleClass=handle.$$.ptrType.registeredClass;var ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);return ptr}function simpleReadValueFromPointer(pointer){return this["fromWireType"](HEAPU32[pointer>>2])}function RegisteredPointer_getPointee(ptr){if(this.rawGetPointee){ptr=this.rawGetPointee(ptr)}return ptr}function RegisteredPointer_destructor(ptr){if(this.rawDestructor){this.rawDestructor(ptr)}}function RegisteredPointer_deleteObject(handle){if(handle!==null){handle["delete"]()}}function downcastPointer(ptr,ptrClass,desiredClass){if(ptrClass===desiredClass){return ptr}if(undefined===desiredClass.baseClass){return null}var rv=downcastPointer(ptr,ptrClass,desiredClass.baseClass);if(rv===null){return null}return desiredClass.downcast(rv)}function getInheritedInstanceCount(){return Object.keys(registeredInstances).length}function getLiveInheritedInstances(){var rv=[];for(var k in registeredInstances){if(registeredInstances.hasOwnProperty(k)){rv.push(registeredInstances[k])}}return rv}function setDelayFunction(fn){delayFunction=fn;if(deletionQueue.length&&delayFunction){delayFunction(flushPendingDeletes)}}function init_embind(){Module["getInheritedInstanceCount"]=getInheritedInstanceCount;Module["getLiveInheritedInstances"]=getLiveInheritedInstances;Module["flushPendingDeletes"]=flushPendingDeletes;Module["setDelayFunction"]=setDelayFunction}var registeredInstances={};function getBasestPointer(class_,ptr){if(ptr===undefined){throwBindingError("ptr should not be undefined")}while(class_.baseClass){ptr=class_.upcast(ptr);class_=class_.baseClass}return ptr}function getInheritedInstance(class_,ptr){ptr=getBasestPointer(class_,ptr);return registeredInstances[ptr]}function makeClassHandle(prototype,record){if(!record.ptrType||!record.ptr){throwInternalError("makeClassHandle requires ptr and ptrType")}var hasSmartPtrType=!!record.smartPtrType;var hasSmartPtr=!!record.smartPtr;if(hasSmartPtrType!==hasSmartPtr){throwInternalError("Both smartPtrType and smartPtr must be specified")}record.count={value:1};return attachFinalizer(Object.create(prototype,{$$:{value:record}}))}function RegisteredPointer_fromWireType(ptr){var rawPointer=this.getPointee(ptr);if(!rawPointer){this.destructor(ptr);return null}var registeredInstance=getInheritedInstance(this.registeredClass,rawPointer);if(undefined!==registeredInstance){if(0===registeredInstance.$$.count.value){registeredInstance.$$.ptr=rawPointer;registeredInstance.$$.smartPtr=ptr;return registeredInstance["clone"]()}else{var rv=registeredInstance["clone"]();this.destructor(ptr);return rv}}function makeDefaultHandle(){if(this.isSmartPointer){return makeClassHandle(this.registeredClass.instancePrototype,{ptrType:this.pointeeType,ptr:rawPointer,smartPtrType:this,smartPtr:ptr})}else{return makeClassHandle(this.registeredClass.instancePrototype,{ptrType:this,ptr:ptr})}}var actualType=this.registeredClass.getActualType(rawPointer);var registeredPointerRecord=registeredPointers[actualType];if(!registeredPointerRecord){return makeDefaultHandle.call(this)}var toType;if(this.isConst){toType=registeredPointerRecord.constPointerType}else{toType=registeredPointerRecord.pointerType}var dp=downcastPointer(rawPointer,this.registeredClass,toType.registeredClass);if(dp===null){return makeDefaultHandle.call(this)}if(this.isSmartPointer){return makeClassHandle(toType.registeredClass.instancePrototype,{ptrType:toType,ptr:dp,smartPtrType:this,smartPtr:ptr})}else{return makeClassHandle(toType.registeredClass.instancePrototype,{ptrType:toType,ptr:dp})}}function init_RegisteredPointer(){RegisteredPointer.prototype.getPointee=RegisteredPointer_getPointee;RegisteredPointer.prototype.destructor=RegisteredPointer_destructor;RegisteredPointer.prototype["argPackAdvance"]=8;RegisteredPointer.prototype["readValueFromPointer"]=simpleReadValueFromPointer;RegisteredPointer.prototype["deleteObject"]=RegisteredPointer_deleteObject;RegisteredPointer.prototype["fromWireType"]=RegisteredPointer_fromWireType}function RegisteredPointer(name,registeredClass,isReference,isConst,isSmartPointer,pointeeType,sharingPolicy,rawGetPointee,rawConstructor,rawShare,rawDestructor){this.name=name;this.registeredClass=registeredClass;this.isReference=isReference;this.isConst=isConst;this.isSmartPointer=isSmartPointer;this.pointeeType=pointeeType;this.sharingPolicy=sharingPolicy;this.rawGetPointee=rawGetPointee;this.rawConstructor=rawConstructor;this.rawShare=rawShare;this.rawDestructor=rawDestructor;if(!isSmartPointer&®isteredClass.baseClass===undefined){if(isConst){this["toWireType"]=constNoSmartPtrRawPointerToWireType;this.destructorFunction=null}else{this["toWireType"]=nonConstNoSmartPtrRawPointerToWireType;this.destructorFunction=null}}else{this["toWireType"]=genericPointerToWireType}}function replacePublicSymbol(name,value,numArguments){if(!Module.hasOwnProperty(name)){throwInternalError("Replacing nonexistant public symbol")}if(undefined!==Module[name].overloadTable&&undefined!==numArguments){Module[name].overloadTable[numArguments]=value}else{Module[name]=value;Module[name].argCount=numArguments}}function embind__requireFunction(signature,rawFunction){signature=readLatin1String(signature);function makeDynCaller(dynCall){var argCache=[rawFunction];return function(){argCache.length=arguments.length+1;for(var i=0;i>2)+i])}return array}function runDestructors(destructors){while(destructors.length){var ptr=destructors.pop();var del=destructors.pop();del(ptr)}}function __embind_register_class_constructor(rawClassType,argCount,rawArgTypesAddr,invokerSignature,invoker,rawConstructor){assert(argCount>0);var rawArgTypes=heap32VectorToArray(argCount,rawArgTypesAddr);invoker=embind__requireFunction(invokerSignature,invoker);var args=[rawConstructor];var destructors=[];whenDependentTypesAreResolved([],[rawClassType],function(classType){classType=classType[0];var humanName="constructor "+classType.name;if(undefined===classType.registeredClass.constructor_body){classType.registeredClass.constructor_body=[]}if(undefined!==classType.registeredClass.constructor_body[argCount-1]){throw new BindingError("Cannot register multiple constructors with identical number of parameters ("+(argCount-1)+") for class '"+classType.name+"'! Overload resolution is currently only performed using the parameter count, not actual type info!")}classType.registeredClass.constructor_body[argCount-1]=function unboundTypeHandler(){throwUnboundTypeError("Cannot construct "+classType.name+" due to unbound types",rawArgTypes)};whenDependentTypesAreResolved([],rawArgTypes,function(argTypes){classType.registeredClass.constructor_body[argCount-1]=function constructor_body(){if(arguments.length!==argCount-1){throwBindingError(humanName+" called with "+arguments.length+" arguments, expected "+(argCount-1))}destructors.length=0;args.length=argCount;for(var i=1;i4&&0===--emval_handle_array[handle].refcount){emval_handle_array[handle]=undefined;emval_free_list.push(handle)}}function count_emval_handles(){var count=0;for(var i=5;i>2])};case 3:return function(pointer){return this["fromWireType"](HEAPF64[pointer>>3])};default:throw new TypeError("Unknown float type: "+name)}}function __embind_register_float(rawType,name,size){var shift=getShiftFromSize(size);name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":function(value){return value},"toWireType":function(destructors,value){if(typeof value!=="number"&&typeof value!=="boolean"){throw new TypeError('Cannot convert "'+_embind_repr(value)+'" to '+this.name)}return value},"argPackAdvance":8,"readValueFromPointer":floatReadValueFromPointer(name,shift),destructorFunction:null})}function integerReadValueFromPointer(name,shift,signed){switch(shift){case 0:return signed?function readS8FromPointer(pointer){return HEAP8[pointer]}:function readU8FromPointer(pointer){return HEAPU8[pointer]};case 1:return signed?function readS16FromPointer(pointer){return HEAP16[pointer>>1]}:function readU16FromPointer(pointer){return HEAPU16[pointer>>1]};case 2:return signed?function readS32FromPointer(pointer){return HEAP32[pointer>>2]}:function readU32FromPointer(pointer){return HEAPU32[pointer>>2]};default:throw new TypeError("Unknown integer type: "+name)}}function __embind_register_integer(primitiveType,name,size,minRange,maxRange){name=readLatin1String(name);if(maxRange===-1){maxRange=4294967295}var shift=getShiftFromSize(size);var fromWireType=function(value){return value};if(minRange===0){var bitshift=32-8*size;fromWireType=function(value){return value<>>bitshift}}var isUnsignedType=name.indexOf("unsigned")!=-1;registerType(primitiveType,{name:name,"fromWireType":fromWireType,"toWireType":function(destructors,value){if(typeof value!=="number"&&typeof value!=="boolean"){throw new TypeError('Cannot convert "'+_embind_repr(value)+'" to '+this.name)}if(valuemaxRange){throw new TypeError('Passing a number "'+_embind_repr(value)+'" from JS side to C/C++ side to an argument of type "'+name+'", which is outside the valid range ['+minRange+", "+maxRange+"]!")}return isUnsignedType?value>>>0:value|0},"argPackAdvance":8,"readValueFromPointer":integerReadValueFromPointer(name,shift,minRange!==0),destructorFunction:null})}function __embind_register_memory_view(rawType,dataTypeIndex,name){var typeMapping=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array];var TA=typeMapping[dataTypeIndex];function decodeMemoryView(handle){handle=handle>>2;var heap=HEAPU32;var size=heap[handle];var data=heap[handle+1];return new TA(buffer,data,size)}name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":decodeMemoryView,"argPackAdvance":8,"readValueFromPointer":decodeMemoryView},{ignoreDuplicateRegistrations:true})}function __embind_register_std_string(rawType,name){name=readLatin1String(name);var stdStringIsUTF8=name==="std::string";registerType(rawType,{name:name,"fromWireType":function(value){var length=HEAPU32[value>>2];var str;if(stdStringIsUTF8){var decodeStartPtr=value+4;for(var i=0;i<=length;++i){var currentBytePtr=value+4+i;if(HEAPU8[currentBytePtr]==0||i==length){var maxRead=currentBytePtr-decodeStartPtr;var stringSegment=UTF8ToString(decodeStartPtr,maxRead);if(str===undefined){str=stringSegment}else{str+=String.fromCharCode(0);str+=stringSegment}decodeStartPtr=currentBytePtr+1}}}else{var a=new Array(length);for(var i=0;i>2]=length;if(stdStringIsUTF8&&valueIsOfTypeString){stringToUTF8(value,ptr+4,length+1)}else{if(valueIsOfTypeString){for(var i=0;i255){_free(ptr);throwBindingError("String has UTF-16 code units that do not fit in 8 bits")}HEAPU8[ptr+4+i]=charCode}}else{for(var i=0;i>2];var HEAP=getHeap();var str;var decodeStartPtr=value+4;for(var i=0;i<=length;++i){var currentBytePtr=value+4+i*charSize;if(HEAP[currentBytePtr>>shift]==0||i==length){var maxReadBytes=currentBytePtr-decodeStartPtr;var stringSegment=decodeString(decodeStartPtr,maxReadBytes);if(str===undefined){str=stringSegment}else{str+=String.fromCharCode(0);str+=stringSegment}decodeStartPtr=currentBytePtr+charSize}}_free(value);return str},"toWireType":function(destructors,value){if(!(typeof value==="string")){throwBindingError("Cannot pass non-string to C++ string type "+name)}var length=lengthBytesUTF(value);var ptr=_malloc(4+length+charSize);HEAPU32[ptr>>2]=length>>shift;encodeString(value,ptr+4,length+charSize);if(destructors!==null){destructors.push(_free,ptr)}return ptr},"argPackAdvance":8,"readValueFromPointer":simpleReadValueFromPointer,destructorFunction:function(ptr){_free(ptr)}})}function __embind_register_void(rawType,name){name=readLatin1String(name);registerType(rawType,{isVoid:true,name:name,"argPackAdvance":0,"fromWireType":function(){return undefined},"toWireType":function(destructors,o){return undefined}})}function _abort(){abort()}function _emscripten_get_sbrk_ptr(){return 532144}function _emscripten_memcpy_big(dest,src,num){HEAPU8.copyWithin(dest,src,src+num)}function _emscripten_get_heap_size(){return HEAPU8.length}function emscripten_realloc_buffer(size){try{wasmMemory.grow(size-buffer.byteLength+65535>>>16);updateGlobalBufferAndViews(wasmMemory.buffer);return 1}catch(e){}}function _emscripten_resize_heap(requestedSize){requestedSize=requestedSize>>>0;var oldSize=_emscripten_get_heap_size();var PAGE_MULTIPLE=65536;var maxHeapSize=2147483648;if(requestedSize>maxHeapSize){return false}var minHeapSize=16777216;for(var cutDown=1;cutDown<=4;cutDown*=2){var overGrownHeapSize=oldSize*(1+.2/cutDown);overGrownHeapSize=Math.min(overGrownHeapSize,requestedSize+100663296);var newSize=Math.min(maxHeapSize,alignUp(Math.max(minHeapSize,requestedSize,overGrownHeapSize),PAGE_MULTIPLE));var replacement=emscripten_realloc_buffer(newSize);if(replacement){return true}}return false}function _fd_close(fd){return 0}function _fd_fdstat_get(fd,pbuf){var type=fd==1||fd==2?2:abort();HEAP8[pbuf>>0]=type;return 0}function _fd_read(fd,iov,iovcnt,pnum){var stream=SYSCALLS.getStreamFromFD(fd);var num=SYSCALLS.doReadv(stream,iov,iovcnt);HEAP32[pnum>>2]=num;return 0}function _fd_seek(fd,offset_low,offset_high,whence,newOffset){}function _fd_write(fd,iov,iovcnt,pnum){var num=0;for(var i=0;i>2];var len=HEAP32[iov+(i*8+4)>>2];for(var j=0;j>2]=num;return 0}function _h264_write_polyfill(){err("missing function: h264_write_polyfill");abort(-1)}function _round(d){d=+d;return d>=+0?+Math_floor(d+ +.5):+Math_ceil(d-+.5)}function _roundf(d){d=+d;return d>=+0?+Math_floor(d+ +.5):+Math_ceil(d-+.5)}function _setTempRet0($i){setTempRet0($i|0)}embind_init_charCodes();BindingError=Module["BindingError"]=extendError(Error,"BindingError");InternalError=Module["InternalError"]=extendError(Error,"InternalError");init_ClassHandle();init_RegisteredPointer();init_embind();UnboundTypeError=Module["UnboundTypeError"]=extendError(Error,"UnboundTypeError");init_emval();var ASSERTIONS=false;var asmLibraryArg={"__assert_fail":___assert_fail,"__sys_fcntl64":___sys_fcntl64,"__sys_fstat64":___sys_fstat64,"__sys_ioctl":___sys_ioctl,"__sys_madvise1":___sys_madvise1,"__sys_open":___sys_open,"__sys_rename":___sys_rename,"__sys_stat64":___sys_stat64,"_embind_register_bool":__embind_register_bool,"_embind_register_class":__embind_register_class,"_embind_register_class_constructor":__embind_register_class_constructor,"_embind_register_class_function":__embind_register_class_function,"_embind_register_emval":__embind_register_emval,"_embind_register_float":__embind_register_float,"_embind_register_integer":__embind_register_integer,"_embind_register_memory_view":__embind_register_memory_view,"_embind_register_std_string":__embind_register_std_string,"_embind_register_std_wstring":__embind_register_std_wstring,"_embind_register_void":__embind_register_void,"abort":_abort,"emscripten_get_sbrk_ptr":_emscripten_get_sbrk_ptr,"emscripten_memcpy_big":_emscripten_memcpy_big,"emscripten_resize_heap":_emscripten_resize_heap,"fd_close":_fd_close,"fd_fdstat_get":_fd_fdstat_get,"fd_read":_fd_read,"fd_seek":_fd_seek,"fd_write":_fd_write,"h264_write_polyfill":_h264_write_polyfill,"memory":wasmMemory,"round":_round,"roundf":_roundf,"setTempRet0":_setTempRet0,"table":wasmTable};var asm=createWasm();var ___wasm_call_ctors=Module["___wasm_call_ctors"]=function(){return(___wasm_call_ctors=Module["___wasm_call_ctors"]=Module["asm"]["__wasm_call_ctors"]).apply(null,arguments)};var _h264_write=Module["_h264_write"]=function(){return(_h264_write=Module["_h264_write"]=Module["asm"]["h264_write"]).apply(null,arguments)};var _free=Module["_free"]=function(){return(_free=Module["_free"]=Module["asm"]["free"]).apply(null,arguments)};var _malloc=Module["_malloc"]=function(){return(_malloc=Module["_malloc"]=Module["asm"]["malloc"]).apply(null,arguments)};var ___getTypeName=Module["___getTypeName"]=function(){return(___getTypeName=Module["___getTypeName"]=Module["asm"]["__getTypeName"]).apply(null,arguments)};var ___embind_register_native_and_builtin_types=Module["___embind_register_native_and_builtin_types"]=function(){return(___embind_register_native_and_builtin_types=Module["___embind_register_native_and_builtin_types"]=Module["asm"]["__embind_register_native_and_builtin_types"]).apply(null,arguments)};var ___errno_location=Module["___errno_location"]=function(){return(___errno_location=Module["___errno_location"]=Module["asm"]["__errno_location"]).apply(null,arguments)};var stackSave=Module["stackSave"]=function(){return(stackSave=Module["stackSave"]=Module["asm"]["stackSave"]).apply(null,arguments)};var stackRestore=Module["stackRestore"]=function(){return(stackRestore=Module["stackRestore"]=Module["asm"]["stackRestore"]).apply(null,arguments)};var stackAlloc=Module["stackAlloc"]=function(){return(stackAlloc=Module["stackAlloc"]=Module["asm"]["stackAlloc"]).apply(null,arguments)};var __growWasmMemory=Module["__growWasmMemory"]=function(){return(__growWasmMemory=Module["__growWasmMemory"]=Module["asm"]["__growWasmMemory"]).apply(null,arguments)};var dynCall_ii=Module["dynCall_ii"]=function(){return(dynCall_ii=Module["dynCall_ii"]=Module["asm"]["dynCall_ii"]).apply(null,arguments)};var dynCall_vi=Module["dynCall_vi"]=function(){return(dynCall_vi=Module["dynCall_vi"]=Module["asm"]["dynCall_vi"]).apply(null,arguments)};var dynCall_i=Module["dynCall_i"]=function(){return(dynCall_i=Module["dynCall_i"]=Module["asm"]["dynCall_i"]).apply(null,arguments)};var dynCall_iiii=Module["dynCall_iiii"]=function(){return(dynCall_iiii=Module["dynCall_iiii"]=Module["asm"]["dynCall_iiii"]).apply(null,arguments)};var dynCall_iiiii=Module["dynCall_iiiii"]=function(){return(dynCall_iiiii=Module["dynCall_iiiii"]=Module["asm"]["dynCall_iiiii"]).apply(null,arguments)};var dynCall_iii=Module["dynCall_iii"]=function(){return(dynCall_iii=Module["dynCall_iii"]=Module["asm"]["dynCall_iii"]).apply(null,arguments)};var dynCall_viiii=Module["dynCall_viiii"]=function(){return(dynCall_viiii=Module["dynCall_viiii"]=Module["asm"]["dynCall_viiii"]).apply(null,arguments)};var dynCall_iij=Module["dynCall_iij"]=function(){return(dynCall_iij=Module["dynCall_iij"]=Module["asm"]["dynCall_iij"]).apply(null,arguments)};var dynCall_iiiiii=Module["dynCall_iiiiii"]=function(){return(dynCall_iiiiii=Module["dynCall_iiiiii"]=Module["asm"]["dynCall_iiiiii"]).apply(null,arguments)};var dynCall_vii=Module["dynCall_vii"]=function(){return(dynCall_vii=Module["dynCall_vii"]=Module["asm"]["dynCall_vii"]).apply(null,arguments)};var dynCall_viii=Module["dynCall_viii"]=function(){return(dynCall_viii=Module["dynCall_viii"]=Module["asm"]["dynCall_viii"]).apply(null,arguments)};var dynCall_viiiii=Module["dynCall_viiiii"]=function(){return(dynCall_viiiii=Module["dynCall_viiiii"]=Module["asm"]["dynCall_viiiii"]).apply(null,arguments)};var dynCall_viiiiii=Module["dynCall_viiiiii"]=function(){return(dynCall_viiiiii=Module["dynCall_viiiiii"]=Module["asm"]["dynCall_viiiiii"]).apply(null,arguments)};var dynCall_viiiiiii=Module["dynCall_viiiiiii"]=function(){return(dynCall_viiiiiii=Module["dynCall_viiiiiii"]=Module["asm"]["dynCall_viiiiiii"]).apply(null,arguments)};var dynCall_iiiiiiii=Module["dynCall_iiiiiiii"]=function(){return(dynCall_iiiiiiii=Module["dynCall_iiiiiiii"]=Module["asm"]["dynCall_iiiiiiii"]).apply(null,arguments)};var dynCall_jii=Module["dynCall_jii"]=function(){return(dynCall_jii=Module["dynCall_jii"]=Module["asm"]["dynCall_jii"]).apply(null,arguments)};var dynCall_viiiiiiii=Module["dynCall_viiiiiiii"]=function(){return(dynCall_viiiiiiii=Module["dynCall_viiiiiiii"]=Module["asm"]["dynCall_viiiiiiii"]).apply(null,arguments)};var dynCall_fiii=Module["dynCall_fiii"]=function(){return(dynCall_fiii=Module["dynCall_fiii"]=Module["asm"]["dynCall_fiii"]).apply(null,arguments)};var dynCall_viiiiiiiii=Module["dynCall_viiiiiiiii"]=function(){return(dynCall_viiiiiiiii=Module["dynCall_viiiiiiiii"]=Module["asm"]["dynCall_viiiiiiiii"]).apply(null,arguments)};var dynCall_iiiiiiiiii=Module["dynCall_iiiiiiiiii"]=function(){return(dynCall_iiiiiiiiii=Module["dynCall_iiiiiiiiii"]=Module["asm"]["dynCall_iiiiiiiiii"]).apply(null,arguments)};var dynCall_viiiiiiiiiii=Module["dynCall_viiiiiiiiiii"]=function(){return(dynCall_viiiiiiiiiii=Module["dynCall_viiiiiiiiiii"]=Module["asm"]["dynCall_viiiiiiiiiii"]).apply(null,arguments)};var dynCall_jiji=Module["dynCall_jiji"]=function(){return(dynCall_jiji=Module["dynCall_jiji"]=Module["asm"]["dynCall_jiji"]).apply(null,arguments)};var dynCall_iidiiii=Module["dynCall_iidiiii"]=function(){return(dynCall_iidiiii=Module["dynCall_iidiiii"]=Module["asm"]["dynCall_iidiiii"]).apply(null,arguments)};var calledRun;function ExitStatus(status){this.name="ExitStatus";this.message="Program terminated with exit("+status+")";this.status=status}dependenciesFulfilled=function runCaller(){if(!calledRun)run();if(!calledRun)dependenciesFulfilled=runCaller};function run(args){args=args||arguments_;if(runDependencies>0){return}preRun();if(runDependencies>0)return;function doRun(){if(calledRun)return;calledRun=true;Module["calledRun"]=true;if(ABORT)return;initRuntime();preMain();readyPromiseResolve(Module);if(Module["onRuntimeInitialized"])Module["onRuntimeInitialized"]();postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(function(){setTimeout(function(){Module["setStatus"]("")},1);doRun()},1)}else{doRun()}}Module["run"]=run;if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}noExitRuntime=true;run(); return Module.ready diff --git a/sdk/src/3rd/video-codec-lib/X264Encoder.wasm b/sdk/src/3rd/video-codec-lib/X264Encoder.wasm index 466e9c0af9ce5f51c30f553af7d198beaccba281..394363b4d7d22959b5f959cad9a0b8ed9e4d3ea8 100644 Binary files a/sdk/src/3rd/video-codec-lib/X264Encoder.wasm and b/sdk/src/3rd/video-codec-lib/X264Encoder.wasm differ diff --git a/sdk/src/AppController.js b/sdk/src/AppController.js index 151a23179a71a92416c8e55fed65adc0687fc069..b0bf8690280b4757af145842ac0394005264718c 100644 --- a/sdk/src/AppController.js +++ b/sdk/src/AppController.js @@ -261,6 +261,9 @@ class AppController { }; this.send = data => { + if (this.reconnection.reconnecting) { + return; + } this.socketWorker.postMessage({cmd: 'sendReq', data: data}); }; @@ -472,7 +475,7 @@ class AppController { // 计算网络时延 const tempNetworkInfo = this.networkInfo; tempNetworkInfo.kbitCount += (data || []).byteLength / K_UNIT; - + if (this.frameParser.shiftPackage('HeartBeat')) { this.__calcNetworkState(); } @@ -757,10 +760,26 @@ class AppController { this.appState = {state: Number(resp.code), message: resp.msg, tip}; this.subscribe.trigger('appStateChange', {...this.appState}); if (needToTellExit) { - this.appState = APP_STATE_FROM_CLIENT.exit; - this.subscribe.trigger('appStateChange', {...this.appState}); + setTimeout(() => { + this.closeSocket() + this._action = 'connect' + this.startParams.auth_ts = new Date().getTime() + this.startParams.session_id = this.uuid_32(); + document.getElementsByTagName('article')[0].remove(); + this.initSocket(this.options.connectURI); + }, 1000); + // this.appState = APP_STATE_FROM_CLIENT.exit; + // this.subscribe.trigger('appStateChange', {...this.appState}); } } + + uuid_32() { + let uuid = ''; + for(i = 0; i < 26; i++) { + uuid += Math.floor(Math.random()*10) + } + return uuid + '32uuid' + } processPhoneControlResp(pkg) { if (!pkg) { diff --git a/sdk/src/AppScreenPrint.js b/sdk/src/AppScreenPrint.js index 88406eeef4fb386f91524901ff716034f3d10658..ca85672e0700eae36e18f7352466d1ce52a0fccc 100644 --- a/sdk/src/AppScreenPrint.js +++ b/sdk/src/AppScreenPrint.js @@ -12,330 +12,446 @@ // See the License for the specific language governing permissions and // limitations under the License. +import JMuxer from 'jmuxer'; import work from 'webworkify-webpack'; import AESGCMCrypto from './AESGCMCrypto'; +import AudioPlayer from './AudioPlayer'; +import AutoRotation from './AutoRotation'; +import CanvasPlayer from './CanvasPlayer'; import Subscribe from './common/Subscribe'; +import CANVAS_WHITE_LIST from './config/canvasWhiteList'; import PROTOCOL_CONFIG from './config/protocolConfig'; import delayAnalysis from './DelayAnalysis'; import FrameParser from './FrameParser'; -import logger from './Logger'; +import Logger from './Logger'; +import TouchHandler from './TouchHandler'; import Util from './Util'; import SocketWorker from './worker/SocketWorker'; +import KeyboardInput from "./KeyboardInput"; +import DirectionHandler from './DirectionHandler'; +import DeviceHardwareHandler from './DeviceHardwareHandler'; import { - PACKAGE_HEADER_LENGTH, - MEDIA_MSG_HEADER_COUNT, - DEFAULT_DEFINITION, - FRAME_TYPE_MAP, + PACKAGE_HEADER_LENGTH, + MEDIA_MSG_HEADER_COUNT, + DEFAULT_DEFINITION, + FRAME_TYPE_MAP } from './config/commonConfig'; +import FullScreen from './Fullscreen'; +import KeyboardListener from './KeyboardListener'; + /*global __IS_DEBUG__*/ if (__IS_DEBUG__) { - window.delayAnalysis = delayAnalysis; + window.delayAnalysis = delayAnalysis; } -const CAE_STREAM_DELIMITER_MAGICWORD = 0x5a5a; + +const CAE_STREAM_DELIMITER_MAGICWORD = 0x5A5A; const K_UNIT = 1000; const K_BIT_UNIT = 8000; const DEFAULT_ORIENTATION = 'PORTRAIT'; const APP_STATE_FROM_CLIENT = { - connecting: { - state: 256, - message: 'Connecting', - }, - connected: { - state: 512, - message: 'Connect success', - }, - unreachable: { - state: 769, - message: 'Server unreachable', - tip: '连接服务器失败,请稍后重试', - }, - reconnecting: { - state: 2816, - message: 'Reconnecting', - }, - exit: { - state: 5888, - message: 'Cloud Phone exit', - tip: '已退出', - }, + 'connecting': { + state: 256, + message: 'Connecting' + }, + 'connected': { + state: 512, + message: 'Connect success' + }, + 'unreachable': { + state: 769, + message: 'Server unreachable', + tip: '连接服务器失败,请稍后重试' + }, + 'reconnecting': { + state: 2816, + message: 'Reconnecting' + }, + 'exit': { + state: 5888, + message: 'Cloud Phone exit', + tip: '已退出' + } }; const APP_STATE_ERROR_CODE_TIP = { - 5888: '已退出', - 769: '连接服务器失败,请稍后重试', - 2308: '启动失败', - 4353: '启动失败', - 770: '资源正在使用中,请稍后', - 65535: '与服务器连接出现异常', - 1537: '认证失败', - 1538: '认证失败', - 1539: '认证失败', - 1540: '认证失败', - 1541: '认证失败', - 1542: '认证失败', - 1543: '登录信息失效,请重新登录', - 3584: '试玩时间已到', - 2560: '与服务器连接出现异常', - 3840: '由于您长时间未操作,服务断开', - 4096: '切换后台超时', - 8960: '云机在其他设备上被连接,本次连接退出', + 5888: '已退出', + 769: '连接服务器失败,请稍后重试', + 2308: '启动失败', + 4353: '启动失败', + 770: '资源正在使用中,请稍后', + 65535: '与服务器连接出现异常', + 1537: '认证失败', + 1538: '认证失败', + 1539: '认证失败', + 1540: '认证失败', + 1541: '认证失败', + 1542: '认证失败', + 1543: '登录信息失效,请重新登录', + 3584: '试玩时间已到', + 2560: '与服务器连接出现异常', + 3840: '由于您长时间未操作,服务断开', + 4096: '切换后台超时', + 8960: '云机在其他设备上被连接,本次连接退出' }; const DEFAULT_VALUME_VALUE = 50; const WEBSOCKET_READY_STATE = { - CONNECTING: 0, - OPEN: 1, - CLOSING: 2, - CLOSED: 3, + CONNECTING: 0, + OPEN: 1, + CLOSING: 2, + CLOSED: 3 }; const WORKER_STATE = { - CHECKING: 0, - LIVE: 1, + CHECKING: 0, + LIVE: 1 }; class AppController { - constructor(options) { - this.firstIFrame = true; - this.options = { volume: DEFAULT_VALUME_VALUE, ...options }; - this.util = new Util(); - this.currentVisible = 'visibility'; - this.subscribe = new Subscribe([ - 'appStateChange', - 'cloudAppData', - 'phoneViewChange', - ]); - // WebSocket variable - this.useSocketWorker = AppController.isSupportURL(); - this.wsState = undefined; - this.sessionId = this.options.sessionId || this.generateGUID(); - this.reconnection = { - can: true, - maxTimes: this.options.reconnectTimes, - count: 0, - timerDelay: 1000, - timerHander: null, - reconnecting: false, // 用于标识已进入重连流程,避免page visibility、page show处理时判断是否要主动触发重连 - trigger: '', // 标识什么事件触发了重连,visibilityChange/pageshow/socketCloseEvent - }; - // 网络时延/码率 - this.networkInfo = { - heartBeatSendTimes: [], - sendTimesMaxCount: 4, - delay: 0, - bitRate: 0, - kbitCount: 0, - lastRefreshTime: 0, - }; - this.lastReceivingTime = null; - - this.frameParser = new FrameParser(this.options.supportAudio); - this.curResolution = { ...PROTOCOL_CONFIG.DEFAULT_RESOLUTION }; - this.createSocket(); - this.socketWorkerState = { - worker: null, - socket: null, - }; - this.appState = null; - this.socketHasOpenned = false; // 标识socket是否已open过,用于重连时判断发送connect还是reconnect cmd - } + constructor(options) { + this.firstIFrame = true; + this.options = {volume: DEFAULT_VALUME_VALUE, ...options}; + this.util = new Util(); + this.render = true; + this.player = null; + this.currentVisible = 'visibility'; + this.playerContainerId = undefined; + this.subscribe = new Subscribe([ + 'phoneViewChange', + 'appStateChange', + 'cloudAppData', + ]); + this.cameraMsgHeader = null; + this.microPhoneMsgHeader = null; + this.cameraMsgBody = null; + this.microPhoneMsgBody = null; + this.sensorMsgHeader = null; + this.gpsLocationMsgHeader = null; + this.cameraMsgType = PROTOCOL_CONFIG.CAMERA_MESSAGE_TYPE; + this.microPhoneMsgType = PROTOCOL_CONFIG.MICROPHONE_MESSAGE_TYPE; + this.sensorMsgType = PROTOCOL_CONFIG.SENSOR_MESSAGE_TYPE; + this.keyEventCodeType = PROTOCOL_CONFIG.KEYEVENT_KEYCODE_TYPE; + this.gpsLocationMsgType = PROTOCOL_CONFIG.GPS_LOCATION_MESSAGE_TYPE; + // WebSocket variable + this.useSocketWorker = AppController.isSupportURL(); + this.wsState = undefined; + this.sessionId = this.options.sessionId || this.generateGUID(); + this.reconnection = { + can: true, + maxTimes: this.options.reconnectTimes, + count: 0, + timerDelay: 1000, + timerHander: null, + reconnecting: false, // 用于标识已进入重连流程,避免page visibility、page show处理时判断是否要主动触发重连 + trigger: '' // 标识什么事件触发了重连,visibilityChange/pageshow/socketCloseEvent + }; + // 网络时延/码率 + this.networkInfo = { + heartBeatSendTimes: [], + sendTimesMaxCount: 4, + delay: 0, + bitRate: 0, + kbitCount: 0, + lastRefreshTime: 0 + }; + this.lastReceivingTime = null; + this.heartBeatInterval = 1000; + this.linkOverTime = 4000; + + this.frameParser = new FrameParser(this.options.supportAudio); + this.autoRotation = null; + this.curResolution = {...PROTOCOL_CONFIG.DEFAULT_RESOLUTION}; + this.nextResolution = {...PROTOCOL_CONFIG.DEFAULT_RESOLUTION}; - createSocket() { - if (this.useSocketWorker) { - this.__createSocketWorker(); - } else { - this.__createSocketWithoutWorker(); + this.createSocket(); + this.socketWorkerState = { + worker: null, + socket: null + }; + this.appState = null; + this.socketHasOpenned = false; // 标识socket是否已open过,用于重连时判断发送connect还是reconnect cmd + + // 初始化全屏类 + this.fullscreen = new FullScreen({ + containerId: this.options.containerId, + autoRotate: this.options.autoRotate, + isMobile: this.options.isMobile + }); + this.fullscreen.init(); } - } - - __createSocketWorker() { - /* javascript-obfuscator:disable */ - this.socketWorker = work(require.resolve('./worker/SocketWorker.js')); - - /* javascript-obfuscator:enable */ - this.socketWorker.addEventListener('message', evt => { - const objData = evt.data; - switch (objData.cmd) { - case 'openRsp': - this.onOpenSocket(objData.state); - break; - case 'errorRsp': - this.onError(); - break; - case 'recvRsp': - this.onMessage(objData.buf, objData.time); - break; - case 'heartbeatRsp': - this.recordHeartbeat(objData.time); - break; - case 'closeRsp': - if ( - (this.reconnection.reconnecting && - this.reconnection.trigger === 'socketCloseEvent') || - !this.reconnection.reconnecting - ) { - this.onClose(objData.state, 'socketCloseEvent'); - } - - break; - case 'socketStateRsp': - this.updateSocketWorkerState(WORKER_STATE.LIVE, objData.state); - break; - default: - logger.debug('Unknown command from socket worker.'); - } - }); - this.socketWorker.addEventListener('error', () => { - logger.debug('Socket worker error.'); - }); - this.initSocket = connectURI => { - this.socketWorker.postMessage({ - cmd: 'initReq', - options: { - protocol: _HTTP_MODE_ ? 'ws' : 'wss', - connectURI, - needHeatBeat: this.options.needHeatBeat, - }, - }); - }; - - this.send = data => { - this.socketWorker.postMessage({ cmd: 'sendReq', data: data }); - }; - this.startHeartbeat = () => { - this.socketWorker.postMessage({ cmd: 'startHeartbeatReq' }); - }; - - this.stopHeartbeat = () => { - this.socketWorker.postMessage({ cmd: 'stopHeartbeatReq' }); - }; + createSocket() { + if (this.useSocketWorker) { + this.__createSocketWorker(); + } else { + this.__createSocketWithoutWorker(); + } + } - this.closeSocket = () => { - this.socketWorker.postMessage({ cmd: 'closeReq' }); - }; + __createSocketWorker() { + + /* javascript-obfuscator:disable */ + this.socketWorker = work(require.resolve('./worker/SocketWorker.js')); + + /* javascript-obfuscator:enable */ + this.socketWorker.addEventListener('message', evt => { + const objData = evt.data; + switch (objData.cmd) { + case 'openRsp': + this.onOpenSocket(objData.state); + break; + case 'errorRsp': + this.onError(); + break; + case 'recvRsp': + this.onMessage(objData.buf, objData.time); + break; + case 'heartbeatRsp': + this.recordHeartbeat(objData.time); + break; + case 'closeRsp': + if ((this.reconnection.reconnecting && this.reconnection.trigger === 'socketCloseEvent') || !this.reconnection.reconnecting) { + this.onClose(objData.state, 'socketCloseEvent'); + } + + break; + case 'socketStateRsp': + this.updateSocketWorkerState(WORKER_STATE.LIVE, objData.state); + break; + default: + Logger.debug('Unknown command from socket worker.'); + } + }); + this.socketWorker.addEventListener('error', () => { + Logger.debug('Socket worker error.'); + }); - this.checkSocketWorkerState = () => { - this.updateSocketWorkerState(WORKER_STATE.CHECKING, null); - this.socketWorker.postMessage({ cmd: 'socketStateReq' }); - }; - } + this.initSocket = connectURI => { + this.socketWorker.postMessage({ + cmd: 'initReq', + options: { + protocol: _HTTP_MODE_ ? 'ws' : 'wss', + connectURI, + needHeatBeat: this.options.needHeatBeat + } + }); + }; + + this.send = data => { + this.socketWorker.postMessage({cmd: 'sendReq', data: data}); + }; + + this.startHeartbeat = () => { + this.socketWorker.postMessage({cmd: 'startHeartbeatReq'}); + }; + + this.stopHeartbeat = () => { + this.socketWorker.postMessage({cmd: 'stopHeartbeatReq'}); + }; + + this.closeSocket = () => { + this.socketWorker.postMessage({cmd: 'closeReq'}); + }; + + this.checkSocketWorkerState = () => { + this.updateSocketWorkerState(WORKER_STATE.CHECKING, null); + this.socketWorker.postMessage({cmd: 'socketStateReq'}); + }; + } - __createSocketWithoutWorker() { - this.socket = new SocketWorker(); - this.initSocket = connectURI => { - this.socket.init({ - protocol: _HTTP_MODE_ ? 'ws' : 'wss', - connectURI, - needHeatBeat: this.options.needHeatBeat, - }); - }; + __createSocketWithoutWorker () { + this.socket = new SocketWorker(); + this.initSocket = connectURI => { + this.socket.init({ + protocol: _HTTP_MODE_ ? 'ws' : 'wss', + connectURI, + needHeatBeat: this.options.needHeatBeat + }); + }; + + // playEvent使用时,使用self + this.send = data => { + this.socket.send(data); + }; + + this.startHeartbeat = () => { + this.socket.startHeartbeat(); + }; + + this.stopHeartbeat = () => { + this.socket.stopHeartbeat(); + }; + + this.closeSocket = () => { + this.socket.destroy(); + }; + + this.socket.onOpen = this.onOpenSocket.bind(this); + this.socket.onError = this.onError.bind(this); + this.socket.onMessage = data => { + this.onMessage(data, Date.now()); + }; + + this.socket.onClose = this.onClose.bind(this); + this.socket.onHeartbeatSended = this.recordHeartbeat.bind(this); + } - // playEvent使用时,使用self - this.send = data => { - this.socket.send(data); - }; + onOpenSocket(state) { + this.socketHasOpenned = true; + this.wsState = state; + // page visibility场景检查socket状态后延迟处理,此处刷新socket状态,避免在延迟时间里close触发重连后,page visibility再次重连。 + this.updateSocketWorkerState(WORKER_STATE.LIVE, state); + this.reconnection.can = true; + this.reconnection.count = 0; + this.reconnection.reconnecting = false; + + // 发送启动命令获取音视频数据 + switch (this._action) { + case 'reconnect': + this._reconnect(); + break; + default: + this.appState = APP_STATE_FROM_CLIENT.connected; + this.subscribe.trigger('appStateChange', {...this.appState}); + this.startCloudPhone(); + this.listenPageVisibility(); + this.listenPageShow(); + } + } - this.startHeartbeat = () => { - this.socket.startHeartbeat(); - }; + initPlyerAndStart() { + this.player = document.getElementById(this.options.containerId); + this.playerContainerId = document.getElementById(this.options.containerId); + if (this.player) { + this.touchHandler = new TouchHandler({ + player: this.player, + isMobile: this.options.isMobile, + sendHandler: this.send, + isDebug: this.options.isDebug, + autoRotate: this.options.autoRotate, + inputId: this.keyboardInput && this.keyboardInput.inputId || '', + containerId: this.options.containerId, + }); + this.touchHandler.start(); + + this.directionHandler = new DirectionHandler({ + containerId: this.options.containerId, + isMobile: this.options.isMobile, + keepRatio: this.options.keepRatio, + playerContainerId: this.playerContainerId, + touchHandler: this.touchHandler + }); + this.directionHandler.init(); + this.listenPlayerSizeChange(); + + this.autoRotation = new AutoRotation(this.options.containerId, + DEFAULT_ORIENTATION, this.options.isMobile,rotateDegrees => { + // 旋转后更新触控,并根据旋转角度判断使用云机键盘还是真机键盘 + this.touchHandler.resize(); + }); + this.autoRotation.init(); + + this.updateResolutionAndTouch(); + } + } - this.stopHeartbeat = () => { - this.socket.stopHeartbeat(); - }; + triggerSubscribe(event, data) { + this.subscribe.trigger(event.name, data); + } - this.closeSocket = () => { - this.socket.destroy(); - }; + listenPlayerSizeChange() { + if (this.isMSE) { + // 视频元信息加载完成后,主动触发 resize 事件更新相关坐标位置 + this.loadedmetadataCallback = () => { + this.touchHandler.resize(); + // 使用完毕移除事件监听 + this.player.removeEventListener('loadedmetadata', this.loadedmetadataCallback); + this.loadedmetadataCallback = null; + }; + + this.player.addEventListener('loadedmetadata', this.loadedmetadataCallback); + + // video 大小变化时需要持续更新坐标位置 + this.videoResizeCallback = () => { + this.touchHandler.resize(); + }; + + this.player.addEventListener('resize', this.videoResizeCallback); + } else { + // 监听 canvas 大小变化 + const MutationObserver = window.MutationObserver; + this.canvasObserver = new MutationObserver(mutations => { + mutations.forEach(mutation => { + if (mutation.attributeName === 'width' || mutation.attributeName === 'height') { + this.touchHandler.resize(); + } + }); + }); + this.canvasObserver.observe(this.player, {attributes: true}); + } + } - this.socket.onOpen = this.onOpenSocket.bind(this); - this.socket.onError = this.onError.bind(this); - this.socket.onMessage = data => { - this.onMessage(data, Date.now()); - }; + onMessage(data, time) { + this.lastReceivingTime = time; - this.socket.onClose = this.onClose.bind(this); - this.socket.onHeartbeatSended = this.recordHeartbeat.bind(this); - } + let videoNum = 0; + let beforeParseTime = 0; + /*global __IS_DEBUG__*/ + if (__IS_DEBUG__) { + videoNum = this.frameParser.getPackageCacheNum('Video'); + beforeParseTime = Date.now(); + } - onOpenSocket(state) { - this.socketHasOpenned = true; - this.wsState = state; - // page visibility场景检查socket状态后延迟处理,此处刷新socket状态,避免在延迟时间里close触发重连后,page visibility再次重连。 - this.updateSocketWorkerState(WORKER_STATE.LIVE, state); - this.reconnection.can = true; - this.reconnection.count = 0; - this.reconnection.reconnecting = false; - - // 发送启动命令获取音视频数据 - switch (this._action) { - case 'reconnect': - this._reconnect(); - break; - default: - this.appState = APP_STATE_FROM_CLIENT.connected; - this.subscribe.trigger('appStateChange', { ...this.appState }); - this.startCloudPhone(); - this.listenPageVisibility(); - this.listenPageShow(); - } - } + this.frameParser.readPackage(data); + /*global __IS_DEBUG__*/ + if (__IS_DEBUG__ && this.frameParser.getPackageCacheNum('Video') - videoNum > 0) { + let traceId = window.delayAnalysis.allocTraceId(); + window.delayAnalysis.record(['receive', 'end', traceId], null, time); + window.delayAnalysis.record(['parse', 'start', traceId], null, beforeParseTime); + window.delayAnalysis.record(['parse', 'end', traceId]); + window.delayAnalysis.cacheTraceId('receive', traceId); + } - triggerSubscribe(event, data) { - this.subscribe.trigger(event.name, data); - } + // 计算网络时延 + const tempNetworkInfo = this.networkInfo; + tempNetworkInfo.kbitCount += (data || []).byteLength / K_UNIT; - onMessage(data, time) { - this.lastReceivingTime = time; - - let videoNum = 0; - let beforeParseTime = 0; - /*global __IS_DEBUG__*/ - if (__IS_DEBUG__) { - videoNum = this.frameParser.getPackageCacheNum('Video'); - beforeParseTime = Date.now(); - } - - this.frameParser.readPackage(data); - /*global __IS_DEBUG__*/ - if ( - __IS_DEBUG__ && - this.frameParser.getPackageCacheNum('Video') - videoNum > 0 - ) { - let traceId = window.delayAnalysis.allocTraceId(); - window.delayAnalysis.record(['receive', 'end', traceId], null, time); - window.delayAnalysis.record( - ['parse', 'start', traceId], - null, - beforeParseTime, - ); - window.delayAnalysis.record(['parse', 'end', traceId]); - window.delayAnalysis.cacheTraceId('receive', traceId); - } - - // 计算网络时延 - const tempNetworkInfo = this.networkInfo; - tempNetworkInfo.kbitCount += (data || []).byteLength / K_UNIT; - - const SnapshotPkg = this.frameParser.shiftPackage('Snapshot'); - if (SnapshotPkg) { - const imgBase64 = - 'data:image/jpg;base64,' + - window.btoa(this.arrayBufferToBase64(SnapshotPkg)); - if (imgBase64) { - this.subscribe.trigger('phoneViewChange', imgBase64); + if (this.frameParser.shiftPackage('HeartBeat')) { + this.__calcNetworkState(); } - } - const cmdControlPkg = this.frameParser.shiftPackage('CmdControl'); - this.processCmdControlResp(cmdControlPkg); - const phoneControlPkg = this.frameParser.shiftPackage('PhoneControl'); - this.processPhoneControlResp(phoneControlPkg); + const SnapshotPkg = this.frameParser.shiftPackage('Snapshot'); + if (SnapshotPkg) { + const imgBase64 = + 'data:image/jpg;base64,' + + window.btoa(this.arrayBufferToBase64(SnapshotPkg)); + if (imgBase64) { + this.subscribe.trigger('phoneViewChange', imgBase64); + } + } + + const cmdControlPkg = this.frameParser.shiftPackage('CmdControl'); + this.processCmdControlResp(cmdControlPkg); + + const phoneControlPkg = this.frameParser.shiftPackage('PhoneControl'); + this.processPhoneControlResp(phoneControlPkg); + + // 若启动竖屏,CAE不发送旋转msg + const orientationPkg = this.frameParser.shiftPackage('Orientation'); + if (orientationPkg) { + let pkgBody = orientationPkg & 0xFF; + const orientation = PROTOCOL_CONFIG.ORIENTATION[pkgBody]; + Logger.debug('Orientation change:' + orientation); + this.pkgBody = pkgBody; + this.orientation = orientation; + this.updateResolutionAndTouch(); + } - const channelDataPkg = this.frameParser.shiftPackage('Channel'); - if (channelDataPkg) { - this.processChannelData(channelDataPkg); + const channelDataPkg = this.frameParser.shiftPackage('Channel'); + if (channelDataPkg) { + this.processChannelData(channelDataPkg) + } } - } + arrayBufferToBase64(buffer) { const uint8Array = new Uint8Array(buffer); const data = uint8Array.reduce( @@ -345,557 +461,669 @@ class AppController { return data; } - __calcNetworkState() { - if (this.networkInfo.heartBeatSendTimes.length > 0) { - this.networkInfo.delay = - this.lastReceivingTime - this.networkInfo.heartBeatSendTimes.shift(); + updateResolutionAndTouch() { + if (this.player && this.orientation) { + // resize之前更新canvas大小 + if (this.options.isMobile) { + this.directionHandler.updateMobileCanvasSize(this.orientation, this.isMSE); + } else { + this.directionHandler.updateCanvasSize(this.orientation, this.isMSE); + } + this.touchHandler.updateOrientation(this.orientation); + this.autoRotation && this.autoRotation.updateOrientation(this.orientation, this.touchHandler.displayBox, this.directionHandler); + } } - if (this.lastReceivingTime !== this.networkInfo.lastRefreshTime) { - this.networkInfo.bitRate = Math.round( - (this.networkInfo.kbitCount * K_BIT_UNIT) / - (this.lastReceivingTime - this.networkInfo.lastRefreshTime), - ); - this.networkInfo.lastRefreshTime = this.lastReceivingTime; - this.networkInfo.kbitCount = 0; - } - } + + __calcNetworkState() { + if (this.networkInfo.heartBeatSendTimes.length > 0) { + this.networkInfo.delay = this.lastReceivingTime - this.networkInfo.heartBeatSendTimes.shift(); + } - onError() { - this.appState = APP_STATE_FROM_CLIENT.unreachable; - this.subscribe.trigger('appStateChange', { ...this.appState }); + if (this.lastReceivingTime !== this.networkInfo.lastRefreshTime) { + this.networkInfo.bitRate = Math.round(this.networkInfo.kbitCount * K_BIT_UNIT / (this.lastReceivingTime - this.networkInfo.lastRefreshTime)); + this.networkInfo.lastRefreshTime = this.lastReceivingTime; + this.networkInfo.kbitCount = 0; + } + + this.subscribe.trigger('netStateChange', { + delay: this.networkInfo.delay, + bitrate: this.networkInfo.bitRate + }); } - processCmdControlResp(pkg) { - if (!pkg) { - return; - } - - let buf = new Uint8Array(pkg); - let text = ''; - buf.forEach(c => { - text += String.fromCharCode(c); - }); - let resp = this.params2JSON(text); - let code = Number(resp.code); - const codeConfig = PROTOCOL_CONFIG.CMD_RESP_TYPE; - let needToTellExit = false; - switch (code) { - case codeConfig.CONNECT_FAILED: - case codeConfig.VERIFY_FAILED: - case codeConfig.START_FAILED: - logger.debug('Receive failed response, disconnect'); - this.disconnect(); - break; - case codeConfig.PLAY_TIMEOUT: - logger.debug('Play timeout, disconnect'); - this.disconnect(); - break; - case codeConfig.TOUCH_TIMEOUT: - logger.debug('Touch timeout, disconnect'); - this.disconnect(); - break; - case codeConfig.PAUSE_TIMEOUT: - logger.debug('Pause timeout, disconnect'); - this.disconnect(); - break; - case codeConfig.PHONE_CONNECTED_EXCEED_LIMIT: - logger.debug('Phone connected exceed limit, disconnect'); - this.disconnect(); - break; - case codeConfig.INVALID_OPERATION: - case codeConfig.RECONNECT_PARAMETER_INVALID: - case codeConfig.RECONNECT_SERVER_UNREACHABLE: - case codeConfig.RECONNECT_ENGING_START_ERROR: - // 重连后未重连成功前接收到无效操作,则认为重连失败。场景为:iphone手机切后台导致断连超时后切回应用重连的场景 - if (this.appState.state === APP_STATE_FROM_CLIENT.reconnecting.state) { - logger.debug('Reconnect faild, disconnect'); - this.disconnect(); - needToTellExit = true; - } - - break; - case codeConfig.H265_NOT_SUPPORT: - this.startParams.media_config.frame_type = FRAME_TYPE_MAP.TYPE264; - this.startCloudPhone(); - break; - default: - break; - } - - const tip = APP_STATE_ERROR_CODE_TIP[resp.code]; - this.appState = { state: Number(resp.code), message: resp.msg, tip }; - this.subscribe.trigger('appStateChange', { ...this.appState }); - if (needToTellExit) { - this.appState = APP_STATE_FROM_CLIENT.exit; - this.subscribe.trigger('appStateChange', { ...this.appState }); + onError() { + this.appState = APP_STATE_FROM_CLIENT.unreachable; + this.subscribe.trigger('appStateChange', {...this.appState}); } - } - processPhoneControlResp(pkg) { - if (!pkg) { - return; + updateResolution() { + if (this.curResolution.width === this.nextResolution.width && this.curResolution.height === this.nextResolution.height) { + return; + } + + this.touchHandler.updateResolution(this.nextResolution.width, this.nextResolution.height); + this.curResolution = this.nextResolution; } - const buf = new Uint8Array(pkg); - if (!buf.length) { - return; + processCmdControlResp(pkg) { + if (!pkg) { + return; + } + + let buf = new Uint8Array(pkg); + let text = ''; + buf.forEach(c => { + text += String.fromCharCode(c); + }); + let resp = this.params2JSON(text); + let code = Number(resp.code); + const codeConfig = PROTOCOL_CONFIG.CMD_RESP_TYPE; + let needToTellExit = false; + switch (code) { + case codeConfig.CONNECT_FAILED: + case codeConfig.VERIFY_FAILED: + case codeConfig.START_FAILED: + Logger.debug('Receive failed response, disconnect'); + this.disconnect(); + break; + case codeConfig.PHONE_CONNECTED: + Logger.debug('Phone has connected, disconnect'); + this.disconnect(); + break; + case codeConfig.PLAY_TIMEOUT: + Logger.debug('Play timeout, disconnect'); + this.disconnect(); + break; + case codeConfig.TOUCH_TIMEOUT: + Logger.debug('Touch timeout, disconnect'); + this.disconnect(); + break; + case codeConfig.PAUSE_TIMEOUT: + Logger.debug('Pause timeout, disconnect'); + this.disconnect(); + break; + case codeConfig.PHONE_CONNECTED_EXCEED_LIMIT: + logger.debug('Phone connected exceed limit, disconnect'); + this.disconnect(); + break; + case codeConfig.START_SUCCESS: + this.startPlay(); + this.isMSE = true; + this.initPlyerAndStart(); + this.updateResolution(); + break; + case codeConfig.INVALID_OPERATION: + case codeConfig.RECONNECT_PARAMETER_INVALID: + case codeConfig.RECONNECT_FAILED: + case codeConfig.RECONNECT_SERVER_UNREACHABLE: + case codeConfig.RECONNECT_ENGING_START_ERROR: + // 重连后未重连成功前接收到无效操作,则认为重连失败。场景为:iphone手机切后台导致断连超时后切回应用重连的场景 + if (this.appState.state === APP_STATE_FROM_CLIENT.reconnecting.state) { + Logger.debug('Reconnect faild, disconnect'); + this.disconnect(); + needToTellExit = true; + } + + break; + case codeConfig.H265_NOT_SUPPORT: + this.startParams.media_config.frame_type = FRAME_TYPE_MAP.TYPE264; + this.startCloudPhone(); + break; + default: + break; + } + + const tip = APP_STATE_ERROR_CODE_TIP[resp.code]; + this.appState = {state: Number(resp.code), message: resp.msg, tip}; + this.subscribe.trigger('appStateChange', {...this.appState}); + if (needToTellExit) { + this.appState = APP_STATE_FROM_CLIENT.exit; + this.subscribe.trigger('appStateChange', {...this.appState}); + } } - const code = buf[0]; - const stateConfig = PROTOCOL_CONFIG.PHONE_CONNECTION_STATE[code]; - if (stateConfig) { - logger.debug(stateConfig.message); - this.appState = stateConfig; - this.subscribe.trigger('appStateChange', { ...this.appState }); + processPhoneControlResp(pkg) { + if (!pkg) { + return; + } + + const buf = new Uint8Array(pkg); + if (!buf.length) { + return; + } + + const code = buf[0]; + const stateConfig = PROTOCOL_CONFIG.PHONE_CONNECTION_STATE[code]; + if (stateConfig) { + Logger.debug(stateConfig.message); + this.appState = stateConfig; + this.subscribe.trigger('appStateChange', {...this.appState}); + } } - } - processChannelData(pkg) { - this.subscribe.trigger('cloudAppData', pkg.buffer); - } + processChannelData(pkg) { + this.subscribe.trigger('cloudAppData', pkg.buffer); + } - recordHeartbeat(time) { - if ( - this.networkInfo.heartBeatSendTimes.length <= - this.networkInfo.sendTimesMaxCount - ) { - this.networkInfo.heartBeatSendTimes.push(time); - } else { - this.networkInfo.heartBeatSendTimes = []; - this.terminateSocketWorker(); - setTimeout(() => { - this.createSocket(); - this.reconnect(); - }, 0); + recordHeartbeat(time) { + if (this.networkInfo.heartBeatSendTimes.length <= this.networkInfo.sendTimesMaxCount){ + this.networkInfo.heartBeatSendTimes.push(time); + } else { + this.networkInfo.heartBeatSendTimes = [] + this.terminateSocketWorker(); + setTimeout(() => { + this.createSocket(); + this.reconnect(); + }, 0); + } } - } - tryReconnect(trigger) { - // client自主断连和CAE断连外认为异常断连,尝试重连 - const tempReconnection = this.reconnection; - tempReconnection.reconnecting = true; - tempReconnection.trigger = trigger; - if ( - tempReconnection.can && - tempReconnection.count < tempReconnection.maxTimes - ) { - tempReconnection.count++; - tempReconnection.timerHander && - clearTimeout(tempReconnection.timerHander); - // 延迟reconnect,但需立即触发appStateChange,以便客户显示loading。 - this.appState = this.socketHasOpenned - ? APP_STATE_FROM_CLIENT.reconnecting - : APP_STATE_FROM_CLIENT.connecting; - this.subscribe.trigger('appStateChange', { ...this.appState }); - tempReconnection.timerHander = setTimeout(() => { - this.reconnect(); - }, tempReconnection.timerDelay); - } - - // 若重连,会在重连失败后更新appState;若不重连,则直接更新appState。websocket初始建连失败时会进入error和close回调,此时更新为exit状态并不合适。 - if ( - tempReconnection.maxTimes === 0 && - this.appState.state === APP_STATE_FROM_CLIENT.connected.state - ) { - this.appState = APP_STATE_FROM_CLIENT.exit; - this.subscribe.trigger('appStateChange', { ...this.appState }); + tryReconnect(trigger) { + // client自主断连和CAE断连外认为异常断连,尝试重连 + const tempReconnection = this.reconnection; + tempReconnection.reconnecting = true; + tempReconnection.trigger = trigger; + if (tempReconnection.can && tempReconnection.count < tempReconnection.maxTimes) { + tempReconnection.count++; + tempReconnection.timerHander && clearTimeout(tempReconnection.timerHander); + // 延迟reconnect,但需立即触发appStateChange,以便客户显示loading。 + this.appState = this.socketHasOpenned ? APP_STATE_FROM_CLIENT.reconnecting : APP_STATE_FROM_CLIENT.connecting; + this.subscribe.trigger('appStateChange', {...this.appState}); + tempReconnection.timerHander = setTimeout(() => { + this.reconnect(); + }, tempReconnection.timerDelay); + } + + // 若重连,会在重连失败后更新appState;若不重连,则直接更新appState。websocket初始建连失败时会进入error和close回调,此时更新为exit状态并不合适。 + if (tempReconnection.maxTimes === 0 && this.appState.state === APP_STATE_FROM_CLIENT.connected.state) { + this.appState = APP_STATE_FROM_CLIENT.exit; + this.subscribe.trigger('appStateChange', {...this.appState}); + } } - } - onClose(state, trigger) { - this.wsState = state; - // 断连后清除心跳缓存,规避“断连前发送心跳,异常无法收到心跳响应,断连后重连,恢复心跳后心跳响应和发送错位导致时延计算错误”的问题 - this.networkInfo.heartBeatSendTimes = []; - logger.debug('Websocket close. Triggered by ' + trigger); - this.tryReconnect(trigger); - } + onClose(state, trigger) { + this.wsState = state; + // 断连后清除心跳缓存,规避“断连前发送心跳,异常无法收到心跳响应,断连后重连,恢复心跳后心跳响应和发送错位导致时延计算错误”的问题 + this.networkInfo.heartBeatSendTimes = []; + Logger.debug('Websocket close. Triggered by ' + trigger); + this.tryReconnect(trigger); - getCheckSum(msgType) { - return ( - (msgType + - ((CAE_STREAM_DELIMITER_MAGICWORD >> 8) & 0xff) + - (CAE_STREAM_DELIMITER_MAGICWORD & 0xff)) & - 0xff - ); - } + if (this.keyboardInput) { + this.keyboardInput.blurInput(); + } + } + + getCheckSum(msgType) { + return (msgType + ((CAE_STREAM_DELIMITER_MAGICWORD >> 8) & 0xFF) + (CAE_STREAM_DELIMITER_MAGICWORD & 0xFF)) & 0xFF; + } - paramsSerialize(params) { - if (params) { - let kvs = Object.keys(params).map(key => { - let value = params[key]; - if (typeof value === 'object') { - value = Object.keys(value) - .map(subKey => - [subKey, encodeURIComponent(value[subKey])].join('='), - ) - .join(':'); - return [key, value].join('='); + paramsSerialize(params) { + if (params) { + let kvs = Object.keys(params).map(key => { + let value = params[key]; + if (key === 'ticket') { + return [key, value].join('=') + } + if (typeof value === 'object') { + value = Object.keys(value).map(subKey => [subKey, encodeURIComponent(value[subKey])].join('=')).join(':'); + return [key, value].join('='); + } + + return [key, encodeURIComponent(value)].join('='); + }); + return kvs.join('&'); } - return [key, encodeURIComponent(value)].join('='); - }); - return kvs.join('&'); + return ''; } - return ''; - } + params2JSON(params = '') { + let json = {}; + params.split('&').forEach(kv => { + let [key, val] = kv.split('='); + json[key] = val; + }); + return json; + } - params2JSON(params = '') { - let json = {}; - params.split('&').forEach(kv => { - let [key, val] = kv.split('='); - json[key] = val; - }); - return json; - } + /** + * 根据协议构造发送给CAE的消息 + * @param {object} typedBuf 8位无符号整型数组Uint8Array + * @param {string} msgType 消息类型,值为protocalConfig配置的key + * @param {number} msgBodyLen 消息内容长度 + */ + setMsgHeader(typedBuf, msgType, msgBodyLen) { + typedBuf[0] = 90; + typedBuf[1] = 90; + typedBuf[2] = this.getCheckSum(PROTOCOL_CONFIG.MSG_TYPE[msgType]); + typedBuf[3] = PROTOCOL_CONFIG.MSG_TYPE[msgType]; + typedBuf[4] = msgBodyLen >> 24; + typedBuf[5] = msgBodyLen >> 16; + typedBuf[6] = msgBodyLen >> 8; + typedBuf[7] = msgBodyLen; + } - /** - * 根据协议构造发送给CAE的消息 - * @param {object} typedBuf 8位无符号整型数组Uint8Array - * @param {string} msgType 消息类型,值为protocalConfig配置的key - * @param {number} msgBodyLen 消息内容长度 - */ - setMsgHeader(typedBuf, msgType, msgBodyLen) { - typedBuf[0] = 90; - typedBuf[1] = 90; - typedBuf[2] = this.getCheckSum(PROTOCOL_CONFIG.MSG_TYPE[msgType]); - typedBuf[3] = PROTOCOL_CONFIG.MSG_TYPE[msgType]; - typedBuf[4] = msgBodyLen >> 24; - typedBuf[5] = msgBodyLen >> 16; - typedBuf[6] = msgBodyLen >> 8; - typedBuf[7] = msgBodyLen; - } + /** + * 根据协议构造发送给CAE的消息 + * @param {string} msgType 消息类型,值为protocalConfig配置的key + * @param {object} params 待转成消息体的控制参数 + * @return {object} 返回消息ArrayBuffer + */ + makeActionMsg(msgType, msgCmd, params = {}) { + const MSG_CMD_MAP = {...PROTOCOL_CONFIG.CMD_TYPE}; - /** - * 根据协议构造发送给CAE的消息 - * @param {string} msgType 消息类型,值为protocalConfig配置的key - * @param {object} params 待转成消息体的控制参数 - * @return {object} 返回消息ArrayBuffer - */ - makeActionMsg(msgType, msgCmd, params = {}) { - const MSG_CMD_MAP = { ...PROTOCOL_CONFIG.CMD_TYPE }; - - let msgBody = this.paramsSerialize({ - command: MSG_CMD_MAP[msgCmd], - ...params, - }); - let msgBodyLen = msgBody.length; - let typedBuf = new Uint8Array(PACKAGE_HEADER_LENGTH + msgBodyLen); - for (let i = 0; i < msgBodyLen; i++) { - typedBuf[PACKAGE_HEADER_LENGTH + i] = msgBody.charCodeAt(i); - } - - this.setMsgHeader(typedBuf, msgType, msgBodyLen); - return typedBuf.buffer; - } + let msgBody = this.paramsSerialize({ + command: MSG_CMD_MAP[msgCmd], + ...params + }); + let msgBodyLen = msgBody.length; + let typedBuf = new Uint8Array(PACKAGE_HEADER_LENGTH + msgBodyLen); + for (let i = 0; i < msgBodyLen; i++) { + typedBuf[PACKAGE_HEADER_LENGTH + i] = msgBody.charCodeAt(i); + } - /** - * 根据协议构造发送给CAE的消息 - * @param {string} msgType 消息类型,值为protocalConfig配置的key - * @param {object} data 待发送的消息数据,ArrayBuffer类型 - * @return {object} 返回消息ArrayBuffer - */ - makeDataMsg(msgType, data) { - let msgBodyLen = data.byteLength; - let typedBuf = new Uint8Array(PACKAGE_HEADER_LENGTH + msgBodyLen); - typedBuf.set(new Uint8Array(data), PACKAGE_HEADER_LENGTH); - this.setMsgHeader(typedBuf, msgType, msgBodyLen); - - return typedBuf.buffer; - } + this.setMsgHeader(typedBuf, msgType, msgBodyLen); + return typedBuf.buffer; + } - verifiedData() { - const userOptions = this.options; - return { - ip: userOptions.phoneIp, - port: userOptions.phonePort, - session_id: this.sessionId, - backgroundTimeout: userOptions.backgroundTimeout, - available_playtime: userOptions.availablePlayTime, - user_id: userOptions.userId, - }; - } + /** + * 根据协议构造发送给CAE的消息 + * @param {string} msgType 消息类型,值为protocalConfig配置的key + * @param {object} data 待发送的消息数据,ArrayBuffer类型 + * @return {object} 返回消息ArrayBuffer + */ + makeDataMsg(msgType, data) { + let msgBodyLen = data.byteLength; + let typedBuf = new Uint8Array(PACKAGE_HEADER_LENGTH + msgBodyLen); + typedBuf.set(new Uint8Array(data), PACKAGE_HEADER_LENGTH); + this.setMsgHeader(typedBuf, msgType, msgBodyLen); - initParams(cipherText, verify, iv) { - this.startParams = { - client_mode: "management", - ticket: this.options.ticket, - session_id: this.sessionId, - auth_ts: this.options.authTimeStamp, - verify_data: verify, - encrypted_data: cipherText, - aes_iv: iv, - sdk_version: this.options.sdkVersion, - protocol_version: 'v2', - client_type: this.options.isMobile ? '4' : '3', - operate_type: 'screenshot', - media_config: { - ...this.options.mediaConfig, - frame_type: this.options.decoderType - ? this.options.decoderType.toLowerCase() - : FRAME_TYPE_MAP.TYPE264, - quality: PROTOCOL_CONFIG[DEFAULT_DEFINITION].quality, - }, - }; - // ios/android接入,切到home后有可能会停止发送心跳,该场景下切home超时不生效,切home超时由断连超时决定。 - if (this.options.isMobile) { - this.startParams.max_disconnect_duration = this.options.backgroundTimeout; + return typedBuf.buffer; } - } - start() { - let crypt = new AESGCMCrypto(); - let iv = crypt.iv(); - let verifiedData = this.verifiedData(); - let encryptedData = { - ...verifiedData, - touch_timeout: this.options.touchTimeout, - }; - Promise.all([ - crypt.encrypt(JSON.stringify(encryptedData), this.options.aesKey, iv), - crypt.abstract(Object.values(verifiedData).join('')), - ]).then(([cipherText, verifyText]) => { - this.initParams(cipherText, verifyText, iv); - if (cipherText) { - this.appState = APP_STATE_FROM_CLIENT.connecting; - this.subscribe.trigger('appStateChange', { ...this.appState }); - this.connect(); - } - }); - } + decode(data) { + this.avc.decode(data); + } - connect() { - if (!this.options.connectURI) { - return; + verifiedData() { + const userOptions = this.options; + return { + ip: userOptions.phoneIp, + port: userOptions.phonePort, + session_id: this.sessionId, + backgroundTimeout: userOptions.backgroundTimeout, + available_playtime: userOptions.availablePlayTime, + user_id: userOptions.userId + }; } - this.initSocket(this.options.connectURI); - } + initParams(cipherText, verify, iv) { + this.startParams = { + client_mode: "management", + ticket: this.options.ticket, + session_id: this.sessionId, + auth_ts: this.options.authTimeStamp, + verify_data: verify, + encrypted_data: cipherText, + aes_iv: iv, + sdk_version: this.options.sdkVersion, + protocol_version: 'v2', + operate_type: 'screenshot', + client_type: this.options.isMobile ? '4' :'3', + media_config: { + ...this.options.mediaConfig, + frame_type: this.options.decoderType ? this.options.decoderType.toLowerCase() : FRAME_TYPE_MAP.TYPE264, + quality: PROTOCOL_CONFIG[DEFAULT_DEFINITION].quality + } + }; + // ios/android接入,切到home后有可能会停止发送心跳,该场景下切home超时不生效,切home超时由断连超时决定。 + if (this.options.isMobile) { + this.startParams.max_disconnect_duration = this.options.backgroundTimeout; + } - disconnect(callbackFn) { - // client自动断连场景不重连 - this.reconnection.can = false; - this.stopCloudPhone(); - this.stopHeartbeat(); - // 延迟关闭socket,避免CAE在关闭前接收不到stop cmd - setTimeout(() => { - this.closeSocket(); - if (callbackFn) { - callbackFn(); - } - }, 1000); - } + if (this.startParams.media_config.physical_width && this.startParams.media_config.physical_height) { + this.nextResolution = { + width: this.startParams.media_config.physical_width, + height: this.startParams.media_config.physical_height + }; + } + } - /* - * 尝试重连有两种场景:1.首次连接,连接失败;2、已有连接断开后重连,重连失败后再重连 - * 断线后重连,15s内重连,15s后CAE清理资源 - */ - reconnect() { - this._action = this.socketHasOpenned ? 'reconnect' : 'connect'; - this.connect(); - } + start() { + let crypt = new AESGCMCrypto(); + let iv = crypt.iv(); + let verifiedData = this.verifiedData(); + let encryptedData = {...verifiedData, touch_timeout: this.options.touchTimeout}; + Promise.all([ + crypt.encrypt(JSON.stringify(encryptedData), this.options.aesKey, iv), + crypt.abstract(Object.values(verifiedData).join('')) + ]).then(([cipherText, verifyText]) => { + this.initParams(cipherText, verifyText, iv); + if (cipherText) { + this.appState = APP_STATE_FROM_CLIENT.connecting; + this.subscribe.trigger('appStateChange', {...this.appState}); + this.connect(); + } + }); + } - _reconnect() { - let arrayBuf = this.makeActionMsg('CMD_CONTROL', 'RECONNECT', { - session_id: this.sessionId, - }); - arrayBuf && this.send(arrayBuf); - } + connect() { + if (!this.options.connectURI) { + return; + } - // 发送启动命令获取音视频数据,启动样例 - startCloudPhone() { - let arrayBuf = this.makeActionMsg('CMD_CONTROL', 'START', this.startParams); - arrayBuf && this.send(arrayBuf); - } + this.initSocket(this.options.connectURI); + } - // 停止样例 - stopCloudPhone() { - const arrayBuf = this.makeActionMsg('CMD_CONTROL', 'STOP'); - arrayBuf && this.send(arrayBuf); - } + startPlay() { + this.playing = true; + } - // 暂停样例 - // 用于home切换场景,暂停后,CAE停止发送数据 - pauseCloudPhone() { - const arrayBuf = this.makeActionMsg('CMD_CONTROL', 'PAUSE'); - arrayBuf && this.send(arrayBuf); - } + stopPlay() { + this.playing = false; + } - // 恢复样例 - // 切换至home,暂停;60s内切回则发送恢复指令恢复,60s后切回,CAE清理资源,需要重新申请云手机 - resumeCloudPhone() { - this._resumeCloudPhone(); - } + __canvasPlay(frame) { + this.decode(frame); + } - _resumeCloudPhone() { - let arrayBuf = this.makeActionMsg('CMD_CONTROL', 'RESUME', { - session_id: this.sessionId, - }); - arrayBuf && this.send(arrayBuf); - } + toLastest() { + let video = this.player; + let action = () => { + if (video.buffered && video.buffered.length && video.buffered.end(0)) { + video.currentTime = video.buffered.end(0); + } - recoverAfterWorkerDead(trigger) { - this.socketWorker && this.socketWorker.terminate(); - this.createSocket(); - this.onClose(WEBSOCKET_READY_STATE.CLOSED, trigger); - } + video.removeEventListener('canplaythrough', action); + }; + + video.addEventListener('canplaythrough', action); + } + + disconnect(callbackFn) { + // client自动断连场景不重连 + this.reconnection.can = false; + this.stopCloudPhone(); + this.stopHeartbeat(); + // 延迟关闭socket,避免CAE在关闭前接收不到stop cmd + setTimeout(() => { + this.closeSocket(); + if (callbackFn) { + callbackFn(); + } + }, 1000); + } - checkAndRecoverSocket(trigger) { /* - * iOS Safari切home后再回到手机界面,有可能出现socket worker无反应情况(socket已断开,却没有接收到close事件) - * 主动给socket worker发送信息,200ms内没有从socket worker接收到响应或socket已经close,且未触发close事件(重连机制在close事件处理中触发),主动触发重连 - * 认为200ms内足以触发close事件及接收到从socket worket的响应 - */ - this.checkSocketWorkerState(); - setTimeout(() => { - if (!this.reconnection.reconnecting && !this.isSocketAvailable()) { - this.recoverAfterWorkerDead(trigger); - } - }, 200); - } + * 尝试重连有两种场景:1.首次连接,连接失败;2、已有连接断开后重连,重连失败后再重连 + * 断线后重连,15s内重连,15s后CAE清理资源 + */ + reconnect() { + this._action = this.socketHasOpenned ? 'reconnect' : 'connect'; + this.connect(); + } - listenPageVisibility() { - let hidden; - if (typeof document.hidden !== 'undefined') { - hidden = 'hidden'; - this.visibilityChange = 'visibilitychange'; - } else if (typeof document.msHidden !== 'undefined') { - hidden = 'msHidden'; - this.visibilityChange = 'msvisibilitychange'; - } else if (typeof document.webkitHidden !== 'undefined') { - hidden = 'webkitHidden'; - this.visibilityChange = 'webkitvisibilitychange'; - } - - this.handleVisibilityChange = () => { - if (document[hidden] && this.currentVisible == 'visibility') { - // 页面隐藏后停止发送心跳 - logger.debug('Page hidden, pause'); - this.pauseCloudPhone(); - this.currentVisible = 'hidden'; - } else if ( - this.wsState === WEBSOCKET_READY_STATE.OPEN && - this.currentVisible == 'hidden' - ) { - logger.debug('Page visibility, resume'); - // 恢复虚拟设备发送数据 - this.resumeCloudPhone(); - this.currentVisible = 'visibility'; - } - }; + _reconnect() { + let arrayBuf = this.makeActionMsg('CMD_CONTROL', 'RECONNECT', { + session_id: this.sessionId + }); + arrayBuf && this.send(arrayBuf); + } - // 判断浏览器的支持情况 - if (typeof document[hidden] !== 'undefined') { - this.util.bind( - document, - this.visibilityChange, - this.handleVisibilityChange, - ); + // 发送启动命令获取音视频数据,启动样例 + startCloudPhone() { + let arrayBuf = this.makeActionMsg('CMD_CONTROL', 'START', this.startParams); + arrayBuf && this.send(arrayBuf); } - } - // 主要处理当前页打开其他页面后再次返回手机页面,从缓存加载,需重连的场景 - listenPageShow() { - let isPageHide = false; - window.addEventListener('pageshow', () => { - if (isPageHide) { - isPageHide = false; - this.checkAndRecoverSocket('pageshow'); - } - }); - window.addEventListener('pagehide', () => { - isPageHide = true; - }); - } + // 停止样例 + stopCloudPhone() { + const arrayBuf = this.makeActionMsg('CMD_CONTROL', 'STOP'); + arrayBuf && this.send(arrayBuf); + } - static isSupport() { - let isSptSocket = window.WebSocket; - return Boolean(isSptSocket); - } + // 暂停样例 + // 用于home切换场景,暂停后,CAE停止发送数据 + pauseCloudPhone() { + const arrayBuf = this.makeActionMsg('CMD_CONTROL', 'PAUSE'); + arrayBuf && this.send(arrayBuf); + } - static isSupportURL() { - let url = window.URL || window.webkitURL; - return Boolean(url.createObjectURL); - } + // 恢复样例 + // 切换至home,暂停;60s内切回则发送恢复指令恢复,60s后切回,CAE清理资源,需要重新申请云手机 + resumeCloudPhone() { + this._resumeCloudPhone(); + } - on(eventName, callback) { - this.subscribe.on(eventName, callback); - } + _resumeCloudPhone() { + let arrayBuf = this.makeActionMsg('CMD_CONTROL', 'RESUME', { + session_id: this.sessionId + }); + arrayBuf && this.send(arrayBuf); + } - off(eventName, callback) { - this.subscribe.off(eventName, callback); - } + // 设置画质 + setResolution(clarityVal) { + const config = PROTOCOL_CONFIG[clarityVal]; + if (this.startParams.media_config && this.startParams.media_config.bitrate) { + config.bitrate = this.startParams.media_config.bitrate; + } - generateGUID() { - return 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, c => { - const r = (AESGCMCrypto.getRandomValue() * 16) | 0; - const v = c === 'x' ? r : (r & 0x3) | 0x8; - return v.toString(16); - }); - } + this.setMediaConfig(config); + } - exit() { - this.disconnect(this.terminateSocketWorker.bind(this)); - this.destroy(true); - } + // 设置音视频参数 + setMediaConfig(config = {}) { + let arrayBuf = this.makeActionMsg('CMD_CONTROL', 'SET_MEDIA_CONFIG', { + media_config: config + }); + arrayBuf && this.send(arrayBuf); + if (config.stream_width && config.stream_height) { + this.nextResolution = { + width: config.stream_width, + height: config.stream_height + }; + } + } - terminateSocketWorker() { - this.socketWorker && this.socketWorker.terminate(); - this.socketWorker = null; - this.socket = null; - } + recoverAfterWorkerDead(trigger) { + this.socketWorker && this.socketWorker.terminate(); + this.createSocket(); + this.onClose(WEBSOCKET_READY_STATE.CLOSED, trigger); + } - updateSocketWorkerState(workerState, socketState) { - this.socketWorkerState.worker = workerState; - this.socketWorkerState.socket = socketState; - } + checkAndRecoverSocket(trigger) { + + /* + * iOS Safari切home后再回到手机界面,有可能出现socket worker无反应情况(socket已断开,却没有接收到close事件) + * 主动给socket worker发送信息,200ms内没有从socket worker接收到响应或socket已经close,且未触发close事件(重连机制在close事件处理中触发),主动触发重连 + * 认为200ms内足以触发close事件及接收到从socket worket的响应 + */ + this.checkSocketWorkerState(); + setTimeout(() => { + if (!this.reconnection.reconnecting && !this.isSocketAvailable()) { + this.recoverAfterWorkerDead(trigger); + } + }, 200); + } - isSocketAvailable() { - return ( - this.socketWorkerState.worker === WORKER_STATE.LIVE && - this.socketWorkerState.socket !== WEBSOCKET_READY_STATE.CLOSING && - this.socketWorkerState.socket !== WEBSOCKET_READY_STATE.CLOSED - ); - } + listenPageVisibility() { + let hidden; + if (typeof document.hidden !== 'undefined') { + hidden = 'hidden'; + this.visibilityChange = 'visibilitychange'; + } else if (typeof document.msHidden !== 'undefined') { + hidden = 'msHidden'; + this.visibilityChange = 'msvisibilitychange'; + } else if (typeof document.webkitHidden !== 'undefined') { + hidden = 'webkitHidden'; + this.visibilityChange = 'webkitvisibilitychange'; + } - setDefaultCamera(devId) { - this.deviceHardwareHandler.setDefaultCamera(devId); - } + this.handleVisibilityChange = () => { + if (document[hidden] && this.currentVisible == 'visibility') { + // 页面隐藏后停止发送心跳 + Logger.debug('Page hidden, pause'); + // 页面隐藏后虚拟设备停止发送数据 + this.pauseCloudPhone(); + this.currentVisible = 'hidden' + } else if (this.wsState === WEBSOCKET_READY_STATE.OPEN && this.currentVisible == 'hidden') { + Logger.debug('Page visibility, resume'); + // 恢复虚拟设备发送数据 + this.resumeCloudPhone(); + this.currentVisible = 'visibility' + } + }; + + // 判断浏览器的支持情况 + if (typeof document[hidden] !== 'undefined') { + this.util.bind(document, this.visibilityChange, this.handleVisibilityChange); + } + } - getCameras() { - let videoDevices = []; - navigator.mediaDevices.enumerateDevices() - .then(devices => { - devices.forEach(device => { - if (device.kind === "videoinput") { - videoDevices.push(device); - } + // 主要处理当前页打开其他页面后再次返回手机页面,从缓存加载,需重连的场景 + listenPageShow() { + let isPageHide = false; + window.addEventListener('pageshow', () => { + if (isPageHide) { + isPageHide = false; + this.checkAndRecoverSocket('pageshow'); + } }); - console.log(videoDevices) - // 输出视频摄像头列表 - return videoDevices; - }) - .catch(error => { - console.log("获取设备列表失败:", error); - }); - } + window.addEventListener('pagehide', () => { + isPageHide = true; + }); + } - resetDefaultCamera() { - this.deviceHardwareHandler.defaultCameraId = ''; - } + static isSupport() { + let isSptAudioCxt = window.AudioContext || window.webkitAudioContext; + let isSptSocket = window.WebSocket; + return Boolean(AESGCMCrypto.isSupport() && isSptAudioCxt && isSptSocket); + } - /** - * 销毁 - * @param {boolean}} reserveSocketWorker 是否需要销毁socket,exit场景,延迟close socket,close前需保留socket - * @return {void}} - */ - destroy(reserveSocketWorker) { - if (!reserveSocketWorker) { - this.terminateSocketWorker(); + static isSupportURL() { + let url = window.URL || window.webkitURL; + return Boolean(url.createObjectURL); + } + + on(eventName, callback) { + this.subscribe.on(eventName, callback); + } + + off(eventName, callback) { + this.subscribe.off(eventName, callback); + } + + generateGUID() { + return 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, c => { + const r = AESGCMCrypto.getRandomValue() * 16 | 0; + const v = c === 'x' ? r : (r & 0x3 | 0x8); + return v.toString(16); + }); + } + + isCanvasPriority() { + // UA 判断 + const userAgent = navigator && navigator.userAgent || ''; + const isMatchUA = Object.values(CANVAS_WHITE_LIST).some(condition => userAgent.includes(condition)); + + // oppo 浏览器 UA 特征不明显,通过 window 对象属性进行判断 + const isOppoBrowser = Boolean(window.OppoWebPage || window.OppoFlow || window.oppoErrorPage || window.oppoUrlQuery); + return isMatchUA || isOppoBrowser; + } + + isMSEMode(frameType = FRAME_TYPE_MAP.TYPE265) { + // 使用 MSE 前提: + // (1) 支持 MediaSource + // (2) 支持 avc1.42c020 编码 + // (3) 不在 canvas 白名单 + // 前两条判断包含在 JMuxer.isSupported 方法中 + let isMSE = true; + if (frameType === FRAME_TYPE_MAP.TYPE264) { + isMSE = Boolean(JMuxer.isSupported('video/mp4; codecs="avc1.42c020"')) && !this.isCanvasPriority(); + } else { + isMSE = Boolean(JMuxer.isSupported('video/mp4; codecs="hev1"')) && !this.isCanvasPriority(); + } + + /*global __IS_DEBUG__*/ + if (__IS_DEBUG__) { + const framework = this.util.getUrlSearchVal('framework'); + // framework 无值时不进行处理,避免默认值影响 canvas 白名单效果 + if (framework) { + isMSE = framework.toLowerCase() !== 'canvas'; + } + } + + return isMSE; + } + + sendDataToCloudApp(data) { + if (!this.playing) { + return; + } + + let arrayBuf = this.makeDataMsg('CHANNEL', data); + this.send(arrayBuf) + } + + sendClipboardData(data) { + if (this.keyboardListener) { + this.keyboardListener.sendClipboardData(data); + } + if (this.keyboardInput) { + this.keyboardInput.sendClipboardData(data); + } + } + + exit() { + this.disconnect(this.terminateSocketWorker.bind(this)); + this.destroy(true); + } + + terminateSocketWorker() { + this.socketWorker && this.socketWorker.terminate(); + this.socketWorker = null; + this.socket = null; + } + + updateSocketWorkerState(workerState, socketState) { + this.socketWorkerState.worker = workerState; + this.socketWorkerState.socket = socketState; + } + + isSocketAvailable() { + return this.socketWorkerState.worker === WORKER_STATE.LIVE + && this.socketWorkerState.socket !== WEBSOCKET_READY_STATE.CLOSING + && this.socketWorkerState.socket !== WEBSOCKET_READY_STATE.CLOSED; + } + + /** + * 销毁 + * @param {boolean}} reserveSocketWorker 是否需要销毁socket,exit场景,延迟close socket,close前需保留socket + * @return {void}} + */ + destroy(reserveSocketWorker) { + this.stopPlay(); + this.jmuxer && this.jmuxer.destroy(); + this.avc && this.avc.destroy(); + this.touchHandler && this.touchHandler.destroy(); + this.autoRotation && this.autoRotation.destroy(); + this.fullscreen && this.fullscreen.destroy(); + // 停止传感器 + this.jmuxer = null; + this.avc = null; + this.touchHandler = null; + this.autoRotation = null; + this.keyboardInput = null; + this.fullscreen = null; + + if (!reserveSocketWorker) { + this.terminateSocketWorker(); + } + + this.util.unbind(null, this.visibilityChange); } - this.util.unbind(null, this.visibilityChange); - } } export default AppController; diff --git a/sdk/src/CameraPlayer.js b/sdk/src/CameraPlayer.js index 30fff7c5e6107b657f46908e22cab9c43179e4da..fe79911d00079f5431a1422842b16a254eb7c40e 100644 --- a/sdk/src/CameraPlayer.js +++ b/sdk/src/CameraPlayer.js @@ -15,6 +15,7 @@ import Util from "./Util"; import work from 'webworkify-webpack'; import PROTOCOL_CONFIG from './config/protocolConfig'; +import {initEncode,encode,rotateTexture} from './worker/VideoEncoder' import {CAMERA_COMMON_MODE_MAP} from './config/commonConfig'; const OPT_CAMERA_FRAME = PROTOCOL_CONFIG.CAMERA_MESSAGE_TYPE.OPT_CAMERA_FRAME; @@ -31,8 +32,15 @@ export default class CameraPlayer { this.videoStream = null; this.animationId = null; this.stopVideo = false; - this.videoEncoderWorker = work(require.resolve('./worker/VideoEncoder.js')); - this.videoEncoderWorker.addEventListener('message', this.videoMessageHandler.bind(this)); + this.video.setAttribute('playsinline', true); + this.video.setAttribute('webkit-playsinline', true); + this.video.setAttribute('autoplay', true); + this.video.setAttribute('muted', true); + window.addEventListener( + 'message', (evt) => this.videoMessageHandler(evt) + ) + // this.videoEncoderWorker = work(require.resolve('./worker/VideoEncoder.js')); + // this.videoEncoderWorker.addEventListener('message', this.videoMessageHandler.bind(this)); this.initMediaDevices(this.options.videoOptions); } } @@ -60,11 +68,11 @@ export default class CameraPlayer { if (this.videoStream) { this.videoStream.stop(); } - navigator.mediaDevices.getUserMedia({ video: videoOptions }) + navigator.mediaDevices.getUserMedia({ video: videoOptions, audio: false }) .then((stream) => { stream.getVideoTracks().forEach(track => track.stop()); }) - navigator.mediaDevices.getUserMedia({ video: videoOptions }) + navigator.mediaDevices.getUserMedia({ video: videoOptions, audio: false }) .then((stream) => { // 视频轨道 this.videoStream = stream.getVideoTracks()[0]; @@ -86,10 +94,11 @@ export default class CameraPlayer { this.gl.readPixels(0, 0, this.canvas.width, this.canvas.height, this.gl.RGBA, this.gl.UNSIGNED_BYTE, pixels); const imageData = this.getImageData(pixels, this.canvas.width, this.canvas.height); - this.videoEncoderWorker.postMessage({ - type: 'encode', - data: imageData - }); + // this.videoEncoderWorker.postMessage({ + // type: 'encode', + // data: imageData + // }); + encode(imageData) } getImageData(data, width, height) { @@ -104,16 +113,17 @@ export default class CameraPlayer { const newVideoStream = new MediaStream(); newVideoStream.addTrack(this.videoStream); this.video.srcObject = newVideoStream; + try { this.video.addEventListener('loadedmetadata', () => { this.canvas.width = this.options.encodeWidth; this.canvas.height = this.options.encodeHeight; - this.videoEncoderWorker.postMessage({ - type: 'initEncode', - width: this.canvas.width, - height: this.canvas.height, - x264WasmPath: this.options.x264WasmPath - }); - + // this.videoEncoderWorker.postMessage({ + // type: 'initEncode', + // width: this.canvas.width, + // height: this.canvas.height, + // x264WasmPath: this.options.x264WasmPath + // }); + initEncode(this.canvas.width,this.canvas.height,this.options.x264WasmPath) // 指定宽高 this.gl.viewport(0, 0, this.canvas.width, this.canvas.height); // 绑定纹理对象 @@ -122,45 +132,75 @@ export default class CameraPlayer { this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, this.gl.RGBA, this.gl.UNSIGNED_BYTE, this.video); // 绘制纹理 this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4); - + this.video.play(); }); - - this.video.play(); + } catch (error) { + console.log(error) + } } videoMessageHandler(evt) { - const message = evt.data; + // const message = evt.data; + // if (!Object.prototype.hasOwnProperty.call(message, 'type')) { + // return; + // } + + // switch (message.type) { + // case 'startEncode': { + // this.animationId = requestAnimationFrame(this.render.bind(this)); + // break; + // } + // case 'encodeResult': { + // this.sendOutBufHandler('CAMERA', OPT_CAMERA_FRAME, message.data); + // this.animationId = requestAnimationFrame(this.render.bind(this)); + // if (this.stopVideo) { + // cancelAnimationFrame(this.animationId); + // } + // break; + // } + // case 'setRotateData': { + // const rotateData = message.data; + // this.gl.uniformMatrix4fv(this.rotationMatrixLocation, false, rotateData); + // this.gl.uniform1i(this.textureLocation, 0); + // // 绘制纹理 + // this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4); + // break; + // } + // default: + // break; + // } + const message = evt.data if (!Object.prototype.hasOwnProperty.call(message, 'type')) { - return; + return } - switch (message.type) { - case 'startEncode': { - this.animationId = requestAnimationFrame(this.render.bind(this)); - break; + case 'startEncode': { + this.animationId = requestAnimationFrame(this.render.bind(this)) + break + } + case 'encodeResult': { + this.sendOutBufHandler('CAMERA', OPT_CAMERA_FRAME, message.data) + this.animationId = requestAnimationFrame(this.render.bind(this)) + if (this.stopVideo) { + cancelAnimationFrame(this.animationId) } - case 'encodeResult': { - this.sendOutBufHandler('CAMERA', OPT_CAMERA_FRAME, message.data); - this.animationId = requestAnimationFrame(this.render.bind(this)); - if (this.stopVideo) { - cancelAnimationFrame(this.animationId); - } - break; - } - case 'setRotateData': { - const rotateData = message.data; - this.gl.uniformMatrix4fv(this.rotationMatrixLocation, false, rotateData); - this.gl.uniform1i(this.textureLocation, 0); - // 绘制纹理 - this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4); - break; - } - default: - break; + break + } + case 'setRotateData': { + const rotateData = message.data + this.gl.uniformMatrix4fv(this.rotationMatrixLocation, false, rotateData) + this.gl.uniform1i(this.textureLocation, 0) + // 绘制纹理 + this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4) + break + } + default: + break } } stopCameraVideo() { + this.videoMessageHandler = () => {}; this.stopVideo = true; if (this.video.srcObject) { this.video.srcObject.getTracks().forEach(track => track.stop()); @@ -168,6 +208,7 @@ export default class CameraPlayer { this.video.srcObject = null; if (this.videoStream) { this.videoStream.stop(); + this.videoStream = null; } } @@ -266,9 +307,11 @@ export default class CameraPlayer { // 将视频帧绘制到纹理对象 this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, this.gl.RGBA, this.gl.UNSIGNED_BYTE, this.video); - this.videoEncoderWorker.postMessage({ - type: 'rotateTexture', - rotateAngles - }); + // this.videoEncoderWorker.postMessage({ + // type: 'rotateTexture', + // rotateAngles + // }); + + rotateTexture(rotateAngles) } } \ No newline at end of file diff --git a/sdk/src/DirectionHandler.js b/sdk/src/DirectionHandler.js index 25fd1d15eef8a6538c723a4370c192da7af323f9..c74c3b323ae0d61609d1fd50288dc03c01c5dc17 100644 --- a/sdk/src/DirectionHandler.js +++ b/sdk/src/DirectionHandler.js @@ -801,7 +801,6 @@ class DirectionHandler { playerHeight = height; playerWidth = height * CLOUD_PHONE_RATIO; } else if ([PROTOCOL_CONFIG.ORIENTATION[8], PROTOCOL_CONFIG.ORIENTATION[24]].includes(this.orientation)) { - console.log(4) if (this.options.keepRatio) { playerHeight = width; playerWidth = width * CLOUD_PHONE_RATIO; diff --git a/sdk/src/worker/VideoEncoder.js b/sdk/src/worker/VideoEncoder.js index f5417ae75a0186142ca2a63cec441d2e00ac091d..d7399ec73811870a595a0b837e1a1fb9a8787f6f 100644 --- a/sdk/src/worker/VideoEncoder.js +++ b/sdk/src/worker/VideoEncoder.js @@ -12,38 +12,75 @@ // See the License for the specific language governing permissions and // limitations under the License. -import VideoEncode from '../codec/Encode'; -import { mat4 } from 'gl-matrix'; +import VideoEncode from '../codec/Encode' +import { mat4 } from 'gl-matrix' -const videoEncoder = new VideoEncode(); +const videoEncoder = new VideoEncode() -self.addEventListener('message', evt => { - const message = evt.data; - switch (message.type) { - case 'initEncode': { - videoEncoder.getWasm({ - width: message.width, - height: message.height, - x264WasmPath: message.x264WasmPath - }); - break; +function isWebAssemblySupported() { + try { + if (typeof WebAssembly === 'object' && typeof WebAssembly.instantiate === 'function') { + const module = new WebAssembly.Module(Uint8Array.of(0x0, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00)); + if (module instanceof WebAssembly.Module) { + return true; + } } - case 'encode': { - videoEncoder.encode(message.data); - break; - } - case 'rotateTexture': { - let rotationMatrix = mat4.create(); - mat4.rotateZ(rotationMatrix, rotationMatrix, message.rotateAngles); - self.postMessage({ - type: 'setRotateData', - data: rotationMatrix - }); - break; - } - default: - // do nothing + } catch (e) { + // Ignore any errors and assume WebAssembly is not supported } -}); + return false; +} + +function initEncode(width,height,x264WasmPath){ + console.log("isWebAssemblySupported",isWebAssemblySupported()) + videoEncoder.getWasm({ + width: width, + height: height, + x264WasmPath: x264WasmPath + }) +} +function encode(data){ + videoEncoder.encode(data) +} + +function rotateTexture(rotateAngles){ + let rotationMatrix = mat4.create() + mat4.rotateZ(rotationMatrix, rotationMatrix, rotateAngles) + self.postMessage({ + type: 'setRotateData', + data: rotationMatrix + }) +} +// self.addEventListener('message', evt => { +// const message = evt.data +// console.log("VideoEncode",WebAssembly) +// console.log("VideoEncode",message.type) +// switch (message.type) { +// case 'initEncode': { +// videoEncoder.getWasm({ +// width: message.width, +// height: message.height, +// x264WasmPath: message.x264WasmPath +// }) +// break +// } +// case 'encode': { +// videoEncoder.encode(message.data) +// break +// } +// case 'rotateTexture': { +// let rotationMatrix = mat4.create() +// mat4.rotateZ(rotationMatrix, rotationMatrix, message.rotateAngles) +// self.postMessage({ +// type: 'setRotateData', +// data: rotationMatrix +// }) +// break +// } +// default: +// // do nothing +// } +// }) -export default function() {} \ No newline at end of file +// export default function () {} +export {initEncode,encode,rotateTexture} \ No newline at end of file