multiple-police-situations/public/cw/player/recorder-core.js

6 lines
16 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
录音
https://github.com/xiangyuecn/Recorder
src: recorder-core.js
*/
!function(x){"use strict";var d=function(){},U=function(e){return new t(e)};U.LM="2022-08-06 20:51";var A="Recorder",S="getUserMedia",P="srcSampleRate",E="sampleRate";U.IsOpen=function(){var e=U.Stream;if(e){var t=e.getTracks&&e.getTracks()||e.audioTracks||[],r=t[0];if(r){var n=r.readyState;return"live"==n||n==r.LIVE}}return!1},U.BufferSize=4096,U.Destroy=function(){for(var e in z(A+" Destroy"),y(),r)r[e]()};var r={};U.BindDestroy=function(e,t){r[e]=t},U.Support=function(){var e=x.AudioContext;if(e||(e=x.webkitAudioContext),!e)return!1;var t=navigator.mediaDevices||{};return t[S]||(t=navigator)[S]||(t[S]=t.webkitGetUserMedia||t.mozGetUserMedia||t.msGetUserMedia),!!t[S]&&(U.Scope=t,U.Ctx&&"closed"!=U.Ctx.state||(U.Ctx=new e,U.BindDestroy("Ctx",function(){var e=U.Ctx;e&&e.close&&(e.close(),U.Ctx=0)})),!0)};var L="ConnectEnableWebM";U[L]=!0;var T="ConnectEnableWorklet";U[T]=!1;var _=function(e,c){var f,i,u,l=e.BufferSize||U.BufferSize,v=U.Ctx,p=e.Stream,s=function(e){var t=p._m=v.createMediaStreamSource(p),r=v.destination,n="createMediaStreamDestination";v[n]&&(r=v[n]()),t.connect(e),e.connect(r)},h="",g=p._call,m=function(e){for(var t in g){for(var r=e.length,n=new Int16Array(r),a=0,o=0;o<r;o++){var i=Math.max(-1,Math.min(1,e[o]));i=i<0?32768*i:32767*i,n[o]=i,a+=Math.abs(i)}for(var s in g)g[s](n,a);return}},d="ScriptProcessor",S="audioWorklet",_=A+" "+S,y="RecProc",C="MediaRecorder",b=C+".WebM.PCM",k=v.createScriptProcessor||v.createJavaScriptNode,M="。由于"+S+"内部1秒375次回调在移动端可能会有性能问题导致回调丢失录音变短PC端无影响暂不建议开启"+S+"。",I=function(){i=p.isWorklet=!1,D(p),z("Connect采用老的"+d+""+(U[T]?"但已":"可")+"设置"+A+"."+T+"=true尝试启用"+S+h+M,3);var e=p._p=k.call(v,l,1,1);s(e);var t="_D220626",r=U[t];r&&z("Use "+A+"."+t,3),e.onaudioprocess=function(e){var t=e.inputBuffer.getChannelData(0);r?(t=new Float32Array(t),setTimeout(function(){m(t)})):m(t)}},w=function(){f=p.isWebM=!1,O(p),i=p.isWorklet=!k||U[T];var t=x.AudioWorkletNode;if(i&&v[S]&&t){var n=function(){return i&&p._na},a=p._na=function(){""!==u&&(clearTimeout(u),u=setTimeout(function(){u=0,n()&&(z(S+"未返回任何音频,恢复使用"+d,3),k&&I())},500))},o=function(){if(n()){var e=p._n=new t(v,y,{processorOptions:{bufferSize:l}});s(e),e.port.onmessage=function(e){u&&(clearTimeout(u),u=""),n()?m(e.data.val):i||z(S+"多余回调",3)},z("Connect采用"+S+",设置"+A+"."+T+"=false可恢复老式"+d+h+M,3)}};v.resume()[g&&"finally"](function(){if(n())if(v[y])o();else{var e,t,r=(t="class "+y+" extends AudioWorkletProcessor{",t+="constructor "+(e=function(e){return e.toString().replace(/^function|DEL_/g,"").replace(/\$RA/g,_)})(function(e){DEL_super(e);var t=this,r=e.processorOptions.bufferSize;t.bufferSize=r,t.buffer=new Float32Array(2*r),t.pos=0,t.port.onmessage=function(e){e.data.kill&&(t.kill=!0,console.log("$RA kill call"))},console.log("$RA .ctor call",e)}),t+="process "+e(function(e,t,r){var n=this,a=n.bufferSize,o=n.buffer,i=n.pos;if((e=(e[0]||[])[0]||[]).length){o.set(e,i);var s=~~((i+=e.length)/a)*a;if(s){this.port.postMessage({val:o.slice(0,s)});var c=o.subarray(s,i);(o=new Float32Array(2*a)).set(c),i=c.length,n.buffer=o}n.pos=i}return!n.kill}),t+='}try{registerProcessor("'+y+'", '+y+')}catch(e){console.error("'+_+'注册失败",e)}',"data:text/javascript;base64,"+btoa(unescape(encodeURIComponent(t))));v[S].addModule(r).then(function(e){n()&&(v[y]=1,o(),u&&a())})[g&&"catch"](function(e){z(S+".addModule失败",1,e),n()&&I()})}})}else I()};!function(){var e=x[C],t="ondataavailable",r="audio/webm; codecs=pcm";f=p.isWebM=U[L];var n=e&&t in e.prototype&&e.isTypeSupported(r);if(h=n?"":"(此浏览器不支持"+b+"",!c||!f||!n)return w();var a=function(){return f&&p._ra},o=(p._ra=function(){""!==u&&(clearTimeout(u),u=setTimeout(function(){a()&&(z(C+"未返回任何音频,降级使用"+S,3),w())},500))},Object.assign({mimeType:r},U.ConnectWebMOptions)),i=p._r=new e(p,o),s=p._rd={sampleRate:v[E]};i[t]=function(e){var t=new FileReader;t.onloadend=function(){if(a()){var e=F(new Uint8Array(t.result),s);if(!e)return;if(-1==e)return void w();u&&(clearTimeout(u),u=""),m(e)}else f||z(C+"多余回调",3)},t.readAsArrayBuffer(e.data)},i.start(~~(l/48)),z("Connect采用"+b+",设置"+A+"."+L+"=false可恢复使用"+S+"或老式"+d)}()},D=function(e){e._na=null,e._n&&(e._n.port.postMessage({kill:!0}),e._n.disconnect(),e._n=null)},O=function(e){e._ra=null,e._r&&(e._r.stop(),e._r=null)},y=function(e){var t=(e=e||U)==U,r=e.Stream;if(r&&(r._m&&(r._m.disconnect(),r._m=null),r._p&&(r._p.disconnect(),r._p.onaudioprocess=r._p=null),D(r),O(r),t)){for(var n=r.getTracks&&r.getTracks()||r.audioTracks||[],a=0;a<n.length;a++){var o=n[a];o.stop&&o.stop()}r.stop&&r.stop()}e.Stream=0};U.SampleData=function(e,t,r,n,a){n||(n={});var o=n.index||0,i=n.offset||0,s=n.frameNext||[];a||(a={});var c=a.frameSize||1;a.frameType&&(c="mp3"==a.frameType?1152:1);var f=e.length;f+1<o&&z("SampleData似乎传入了未重置chunk "+o+">"+f,3);for(var u=0,l=o;l<f;l++)u+=e[l].length;u=Math.max(0,u-Math.floor(i));var v=t/r;1<v?u=Math.floor(u/v):(v=1,r=t),u+=s.length;for(var p=new Int16Array(u),h=0,l=0;l<s.length;l++)p[h]=s[l],h++;for(;o<f;o++){for(var g=e[o],l=i,m=g.length;l<m;){var d=Math.floor(l),S=Math.ceil(l),_=l-d,y=g[d],C=S<m?g[S]:(e[o+1]||[y])[0]||0;p[h]=y+(C-y)*_,h++,l+=v}i=l-m}s=null;var b=p.length%c;if(0<b){var k=2*(p.length-b);s=new Int16Array(p.buffer.slice(k)),p=new Int16Array(p.buffer.slice(0,k))}return{index:o,offset:i,frameNext:s,sampleRate:r,data:p}},U.PowerLevel=function(e,t){var r=e/t||0;return r<1251?Math.round(r/1250*10):Math.round(Math.min(100,Math.max(0,100*(1+Math.log(r/1e4)/Math.log(10)))))};var z=function(e,t){var r=new Date,n=("0"+r.getMinutes()).substr(-2)+":"+("0"+r.getSeconds()).substr(-2)+"."+("00"+r.getMilliseconds()).substr(-3),a=this&&this.envIn&&this.envCheck&&this.id,o=["["+n+" "+A+(a?":"+a:"")+"]"+e],i=arguments,s=x.console||{},c=2,f=s.log;for("number"==typeof t?f=1==t?s.error:3==t?s.warn:f:c=1;c<i.length;c++)o.push(i[c]);u?f&&f("[IsLoser]"+o[0],1<o.length?o:""):f.apply(s,o)},u=!0;try{u=!console.log.apply}catch(e){}U.CLog=z;var n=0;function t(e){this.id=++n,o();var t={type:"mp3",bitRate:16,sampleRate:16e3,onProcess:d};for(var r in e)t[r]=e[r];this.set=t,this._S=9,this.Sync={O:9,C:9}}U.Sync={O:9,C:9},U.prototype=t.prototype={CLog:z,_streamStore:function(){return this.set.sourceStream?this:U},open:function(e,r){var n=this,a=n._streamStore();e=e||d;var o=function(e,t){t=!!t,n.CLog("录音open失败"+e+",isUserNotAllow:"+t,1),r&&r(e,t)},i=function(){n.CLog("open ok id:"+n.id),e(),n._SO=0},s=a.Sync,c=++s.O,f=s.C;n._O=n._O_=c,n._SO=n._S;var t=n.envCheck({envName:"H5",canProcess:!0});if(t)o("不能录音:"+t);else if(n.set.sourceStream){if(!U.Support())return void o("不支持此浏览器从流中获取录音");y(a),n.Stream=n.set.sourceStream,n.Stream._call={};try{_(a)}catch(e){return void o("从流中打开录音失败:"+e.message)}i()}else{var u=function(e,t){try{x.top.a}catch(e){return void o('无权录音(跨域请尝试给iframe添加麦克风访问策略如allow="camera;microphone")')}/Permission|Allow/i.test(e)?o("用户拒绝了录音权限",!0):!1===x.isSecureContext?o("浏览器禁止不安全页面录音可开启https解决"):/Found/i.test(e)?o(t+",无可用麦克风"):o(t)};if(U.IsOpen())i();else if(U.Support()){var l=function(t){setTimeout(function(){t._call={};var e=U.Stream;e&&(y(),t._call=e._call),U.Stream=t,function(){if(f!=s.C||!n._O){var e="open被取消";return c==s.O?n.close():e="open被中断",o(e),!0}}()||(U.IsOpen()?(e&&n.CLog("发现同时多次调用open",1),_(a,1),i()):o("录音功能无效:无音频流"))},100)},v=function(e){var t=e.name||e.message||e.code+":"+e;n.CLog("请求录音权限错误",1,e),u(t,"无法录音:"+t)},p={noiseSuppression:!1,echoCancellation:!1},h=n.set.audioTrackSet;for(var g in h)p[g]=h[g];p.sampleRate=U.Ctx.sampleRate;try{var m=U.Scope[S]({audio:p},l,v)}catch(e){n.CLog(S,3,e),m=U.Scope[S]({audio:!0},l,v)}m&&m.then&&m.then(l)[e&&"catch"](v)}else u("","此浏览器不支持录音")}},close:function(e){e=e||d;var t=this,r=t._streamStore();t._stop();var n=r.Sync;if(t._O=0,t._O_!=n.O)return t.CLog("close被忽略因为同时open了多个rec只有最后一个会真正close",3),void e();n.C++,y(r),t.CLog("close"),e()},mock:function(e,t){var r=this;return r._stop(),r.isMock=1,r.mockEnvInfo=null,r.buffers=[e],r.recSize=e.length,r[P]=t,r},envCheck:function(e){var t,r=this.set,n="CPU_BE";if(t||U[n]||!x.Int8Array||new Int8Array(new Int32Array([1]).buffer)[0]||(o(n),t="不支持CPU_BE架构"),!t){var a=r.type;this[a+"_envCheck"]?t=this[a+"_envCheck"](e,r):r.takeoffEncodeChunk&&(t=a+"类型"+(this[a]?"":"(未加载编码器)")+"不支持设置takeoffEncodeChunk")}return t||""},envStart:function(e,t){var r=this,n=r.set;r.isMock=e?1:0,r.mockEnvInfo=e,r.buffers=[],r.recSize=0,r.envInLast=0,r.envInFirst=0,r.envInFix=0,r.envInFixTs=[];var a=n[E];if(t<a?n[E]=t:a=0,r[P]=t,r.CLog(P+": "+t+" set."+E+": "+n[E]+(a?" 忽略"+a:""),a?3:0),r.engineCtx=0,r[n.type+"_start"]){var o=r.engineCtx=r[n.type+"_start"](n);o&&(o.pcmDatas=[],o.pcmSize=0)}},envResume:function(){this.envInFixTs=[]},envIn:function(e,t){var a=this,o=a.set,i=a.engineCtx,r=a[P],n=e.length,s=U.PowerLevel(t,n),c=a.buffers,f=c.length;c.push(e);var u=c,l=f,v=Date.now(),p=Math.round(n/r*1e3);a.envInLast=v,1==a.buffers.length&&(a.envInFirst=v-p);var h=a.envInFixTs;h.splice(0,0,{t:v,d:p});for(var g=v,m=0,d=0;d<h.length;d++){var S=h[d];if(3e3<v-S.t){h.length=d;break}g=S.t,m+=S.d}var _=h[1],y=v-g;if(y/3<y-m&&(_&&1e3<y||6<=h.length)){var C=v-_.t-p;if(p/5<C){var b=!o.disableEnvInFix;if(a.CLog("["+v+"]"+(b?"":"未")+"补偿"+C+"ms",3),a.envInFix+=C,b){var k=new Int16Array(C*r/1e3);n+=k.length,c.push(k)}}}var M=a.recSize,I=n,w=M+I;if(a.recSize=w,i){var x=U.SampleData(c,r,o[E],i.chunkInfo);i.chunkInfo=x,w=(M=i.pcmSize)+(I=x.data.length),i.pcmSize=w,c=i.pcmDatas,f=c.length,c.push(x.data),r=x[E]}var A=Math.round(w/r*1e3),L=c.length,T=u.length,D=function(){for(var e=O?0:-I,t=null==c[0],r=f;r<L;r++){var n=c[r];null==n?t=1:(e+=n.length,i&&n.length&&a[o.type+"_encode"](i,n))}if(t&&i)for(r=l,u[0]&&(r=0);r<T;r++)u[r]=null;t&&(e=O?I:0,c[0]=null),i?i.pcmSize+=e:a.recSize+=e},O=0,z="rec.set.onProcess";try{O=o.onProcess(c,s,A,r,f,D)}catch(e){console.error(z+"回调出错是不允许的,需保证不会抛异常",e)}var F=Date.now()-v;if(10<F&&1e3<a.envInFirst-v&&a.CLog(z+"低性能,耗时"+F+"ms",3),!0===O){var R=0;for(d=f;d<L;d++)null==c[d]?R=1:c[d]=new Int16Array(0);R?a.CLog("未进入异步前不能清除buffers",3):i?i.pcmSize-=I:a.recSize-=I}else D()},start:function(){var e=this,t=U.Ctx,r=1;if(e.set.sourceStream?e.Stream||(r=0):U.IsOpen()||(r=0),r)if(e.CLog("开始录音"),e._stop(),e.state=3,e.envStart(null,t[E]),e._SO&&e._SO+1!=e._S)e.CLog("start被中断",3);else{e._SO=0;var n=function(){3==e.state&&(e.state=1,e.resume())};"suspended"==t.state?(e.CLog("wait ctx resume..."),t.resume().then(function(){e.CLog("ctx resume"),n()})):n()}else e.CLog("未open",1)},pause:function(){var e=this;e.state&&(e.state=2,e.CLog("pause"),delete e._streamStore().Stream._call[e.id])},resume:function(){var e,r=this;if(r.state){r.state=1,r.CLog("resume"),r.envResume();var t=r._streamStore().Stream;t._call[r.id]=function(e,t){1==r.state&&r.envIn(e,t)},(e=t)._na&&e._na(),e._ra&&e._ra()}},_stop:function(e){var t=this,r=t.set;t.isMock||t._S++,t.state&&(t.pause(),t.state=0),!e&&t[r.type+"_stop"]&&(t[r.type+"_stop"](t.engineCtx),t.engineCtx=0)},stop:function(r,t,e){var n,a=this,o=a.set,i=a.envInLast-a.envInFirst,s=i&&a.buffers.length;a.CLog("stop 和start时差"+(i?i+"ms 补偿"+a.envInFix+"ms envIn:"+s+" fps:"+(s/i*1e3).toFixed(1):"-"));var c=function(){a._stop(),e&&a.close()},f=function(e){a.CLog("结束录音失败:"+e,1),t&&t(e),c()},u=function(e,t){if(a.CLog("结束录音 编码花"+(Date.now()-n)+"ms 音频时长"+t+"ms 文件大小"+e.size+"b"),o.takeoffEncodeChunk)a.CLog("启用takeoffEncodeChunk后stop返回的blob长度为0不提供音频数据",3);else if(e.size<Math.max(100,t/2))return void f("生成的"+o.type+"无效");r&&r(e,t),c()};if(!a.isMock){var l=3==a.state;if(!a.state||l)return void f("未开始录音"+(l?"开始录音前无用户交互导致AudioContext未运行":""));a._stop(!0)}var v=a.recSize;if(v)if(a.buffers[0])if(a[o.type]){if(a.isMock){var p=a.envCheck(a.mockEnvInfo||{envName:"mock",canProcess:!1});if(p)return void f("录音错误:"+p)}var h=a.engineCtx;if(a[o.type+"_complete"]&&h){var g=Math.round(h.pcmSize/o[E]*1e3);return n=Date.now(),void a[o.type+"_complete"](h,function(e){u(e,g)},f)}n=Date.now();var m=U.SampleData(a.buffers,a[P],o[E]);o[E]=m[E];var d=m.data;g=Math.round(d.length/o[E]*1e3),a.CLog("采样"+v+"->"+d.length+" 花:"+(Date.now()-n)+"ms"),setTimeout(function(){n=Date.now(),a[o.type](d,function(e){u(e,g)},function(e){f(e)})})}else f("未加载"+o.type+"编码器");else f("音频buffers被释放");else f("未采集到录音")}},x[A]&&(z("重复引入"+A,3),x[A].Destroy()),x[A]=U;var F=function(e,t){t.pos||(t.pos=[0],t.tracks={},t.bytes=[]);var r=t.tracks,n=[t.pos[0]],a=function(){t.pos[0]=n[0]},o=t.bytes.length,i=new Uint8Array(o+e.length);if(i.set(t.bytes),i.set(e,o),t.bytes=i,!t._ht){if(B(i,n),N(i,n),!R(B(i,n),[24,83,128,103]))return;for(B(i,n);n[0]<i.length;){var s=B(i,n),c=N(i,n),f=[0],u=0;if(!c)return;if(R(s,[22,84,174,107])){for(;f[0]<c.length;){var l=B(c,f),v=N(c,f),p=[0],h={channels:0,sampleRate:0};if(R(l,[174]))for(;p[0]<v.length;){var g=B(v,p),m=N(v,p),d=[0];if(R(g,[215])){var S=W(m);h.number=S,r[S]=h}else if(R(g,[131])){var S=W(m);1==S?h.type="video":2==S?(h.type="audio",u||(t.track0=h),h.idx=u++):h.type="Type-"+S}else if(R(g,[134])){for(var _="",y=0;y<m.length;y++)_+=String.fromCharCode(m[y]);h.codec=_}else if(R(g,[225]))for(;d[0]<m.length;){var C=B(m,d),b=N(m,d);if(R(C,[181])){var S=0,k=new Uint8Array(b.reverse()).buffer;4==b.length?S=new Float32Array(k)[0]:8==b.length?S=new Float64Array(k)[0]:z("WebM Track !Float",1,b),h[E]=Math.round(S)}else R(C,[98,100])?h.bitDepth=W(b):R(C,[159])&&(h.channels=W(b))}}}t._ht=1,z("WebM Tracks",r),a();break}}}var M=t.track0;if(M){if(16==M.bitDepth&&/FLOAT/i.test(M.codec)&&(M.bitDepth=32,z("WebM 16改32位",3)),M[E]!=t[E]||32!=M.bitDepth||M.channels<1||!/(\b|_)PCM\b/i.test(M.codec))return t.bytes=[],t.bad||z("WebM Track非预期",3,t),-(t.bad=1);for(var I=[],w=0;n[0]<i.length;){var l=B(i,n),v=N(i,n);if(!v)break;if(R(l,[163])){var x=15&v[0],h=r[x];if(0===h.idx){for(var A=new Uint8Array(v.length-4),y=4;y<v.length;y++)A[y-4]=v[y];I.push(A),w+=A.length}}a()}if(w){var L=new Uint8Array(i.length-t.pos[0]);L.set(i.subarray(t.pos[0])),t.bytes=L,t.pos[0]=0;for(var A=new Uint8Array(w),y=0,T=0;y<I.length;y++)A.set(I[y],T),T+=I[y].length;var k=new Float32Array(A.buffer);if(1<M.channels){for(var D=[],y=0;y<k.length;)D.push(k[y]),y+=M.channels;k=new Float32Array(D)}return k}}},R=function(e,t){if(!e||e.length!=t.length)return!1;if(1==e.length)return e[0]==t[0];for(var r=0;r<e.length;r++)if(e[r]!=t[r])return!1;return!0},W=function(e){for(var t="",r=0;r<e.length;r++){var n=e[r];t+=(n<16?"0":"")+n.toString(16)}return parseInt(t,16)||0},B=function(e,t,r){var n=t[0];if(!(n>=e.length)){var a=e[n],o=("0000000"+a.toString(2)).substr(-8),i=/^(0*1)(\d*)$/.exec(o);if(i){var s=i[1].length,c=[];if(!(n+s>e.length)){for(var f=0;f<s;f++)c[f]=e[n],n++;return r&&(c[0]=parseInt(i[2]||"0",2)),t[0]=n,c}}}},N=function(e,t){var r=B(e,t,1);if(r){var n=W(r),a=t[0],o=[];if(n<2147483647){if(a+n>e.length)return;for(var i=0;i<n;i++)o[i]=e[a],a++}return t[0]=a,o}};U.TrafficImgUrl="";var o=U.Traffic=function(e){e=e?"/"+A+"/Report/"+e:"";var t=U.TrafficImgUrl;if(t){var r=U.Traffic,n=/^(https?:..[^\/#]*\/?)[^#]*/i.exec(location.href)||[],a=n[1]||"http://file/",o=(n[0]||a)+e;if(0==t.indexOf("//")&&(t=/^https:/i.test(o)?"https:"+t:"http:"+t),e&&(t=t+"&cu="+encodeURIComponent(a+e)),!r[o]){r[o]=1;var i=new Image;i.src=t,z("Traffic Analysis Image: "+(e||A+".TrafficImgUrl="+U.TrafficImgUrl))}}}}(window),"function"==typeof define&&define.amd&&define(function(){return Recorder}),"object"==typeof module&&module.exports&&(module.exports=Recorder);