g-ai-robot3 0.1.32 → 0.1.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +82 -82
- package/dist/g-ai-robot3.common.js +3391 -495
- package/dist/g-ai-robot3.css +1 -1
- package/dist/g-ai-robot3.umd.js +3391 -495
- package/dist/g-ai-robot3.umd.min.js +1 -12
- package/package.json +60 -59
package/dist/g-ai-robot3.umd.js
CHANGED
|
@@ -11,30 +11,2239 @@
|
|
|
11
11
|
return /******/ (function() { // webpackBootstrap
|
|
12
12
|
/******/ var __webpack_modules__ = ({
|
|
13
13
|
|
|
14
|
-
/***/
|
|
15
|
-
/***/ (function(
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
!function(t,e){ true?module.exports=e():0}(this,function(){return function(t){var e={};function n(i){if(e[i])return e[i].exports;var o=e[i]={i:i,l:!1,exports:{}};return t[i].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=t,n.c=e,n.d=function(t,e,i){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:i})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var o in t)n.d(i,o,function(e){return t[e]}.bind(null,o));return i},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s=1)}([function(t,e,n){"use strict";function i(t,e,n){for(var i=0;i<n.length;i++)t.setUint8(e+i,n.charCodeAt(i))}Object.defineProperty(e,"__esModule",{value:!0}),e.compress=function(t,e,n){for(var i=e/n,o=Math.max(i,1),r=t.left,a=t.right,s=Math.floor((r.length+a.length)/i),u=new Float32Array(s),c=0,l=0;c<s;){var f=Math.floor(l);u[c]=r[f],c++,a.length&&(u[c]=a[f],c++),l+=o}return u},e.encodePCM=function(t,e,n){void 0===n&&(n=!0);var i=0,o=t.length*(e/8),r=new ArrayBuffer(o),a=new DataView(r);if(8===e)for(var s=0;s<t.length;s++,i++){var u=(c=Math.max(-1,Math.min(1,t[s])))<0?128*c:127*c;u=+u+128,a.setInt8(i,u)}else for(s=0;s<t.length;s++,i+=2){var c=Math.max(-1,Math.min(1,t[s]));a.setInt16(i,c<0?32768*c:32767*c,n)}return a},e.encodeWAV=function(t,e,n,o,r,a){void 0===a&&(a=!0);var s=n>e?e:n,u=r,c=new ArrayBuffer(44+t.byteLength),l=new DataView(c),f=o,p=0;i(l,p,"RIFF"),p+=4,l.setUint32(p,36+t.byteLength,a),i(l,p+=4,"WAVE"),i(l,p+=4,"fmt "),p+=4,l.setUint32(p,16,a),p+=4,l.setUint16(p,1,a),p+=2,l.setUint16(p,f,a),p+=2,l.setUint32(p,s,a),p+=4,l.setUint32(p,f*s*(u/8),a),p+=4,l.setUint16(p,f*(u/8),a),p+=2,l.setUint16(p,u,a),i(l,p+=2,"data"),p+=4,l.setUint32(p,t.byteLength,a),p+=4;for(var d=0;d<t.byteLength;)l.setUint8(p,t.getUint8(d)),p++,d++;return l}},function(t,e,n){"use strict";var i,o=this&&this.__extends||(i=function(t,e){return(i=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n])})(t,e)},function(t,e){function n(){this.constructor=t}i(t,e),t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)});Object.defineProperty(e,"__esModule",{value:!0});var r=n(2),a=n(0),s=n(3),u=function(t){function e(e){void 0===e&&(e={});var n=t.call(this,e)||this;return n.isrecording=!1,n.ispause=!1,n.isplaying=!1,n}return o(e,t),e.prototype.setOption=function(t){void 0===t&&(t={}),this.setNewOption(t)},e.prototype.start=function(){return this.isrecording?Promise.reject():(this.isrecording=!0,this.startRecord())},e.prototype.pause=function(){this.isrecording&&!this.ispause&&(this.ispause=!0,this.pauseRecord())},e.prototype.resume=function(){this.isrecording&&this.ispause&&(this.ispause=!1,this.resumeRecord())},e.prototype.stop=function(){this.isrecording&&(this.isrecording=!1,this.ispause=!1,this.stopRecord())},e.prototype.play=function(){this.stop(),this.isplaying=!0,this.onplay&&this.onplay(),s.default.addPlayEnd(this.onplayend);var t=this.getWAV();t.byteLength>44&&s.default.play(t.buffer)},e.prototype.getPlayTime=function(){return s.default.getPlayTime()},e.prototype.pausePlay=function(){!this.isrecording&&this.isplaying&&(this.isplaying=!1,this.onpauseplay&&this.onpauseplay(),s.default.pausePlay())},e.prototype.resumePlay=function(){this.isrecording||this.isplaying||(this.isplaying=!0,this.onresumeplay&&this.onresumeplay(),s.default.resumePlay())},e.prototype.stopPlay=function(){this.isrecording||(this.isplaying=!1,this.onstopplay&&this.onstopplay(),s.default.stopPlay())},e.prototype.destroy=function(){return s.default.destroyPlay(),this.destroyRecord()},e.prototype.getRecordAnalyseData=function(){return this.getAnalyseData()},e.prototype.getPlayAnalyseData=function(){return s.default.getAnalyseData()},e.prototype.getPCM=function(){this.stop();var t=this.getData();return t=a.compress(t,this.inputSampleRate,this.outputSampleRate),a.encodePCM(t,this.oututSampleBits,this.littleEdian)},e.prototype.getPCMBlob=function(){return new Blob([this.getPCM()])},e.prototype.downloadPCM=function(t){void 0===t&&(t="recorder");var e=this.getPCMBlob();r.downloadPCM(e,t)},e.prototype.getWAV=function(){var t=this.getPCM();return a.encodeWAV(t,this.inputSampleRate,this.outputSampleRate,this.config.numChannels,this.oututSampleBits,this.littleEdian)},e.prototype.getWAVBlob=function(){return new Blob([this.getWAV()],{type:"audio/wav"})},e.prototype.downloadWAV=function(t){void 0===t&&(t="recorder");var e=this.getWAVBlob();r.downloadWAV(e,t)},e.prototype.download=function(t,e,n){r.download(t,e,n)},e.prototype.getChannelData=function(){var t=this.getPCM(),e=t.byteLength,n=this.littleEdian,i={left:null,right:null};if(2===this.config.numChannels){var o=new DataView(new ArrayBuffer(e/2)),r=new DataView(new ArrayBuffer(e/2));if(16===this.config.sampleBits)for(var a=0;a<e/2;a+=2)o.setInt16(a,t.getInt16(2*a,n),n),r.setInt16(a,t.getInt16(2*a+2,n),n);else for(a=0;a<e/2;a+=2)o.setInt8(a,t.getInt8(2*a)),r.setInt8(a,t.getInt8(2*a+1));i.left=o,i.right=r}else i.left=t;return i},e}(n(5).default);e.default=u},function(t,e,n){"use strict";function i(t,e,n){var i=document.createElement("a");i.href=window.URL.createObjectURL(t),i.download=e+"."+n,i.click()}Object.defineProperty(e,"__esModule",{value:!0}),e.downloadWAV=function(t,e){void 0===e&&(e="recorder"),i(t,e,"wav")},e.downloadPCM=function(t,e){void 0===e&&(e="recorder"),i(t,e,"pcm")},e.download=function(t,e,n){return i(t,e,n)}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var i=n(4),o=null,r=0,a=0,s=null,u=null,c=null,l=!1,f=0,p=function(){};function d(){return l=!1,s.decodeAudioData(c.slice(0),function(t){(o=s.createBufferSource()).onended=function(){l||(f=s.currentTime-a+r,p())},o.buffer=t,o.connect(u),u.connect(s.destination),o.start(0,r),a=s.currentTime},function(t){i.throwError(t)})}function h(){o&&(o.stop(),o=null)}var y=function(){function t(){}return t.play=function(t){return s||(s=new(window.AudioContext||window.webkitAudioContext),(u=s.createAnalyser()).fftSize=2048),this.stopPlay(),c=t,f=0,d()},t.pausePlay=function(){h(),r+=s.currentTime-a,l=!0},t.resumePlay=function(){return d()},t.stopPlay=function(){r=0,c=null,h()},t.destroyPlay=function(){this.stopPlay()},t.getAnalyseData=function(){var t=new Uint8Array(u.frequencyBinCount);return u.getByteTimeDomainData(t),t},t.addPlayEnd=function(t){void 0===t&&(t=function(){}),p=t},t.getPlayTime=function(){var t=l?r:s.currentTime-a+r;return f||t},t}();e.default=y},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.throwError=function(t){throw new Error(t)}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var i=n(0),o=function(){function t(e){void 0===e&&(e={}),this.size=0,this.lBuffer=[],this.rBuffer=[],this.tempPCM=[],this.inputSampleBits=16,this.fileSize=0,this.duration=0,this.needRecord=!0;var n,i=new(window.AudioContext||window.webkitAudioContext);this.inputSampleRate=i.sampleRate,this.setNewOption(e),this.littleEdian=(n=new ArrayBuffer(2),new DataView(n).setInt16(0,256,!0),256===new Int16Array(n)[0]),t.initUserMedia()}return t.prototype.setNewOption=function(t){void 0===t&&(t={}),this.config={sampleBits:~[8,16].indexOf(t.sampleBits)?t.sampleBits:16,sampleRate:~[8e3,11025,16e3,22050,24e3,44100,48e3].indexOf(t.sampleRate)?t.sampleRate:this.inputSampleRate,numChannels:~[1,2].indexOf(t.numChannels)?t.numChannels:1},this.outputSampleRate=this.config.sampleRate,this.oututSampleBits=this.config.sampleBits},t.prototype.startRecord=function(){var t=this;return this.context&&this.destroyRecord(),this.initRecorder(),navigator.mediaDevices.getUserMedia({audio:!0}).then(function(e){t.audioInput=t.context.createMediaStreamSource(e),t.stream=e}).then(function(){t.audioInput.connect(t.analyser),t.analyser.connect(t.recorder),t.recorder.connect(t.context.destination)})},t.prototype.pauseRecord=function(){this.needRecord=!1},t.prototype.resumeRecord=function(){this.needRecord=!0},t.prototype.stopRecord=function(){this.audioInput&&this.audioInput.disconnect(),this.source&&this.source.stop(),this.recorder.disconnect(),this.analyser.disconnect(),this.needRecord=!0},t.prototype.destroyRecord=function(){return this.clearRecordStatus(),this.stopStream(),this.closeAudioContext()},t.prototype.getAnalyseData=function(){var t=new Uint8Array(this.analyser.frequencyBinCount);return this.analyser.getByteTimeDomainData(t),t},t.prototype.getData=function(){return this.flat()},t.prototype.clearRecordStatus=function(){this.lBuffer.length=0,this.rBuffer.length=0,this.size=0,this.fileSize=0,this.PCM=null,this.audioInput=null,this.duration=0},t.prototype.flat=function(){var t=null,e=new Float32Array(0);1===this.config.numChannels?t=new Float32Array(this.size):(t=new Float32Array(this.size/2),e=new Float32Array(this.size/2));for(var n=0,i=0;i<this.lBuffer.length;i++)t.set(this.lBuffer[i],n),n+=this.lBuffer[i].length;n=0;for(i=0;i<this.rBuffer.length;i++)e.set(this.rBuffer[i],n),n+=this.rBuffer[i].length;return{left:t,right:e}},t.prototype.initRecorder=function(){var t=this;this.clearRecordStatus(),this.context=new(window.AudioContext||window.webkitAudioContext),this.analyser=this.context.createAnalyser(),this.analyser.fftSize=2048;var e=this.context.createScriptProcessor||this.context.createJavaScriptNode;this.recorder=e.apply(this.context,[4096,this.config.numChannels,this.config.numChannels]),this.recorder.onaudioprocess=function(e){if(t.needRecord){var n,i=e.inputBuffer.getChannelData(0),o=null;t.lBuffer.push(new Float32Array(i)),t.size+=i.length,2===t.config.numChannels&&(o=e.inputBuffer.getChannelData(1),t.rBuffer.push(new Float32Array(o)),t.size+=o.length),t.fileSize=Math.floor(t.size/Math.max(t.inputSampleRate/t.outputSampleRate,1))*(t.oututSampleBits/8),n=100*Math.max.apply(Math,i),t.duration+=4096/t.inputSampleRate,t.onprocess&&t.onprocess(t.duration),t.onprogress&&t.onprogress({duration:t.duration,fileSize:t.fileSize,vol:n})}}},t.prototype.stopStream=function(){this.stream&&this.stream.getTracks&&(this.stream.getTracks().forEach(function(t){return t.stop()}),this.stream=null)},t.prototype.closeAudioContext=function(){return this.context&&this.context.close&&"closed"!==this.context.state?this.context.close():new Promise(function(t){t()})},t.initUserMedia=function(){void 0===navigator.mediaDevices&&(navigator.mediaDevices={}),void 0===navigator.mediaDevices.getUserMedia&&(navigator.mediaDevices.getUserMedia=function(t){var e=navigator.getUserMedia||navigator.webkitGetUserMedia||navigator.mozGetUserMedia;return e?new Promise(function(n,i){e.call(navigator,t,n,i)}):Promise.reject(new Error("浏览器不支持 getUserMedia !"))})},t.prototype.transformIntoPCM=function(t,e){var n=new Float32Array(t),o=new Float32Array(e),r=i.compress({left:n,right:o},this.inputSampleRate,this.outputSampleRate);return i.encodePCM(r,this.oututSampleBits,this.littleEdian)},t.getPermission=function(){return this.initUserMedia(),navigator.mediaDevices.getUserMedia({audio:!0}).then(function(t){t&&t.getTracks().forEach(function(t){return t.stop()})})},t}();e.default=o}]).default});
|
|
28
|
-
|
|
14
|
+
/***/ 9243:
|
|
15
|
+
/***/ (function() {
|
|
16
|
+
|
|
17
|
+
/*
|
|
18
|
+
录音 Recorder扩展,动态波形显示
|
|
19
|
+
https://github.com/xiangyuecn/Recorder
|
|
20
|
+
*/
|
|
21
|
+
(function(factory){
|
|
22
|
+
var browser=typeof window=="object" && !!window.document;
|
|
23
|
+
var win=browser?window:Object; //非浏览器环境,Recorder挂载在Object下面
|
|
24
|
+
var rec=win.Recorder,ni=rec.i18n;
|
|
25
|
+
factory(rec,ni,ni.$T,browser);
|
|
26
|
+
}(function(Recorder,i18n,$T,isBrowser){
|
|
27
|
+
"use strict";
|
|
28
|
+
|
|
29
|
+
var WaveView=function(set){
|
|
30
|
+
return new fn(set);
|
|
31
|
+
};
|
|
32
|
+
var ViewTxt="WaveView";
|
|
33
|
+
var fn=function(set){
|
|
34
|
+
var This=this;
|
|
35
|
+
var o={
|
|
36
|
+
/*
|
|
37
|
+
elem:"css selector" //自动显示到dom,并以此dom大小为显示大小
|
|
38
|
+
//或者配置显示大小,手动把waveviewObj.elem显示到别的地方
|
|
39
|
+
,width:0 //显示宽度
|
|
40
|
+
,height:0 //显示高度
|
|
41
|
+
|
|
42
|
+
H5环境以上配置二选一
|
|
43
|
+
|
|
44
|
+
compatibleCanvas: CanvasObject //提供一个兼容H5的canvas对象,需支持getContext("2d"),支持设置width、height,支持drawImage(canvas,...)
|
|
45
|
+
,width:0 //canvas显示宽度
|
|
46
|
+
,height:0 //canvas显示高度
|
|
47
|
+
非H5环境使用以上配置
|
|
48
|
+
*/
|
|
49
|
+
|
|
50
|
+
scale:2 //缩放系数,应为正整数,使用2(3? no!)倍宽高进行绘制,避免移动端绘制模糊
|
|
51
|
+
,speed:9 //移动速度系数,越大越快
|
|
52
|
+
,phase:21.8 //相位,调整了速度后,调整这个值得到一个看起来舒服的波形
|
|
53
|
+
|
|
54
|
+
,fps:20 //绘制帧率,调整后也需调整phase值
|
|
55
|
+
,keep:true //当停止了input输入时,是否保持波形,设为false停止后将变成一条线
|
|
56
|
+
|
|
57
|
+
,lineWidth:3 //线条基础粗细
|
|
58
|
+
|
|
59
|
+
//渐变色配置:[位置,css颜色,...] 位置: 取值0.0-1.0之间
|
|
60
|
+
,linear1:[0,"rgba(150,96,238,1)",0.2,"rgba(170,79,249,1)",1,"rgba(53,199,253,1)"] //线条渐变色1,从左到右
|
|
61
|
+
,linear2:[0,"rgba(209,130,255,0.6)",1,"rgba(53,199,255,0.6)"] //线条渐变色2,从左到右
|
|
62
|
+
,linearBg:[0,"rgba(255,255,255,0.2)",1,"rgba(54,197,252,0.2)"] //背景渐变色,从上到下
|
|
63
|
+
};
|
|
64
|
+
for(var k in set){
|
|
65
|
+
o[k]=set[k];
|
|
66
|
+
};
|
|
67
|
+
This.set=set=o;
|
|
68
|
+
|
|
69
|
+
var cCanvas="compatibleCanvas";
|
|
70
|
+
if(set[cCanvas]){
|
|
71
|
+
var canvas=This.canvas=set[cCanvas];
|
|
72
|
+
}else{
|
|
73
|
+
if(!isBrowser)throw new Error($T.G("NonBrowser-1",[ViewTxt]));
|
|
74
|
+
var elem=set.elem;
|
|
75
|
+
if(elem){
|
|
76
|
+
if(typeof(elem)=="string"){
|
|
77
|
+
elem=document.querySelector(elem);
|
|
78
|
+
}else if(elem.length){
|
|
79
|
+
elem=elem[0];
|
|
80
|
+
};
|
|
81
|
+
};
|
|
82
|
+
if(elem){
|
|
83
|
+
set.width=elem.offsetWidth;
|
|
84
|
+
set.height=elem.offsetHeight;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
var thisElem=This.elem=document.createElement("div");
|
|
88
|
+
thisElem.style.fontSize=0;
|
|
89
|
+
thisElem.innerHTML='<canvas style="width:100%;height:100%;"/>';
|
|
90
|
+
|
|
91
|
+
var canvas=This.canvas=thisElem.querySelector("canvas");
|
|
92
|
+
|
|
93
|
+
if(elem){
|
|
94
|
+
elem.innerHTML="";
|
|
95
|
+
elem.appendChild(thisElem);
|
|
96
|
+
};
|
|
97
|
+
};
|
|
98
|
+
var scale=set.scale;
|
|
99
|
+
var width=set.width*scale;
|
|
100
|
+
var height=set.height*scale;
|
|
101
|
+
if(!width || !height){
|
|
102
|
+
throw new Error($T.G("IllegalArgs-1",[ViewTxt+" width=0 height=0"]));
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
canvas.width=width;
|
|
106
|
+
canvas.height=height;
|
|
107
|
+
var ctx=This.ctx=canvas.getContext("2d");
|
|
108
|
+
|
|
109
|
+
This.linear1=This.genLinear(ctx,width,set.linear1);
|
|
110
|
+
This.linear2=This.genLinear(ctx,width,set.linear2);
|
|
111
|
+
This.linearBg=This.genLinear(ctx,height,set.linearBg,true);
|
|
112
|
+
|
|
113
|
+
This._phase=0;
|
|
114
|
+
};
|
|
115
|
+
fn.prototype=WaveView.prototype={
|
|
116
|
+
genLinear:function(ctx,size,colors,top){
|
|
117
|
+
var rtv=ctx.createLinearGradient(0,0,top?0:size,top?size:0);
|
|
118
|
+
for(var i=0;i<colors.length;){
|
|
119
|
+
rtv.addColorStop(colors[i++],colors[i++]);
|
|
120
|
+
};
|
|
121
|
+
return rtv;
|
|
122
|
+
}
|
|
123
|
+
,genPath:function(frequency,amplitude,phase){
|
|
124
|
+
//曲线生成算法参考 https://github.com/HaloMartin/MCVoiceWave/blob/f6dc28975fbe0f7fc6cc4dbc2e61b0aa5574e9bc/MCVoiceWave/MCVoiceWaveView.m#L268
|
|
125
|
+
var rtv=[];
|
|
126
|
+
var This=this,set=This.set;
|
|
127
|
+
var scale=set.scale;
|
|
128
|
+
var width=set.width*scale;
|
|
129
|
+
var maxAmplitude=set.height*scale/2;
|
|
130
|
+
|
|
131
|
+
for(var x=0;x<=width;x+=scale) {
|
|
132
|
+
var scaling=(1+Math.cos(Math.PI+(x/width)*2*Math.PI))/2;
|
|
133
|
+
var y=scaling*maxAmplitude*amplitude*Math.sin(2*Math.PI*(x/width)*frequency+phase)+maxAmplitude;
|
|
134
|
+
rtv.push(y);
|
|
135
|
+
}
|
|
136
|
+
return rtv;
|
|
137
|
+
}
|
|
138
|
+
,input:function(pcmData,powerLevel,sampleRate){
|
|
139
|
+
var This=this;
|
|
140
|
+
This.sampleRate=sampleRate;
|
|
141
|
+
This.pcmData=pcmData;
|
|
142
|
+
This.pcmPos=0;
|
|
143
|
+
|
|
144
|
+
This.inputTime=Date.now();
|
|
145
|
+
This.schedule();
|
|
146
|
+
}
|
|
147
|
+
,schedule:function(){
|
|
148
|
+
var This=this,set=This.set;
|
|
149
|
+
var interval=Math.floor(1000/set.fps);
|
|
150
|
+
if(!This.timer){
|
|
151
|
+
This.timer=setInterval(function(){
|
|
152
|
+
This.schedule();
|
|
153
|
+
},interval);
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
var now=Date.now();
|
|
157
|
+
var drawTime=This.drawTime||0;
|
|
158
|
+
if(now-drawTime<interval){
|
|
159
|
+
//没到间隔时间,不绘制
|
|
160
|
+
return;
|
|
161
|
+
};
|
|
162
|
+
This.drawTime=now;
|
|
163
|
+
|
|
164
|
+
//切分当前需要的绘制数据
|
|
165
|
+
var bufferSize=This.sampleRate/set.fps;
|
|
166
|
+
var pcm=This.pcmData;
|
|
167
|
+
var pos=This.pcmPos;
|
|
168
|
+
var len=Math.max(0, Math.min(bufferSize,pcm.length-pos));
|
|
169
|
+
var sum=0;
|
|
170
|
+
for(var i=0;i<len;i++,pos++){
|
|
171
|
+
sum+=Math.abs(pcm[pos]);
|
|
172
|
+
};
|
|
173
|
+
This.pcmPos=pos;
|
|
174
|
+
|
|
175
|
+
//推入绘制
|
|
176
|
+
if(len || !set.keep){
|
|
177
|
+
This.draw(Recorder.PowerLevel(sum, len));
|
|
178
|
+
}
|
|
179
|
+
if(!len && now-This.inputTime>1300){
|
|
180
|
+
//超时没有输入,干掉定时器
|
|
181
|
+
clearInterval(This.timer);
|
|
182
|
+
This.timer=0;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
,draw:function(powerLevel){
|
|
186
|
+
var This=this,set=This.set;
|
|
187
|
+
var ctx=This.ctx;
|
|
188
|
+
var scale=set.scale;
|
|
189
|
+
var width=set.width*scale;
|
|
190
|
+
var height=set.height*scale;
|
|
191
|
+
|
|
192
|
+
var speedx=set.speed/set.fps;
|
|
193
|
+
var phase=This._phase-=speedx;//位移速度
|
|
194
|
+
var phase2=phase+speedx*set.phase;
|
|
195
|
+
var amplitude=powerLevel/100;
|
|
196
|
+
var path1=This.genPath(2,amplitude,phase);
|
|
197
|
+
var path2=This.genPath(1.8,amplitude,phase2);
|
|
198
|
+
|
|
199
|
+
//开始绘制图形
|
|
200
|
+
ctx.clearRect(0,0,width,height);
|
|
201
|
+
|
|
202
|
+
//绘制包围背景
|
|
203
|
+
ctx.beginPath();
|
|
204
|
+
for(var i=0,x=0;x<=width;i++,x+=scale) {
|
|
205
|
+
if (x==0) {
|
|
206
|
+
ctx.moveTo(x,path1[i]);
|
|
207
|
+
}else {
|
|
208
|
+
ctx.lineTo(x,path1[i]);
|
|
209
|
+
};
|
|
210
|
+
};
|
|
211
|
+
i--;
|
|
212
|
+
for(var x=width-1;x>=0;i--,x-=scale) {
|
|
213
|
+
ctx.lineTo(x,path2[i]);
|
|
214
|
+
};
|
|
215
|
+
ctx.closePath();
|
|
216
|
+
ctx.fillStyle=This.linearBg;
|
|
217
|
+
ctx.fill();
|
|
218
|
+
|
|
219
|
+
//绘制线
|
|
220
|
+
This.drawPath(path2,This.linear2);
|
|
221
|
+
This.drawPath(path1,This.linear1);
|
|
222
|
+
}
|
|
223
|
+
,drawPath:function(path,linear){
|
|
224
|
+
var This=this,set=This.set;
|
|
225
|
+
var ctx=This.ctx;
|
|
226
|
+
var scale=set.scale;
|
|
227
|
+
var width=set.width*scale;
|
|
228
|
+
|
|
229
|
+
ctx.beginPath();
|
|
230
|
+
for(var i=0,x=0;x<=width;i++,x+=scale) {
|
|
231
|
+
if (x==0) {
|
|
232
|
+
ctx.moveTo(x,path[i]);
|
|
233
|
+
}else {
|
|
234
|
+
ctx.lineTo(x,path[i]);
|
|
235
|
+
};
|
|
236
|
+
};
|
|
237
|
+
ctx.lineWidth=set.lineWidth*scale;
|
|
238
|
+
ctx.strokeStyle=linear;
|
|
239
|
+
ctx.stroke();
|
|
240
|
+
}
|
|
241
|
+
};
|
|
242
|
+
Recorder[ViewTxt]=WaveView;
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
}));
|
|
29
246
|
|
|
30
247
|
/***/ }),
|
|
31
248
|
|
|
32
|
-
/***/
|
|
33
|
-
/***/ (function(module,
|
|
249
|
+
/***/ 2346:
|
|
250
|
+
/***/ (function(module, exports, __webpack_require__) {
|
|
251
|
+
|
|
252
|
+
var __WEBPACK_AMD_DEFINE_RESULT__;/*
|
|
253
|
+
录音
|
|
254
|
+
https://github.com/xiangyuecn/Recorder
|
|
255
|
+
*/
|
|
256
|
+
(function(factory){
|
|
257
|
+
var browser=typeof window=="object" && !!window.document;
|
|
258
|
+
var win=browser?window:Object; //非浏览器环境,Recorder挂载在Object下面
|
|
259
|
+
factory(win,browser);
|
|
260
|
+
//umd returnExports.js
|
|
261
|
+
if(true){
|
|
262
|
+
!(__WEBPACK_AMD_DEFINE_RESULT__ = (function(){
|
|
263
|
+
return win.Recorder;
|
|
264
|
+
}).call(exports, __webpack_require__, exports, module),
|
|
265
|
+
__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
|
|
266
|
+
};
|
|
267
|
+
if( true && module.exports){
|
|
268
|
+
module.exports=win.Recorder;
|
|
269
|
+
};
|
|
270
|
+
}(function(Export,isBrowser){
|
|
271
|
+
"use strict";
|
|
272
|
+
|
|
273
|
+
var NOOP=function(){};
|
|
274
|
+
var IsNum=function(v){return typeof v=="number"};
|
|
275
|
+
var ToJson=function(v){return JSON.stringify(v)};
|
|
276
|
+
|
|
277
|
+
var Recorder=function(set){
|
|
278
|
+
return new initFn(set);
|
|
279
|
+
};
|
|
280
|
+
var LM=Recorder.LM="2024-10-20 22:15";
|
|
281
|
+
var GitUrl="https://github.com/xiangyuecn/Recorder";
|
|
282
|
+
var RecTxt="Recorder";
|
|
283
|
+
var getUserMediaTxt="getUserMedia";
|
|
284
|
+
var srcSampleRateTxt="srcSampleRate";
|
|
285
|
+
var sampleRateTxt="sampleRate";
|
|
286
|
+
var bitRateTxt="bitRate";
|
|
287
|
+
var CatchTxt="catch";
|
|
288
|
+
|
|
289
|
+
var WRec2=Export[RecTxt];//重复加载js
|
|
290
|
+
if(WRec2&&WRec2.LM==LM){
|
|
291
|
+
WRec2.CLog(WRec2.i18n.$T("K8zP::重复导入{1}",0,RecTxt),3);
|
|
292
|
+
return;
|
|
293
|
+
};
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
//是否已经打开了全局的麦克风录音,所有工作都已经准备好了,就等接收音频数据了
|
|
297
|
+
Recorder.IsOpen=function(){
|
|
298
|
+
var stream=Recorder.Stream;
|
|
299
|
+
if(stream){
|
|
300
|
+
var tracks=Tracks_(stream), track=tracks[0];
|
|
301
|
+
if(track){
|
|
302
|
+
var state=track.readyState;
|
|
303
|
+
return state=="live"||state==track.LIVE;
|
|
304
|
+
};
|
|
305
|
+
};
|
|
306
|
+
return false;
|
|
307
|
+
};
|
|
308
|
+
/*H5录音时的AudioContext缓冲大小。会影响H5录音时的onProcess调用速率,相对于AudioContext.sampleRate=48000时,4096接近12帧/s,调节此参数可生成比较流畅的回调动画。
|
|
309
|
+
取值256, 512, 1024, 2048, 4096, 8192, or 16384
|
|
310
|
+
注意,取值不能过低,2048开始不同浏览器可能回调速率跟不上造成音质问题。
|
|
311
|
+
一般无需调整,调整后需要先close掉已打开的录音,再open时才会生效。
|
|
312
|
+
*/
|
|
313
|
+
Recorder.BufferSize=4096;
|
|
314
|
+
//销毁已持有的所有全局资源,当要彻底移除Recorder时需要显式的调用此方法
|
|
315
|
+
Recorder.Destroy=function(){
|
|
316
|
+
CLog(RecTxt+" Destroy");
|
|
317
|
+
Disconnect();//断开可能存在的全局Stream、资源
|
|
318
|
+
|
|
319
|
+
for(var k in DestroyList){
|
|
320
|
+
DestroyList[k]();
|
|
321
|
+
};
|
|
322
|
+
};
|
|
323
|
+
var DestroyList={};
|
|
324
|
+
//登记一个需要销毁全局资源的处理方法
|
|
325
|
+
Recorder.BindDestroy=function(key,call){
|
|
326
|
+
DestroyList[key]=call;
|
|
327
|
+
};
|
|
328
|
+
//判断浏览器是否支持录音,随时可以调用。注意:仅仅是检测浏览器支持情况,不会判断和调起用户授权,不会判断是否支持特定格式录音。
|
|
329
|
+
Recorder.Support=function(){
|
|
330
|
+
if(!isBrowser) return false;
|
|
331
|
+
var scope=navigator.mediaDevices||{};
|
|
332
|
+
if(!scope[getUserMediaTxt]){
|
|
333
|
+
scope=navigator;
|
|
334
|
+
scope[getUserMediaTxt]||(scope[getUserMediaTxt]=scope.webkitGetUserMedia||scope.mozGetUserMedia||scope.msGetUserMedia);
|
|
335
|
+
};
|
|
336
|
+
if(!scope[getUserMediaTxt]){
|
|
337
|
+
return false;
|
|
338
|
+
};
|
|
339
|
+
Recorder.Scope=scope;
|
|
340
|
+
|
|
341
|
+
if(!Recorder.GetContext()){
|
|
342
|
+
return false;
|
|
343
|
+
};
|
|
344
|
+
return true;
|
|
345
|
+
};
|
|
346
|
+
//获取AudioContext对象,如果浏览器不支持将返回null。tryNew=false时返回全局的Recorder.Ctx,Ctx.state可能是closed,仅限用于解码等操作。tryNew=true时会尝试创建新的ctx(不支持close的老浏览器依旧返回全局的),注意用完必须自己调用CloseNewCtx(ctx)关闭;注意:非用户操作(触摸、点击等)时调用返回的ctx.state可能是suspended状态,需要在用户操作时调用ctx.resume恢复成running状态,参考rec的runningContext配置
|
|
347
|
+
Recorder.GetContext=function(tryNew){
|
|
348
|
+
if(!isBrowser) return null;
|
|
349
|
+
var AC=window.AudioContext;
|
|
350
|
+
if(!AC){
|
|
351
|
+
AC=window.webkitAudioContext;
|
|
352
|
+
};
|
|
353
|
+
if(!AC){
|
|
354
|
+
return null;
|
|
355
|
+
};
|
|
356
|
+
|
|
357
|
+
var ctx=Recorder.Ctx, isNew=0;
|
|
358
|
+
if(!ctx){ //241020版本后不再保留打开状态的ctx,原因是iOS不全部关闭时新的ctx有可能不正常
|
|
359
|
+
//不能反复构造,低版本number of hardware contexts reached maximum (6)
|
|
360
|
+
ctx=Recorder.Ctx=new AC(); isNew=1;
|
|
361
|
+
Recorder.NewCtxs=Recorder.NewCtxs||[];
|
|
362
|
+
|
|
363
|
+
Recorder.BindDestroy("Ctx",function(){
|
|
364
|
+
var ctx=Recorder.Ctx;
|
|
365
|
+
if(ctx&&ctx.close){//能关掉就关掉,关不掉就保留着
|
|
366
|
+
CloseCtx(ctx);
|
|
367
|
+
Recorder.Ctx=0;
|
|
368
|
+
};
|
|
369
|
+
var arr=Recorder.NewCtxs; Recorder.NewCtxs=[];
|
|
370
|
+
for(var i=0;i<arr.length;i++)CloseCtx(arr[i]);
|
|
371
|
+
});
|
|
372
|
+
};
|
|
373
|
+
if(tryNew && ctx.close){//没法关闭的不允许再创建
|
|
374
|
+
if(!isNew){
|
|
375
|
+
if(!ctx._useC) CloseCtx(ctx); //关闭全局的,不再保留打开状态
|
|
376
|
+
ctx=new AC(); //如果是上面新建的就用上面的,不然就用全新的
|
|
377
|
+
};
|
|
378
|
+
ctx._useC=1;
|
|
379
|
+
Recorder.NewCtxs.push(ctx);
|
|
380
|
+
};
|
|
381
|
+
return ctx;
|
|
382
|
+
};
|
|
383
|
+
//关闭新创建的AudioContext(之前老版本如果是全局的不关闭,241020版本后全部关闭)
|
|
384
|
+
Recorder.CloseNewCtx=function(ctx){
|
|
385
|
+
if(ctx && ctx.close){
|
|
386
|
+
CloseCtx(ctx);
|
|
387
|
+
var arr=Recorder.NewCtxs||[],L=arr.length;
|
|
388
|
+
for(var i=0;i<arr.length;i++){
|
|
389
|
+
if(arr[i]==ctx){ arr.splice(i,1); break; }
|
|
390
|
+
}
|
|
391
|
+
CLog($T("mSxV::剩{1}个GetContext未close",0,L+"-1="+arr.length),arr.length?3:0);
|
|
392
|
+
}
|
|
393
|
+
};
|
|
394
|
+
var CloseCtx=function(ctx){
|
|
395
|
+
if(ctx && ctx.close && !ctx._isC){
|
|
396
|
+
ctx._isC=1;
|
|
397
|
+
if(ctx.state!="closed"){
|
|
398
|
+
try{ ctx.close() }catch(e){ CLog("ctx close err",1,e) }
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
};
|
|
402
|
+
//当AudioContext的状态是suspended时,调用resume恢复状态,但如果没有用户操作resume可能没有回调,封装解决此回调问题;check(count)返回true继续尝试resume,返回false终止任务(不回调False)
|
|
403
|
+
var ResumeCtx=Recorder.ResumeCtx=function(ctx,check,True,False){
|
|
404
|
+
var isEnd=0,isBind=0,isLsSC=0,runC=0,EL="EventListener",Tag="ResumeCtx ";
|
|
405
|
+
var end=function(err,ok){
|
|
406
|
+
if(isBind){ bind() }
|
|
407
|
+
if(!isEnd){ isEnd=1; //回调结果
|
|
408
|
+
err&&False(err,runC);
|
|
409
|
+
ok&&True(runC);
|
|
410
|
+
}
|
|
411
|
+
if(ok){ //监听后续状态变化
|
|
412
|
+
if(!ctx._LsSC && ctx["add"+EL]) ctx["add"+EL]("statechange",run);
|
|
413
|
+
ctx._LsSC=1; isLsSC=1;
|
|
414
|
+
}
|
|
415
|
+
};
|
|
416
|
+
var bind=function(add){
|
|
417
|
+
if(add && isBind) return; isBind=add?1:0;
|
|
418
|
+
var types=["focus","mousedown","mouseup","touchstart","touchend"];
|
|
419
|
+
for(var i=0;i<types.length;i++)
|
|
420
|
+
window[(add?"add":"remove")+EL](types[i],run,true);
|
|
421
|
+
};
|
|
422
|
+
var run=function(){
|
|
423
|
+
var sVal=ctx.state,spEnd=CtxSpEnd(sVal);
|
|
424
|
+
if(!isEnd && !check(spEnd?++runC:runC))return end(); //终止,不回调
|
|
425
|
+
if(spEnd){
|
|
426
|
+
if(isLsSC)CLog(Tag+"sc "+sVal,3);
|
|
427
|
+
bind(1); //绑定用户事件尝试恢复
|
|
428
|
+
ctx.resume().then(function(){ //resume回调不可靠
|
|
429
|
+
if(isLsSC)CLog(Tag+"sc "+ctx.state);
|
|
430
|
+
end(0,1);
|
|
431
|
+
})[CatchTxt](function(e){ //出错且无法恢复
|
|
432
|
+
CLog(Tag+"error",1,e);
|
|
433
|
+
if(!CtxSpEnd(ctx.state)){
|
|
434
|
+
end(e.message||"error");
|
|
435
|
+
}
|
|
436
|
+
});
|
|
437
|
+
}else if(sVal=="closed"){
|
|
438
|
+
if(isLsSC && !ctx._isC)CLog(Tag+"sc "+sVal,1); //无法恢复,打个日志
|
|
439
|
+
end("ctx closed");
|
|
440
|
+
}else{ end(0,1) }; //running 或老的无state
|
|
441
|
+
};
|
|
442
|
+
run();
|
|
443
|
+
};
|
|
444
|
+
var CtxSpEnd=Recorder.CtxSpEnd=function(v){
|
|
445
|
+
return v=="suspended"||v=="interrupted"; //后面这个仅iOS有
|
|
446
|
+
};
|
|
447
|
+
var CtxState=function(ctx){
|
|
448
|
+
var v=ctx.state,msg="ctx.state="+v;
|
|
449
|
+
if(CtxSpEnd(v))msg+=$T("nMIy::(注意:ctx不是running状态,rec.open和start至少要有一个在用户操作(触摸、点击等)时进行调用,否则将在rec.start时尝试进行ctx.resume,可能会产生兼容性问题(仅iOS),请参阅文档中runningContext配置)");
|
|
450
|
+
return msg;
|
|
451
|
+
};
|
|
452
|
+
|
|
453
|
+
|
|
454
|
+
/*是否启用MediaRecorder.WebM.PCM来进行音频采集连接(如果浏览器支持的话),默认启用,禁用或者不支持时将使用AudioWorklet或ScriptProcessor来连接;MediaRecorder采集到的音频数据比其他方式更好,几乎不存在丢帧现象,所以音质明显会好很多,建议保持开启*/
|
|
455
|
+
var ConnectEnableWebM="ConnectEnableWebM";
|
|
456
|
+
Recorder[ConnectEnableWebM]=true;
|
|
457
|
+
|
|
458
|
+
/*是否启用AudioWorklet特性来进行音频采集连接(如果浏览器支持的话),默认禁用,禁用或不支持时将使用过时的ScriptProcessor来连接(如果方法还在的话),当前AudioWorklet的实现在移动端没有ScriptProcessor稳健;ConnectEnableWebM如果启用并且有效时,本参数将不起作用*/
|
|
459
|
+
var ConnectEnableWorklet="ConnectEnableWorklet";
|
|
460
|
+
Recorder[ConnectEnableWorklet]=false;
|
|
461
|
+
|
|
462
|
+
/*初始化H5音频采集连接。如果自行提供了sourceStream将只进行一次简单的连接处理。如果是普通麦克风录音,此时的Stream是全局的,Safari上断开后就无法再次进行连接使用,表现为静音,因此使用全部使用全局处理避免调用到disconnect;全局处理也有利于屏蔽底层细节,start时无需再调用底层接口,提升兼容、可靠性。*/
|
|
463
|
+
var Connect=function(streamStore){
|
|
464
|
+
var bufferSize=streamStore.BufferSize||Recorder.BufferSize;
|
|
465
|
+
|
|
466
|
+
var stream=streamStore.Stream;
|
|
467
|
+
var ctx=stream._c, ctxSR=ctx[sampleRateTxt], srChunk={};
|
|
468
|
+
|
|
469
|
+
//获取音频流信息
|
|
470
|
+
var tracks=Tracks_(stream),track=tracks[0],trackSet=null,tsMsg="";
|
|
471
|
+
if(track && track.getSettings){
|
|
472
|
+
trackSet=track.getSettings();
|
|
473
|
+
var trackSR=trackSet[sampleRateTxt];
|
|
474
|
+
if(trackSR && trackSR!=ctxSR){
|
|
475
|
+
tsMsg=$T("eS8i::Stream的采样率{1}不等于{2},将进行采样率转换(注意:音质不会变好甚至可能变差),主要在移动端未禁用回声消除时会产生此现象,浏览器有回声消除时可能只会返回16k采样率的音频数据,",0,trackSR,ctxSR);
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
stream._ts=trackSet;
|
|
479
|
+
CLog(tsMsg+"Stream TrackSet: "+ToJson(trackSet), tsMsg?3:0);
|
|
480
|
+
|
|
481
|
+
var mediaConn=function(node){
|
|
482
|
+
var media=stream._m=ctx.createMediaStreamSource(stream);
|
|
483
|
+
var ctxDest=ctx.destination,cmsdTxt="createMediaStreamDestination";
|
|
484
|
+
if(ctx[cmsdTxt]){
|
|
485
|
+
ctxDest=stream._d=ctx[cmsdTxt]();
|
|
486
|
+
};
|
|
487
|
+
media.connect(node);
|
|
488
|
+
node.connect(ctxDest);
|
|
489
|
+
}
|
|
490
|
+
var isWebM,isWorklet,badInt,webMTips="";
|
|
491
|
+
var calls=stream._call;
|
|
492
|
+
|
|
493
|
+
//浏览器回传的音频数据处理
|
|
494
|
+
var onReceive=function(float32Arr, arrSR){
|
|
495
|
+
for(var k0 in calls){//has item
|
|
496
|
+
if(arrSR!=ctxSR){ //MediaRecorder录制的采样率可能和ctx的采样率不同(16k),转换采样率方便统一处理代码也更简单,但音质不会变好,甚至可能会变差一点
|
|
497
|
+
srChunk.index=0;
|
|
498
|
+
srChunk=Recorder.SampleData([float32Arr],arrSR,ctxSR,srChunk,{_sum:1});
|
|
499
|
+
var pcm=srChunk.data;
|
|
500
|
+
var sum=srChunk._sum;
|
|
501
|
+
}else{ //采样率相同,不需要转换采样率
|
|
502
|
+
srChunk={};
|
|
503
|
+
var size=float32Arr.length;
|
|
504
|
+
|
|
505
|
+
var pcm=new Int16Array(size);
|
|
506
|
+
var sum=0;
|
|
507
|
+
for(var j=0;j<size;j++){//floatTo16BitPCM
|
|
508
|
+
var s=Math.max(-1,Math.min(1,float32Arr[j]));
|
|
509
|
+
s=s<0?s*0x8000:s*0x7FFF;
|
|
510
|
+
pcm[j]=s;
|
|
511
|
+
sum+=Math.abs(s);
|
|
512
|
+
};
|
|
513
|
+
};
|
|
514
|
+
|
|
515
|
+
for(var k in calls){
|
|
516
|
+
calls[k](pcm,sum);
|
|
517
|
+
};
|
|
518
|
+
|
|
519
|
+
return;
|
|
520
|
+
};
|
|
521
|
+
};
|
|
522
|
+
|
|
523
|
+
var scriptProcessor="ScriptProcessor";//一堆字符串名字,有利于压缩js
|
|
524
|
+
var audioWorklet="audioWorklet";
|
|
525
|
+
var recAudioWorklet=RecTxt+" "+audioWorklet;
|
|
526
|
+
var RecProc="RecProc";
|
|
527
|
+
var MediaRecorderTxt="MediaRecorder";
|
|
528
|
+
var MRWebMPCM=MediaRecorderTxt+".WebM.PCM";
|
|
529
|
+
|
|
530
|
+
|
|
531
|
+
//===================连接方式三=========================
|
|
532
|
+
//古董级别的 ScriptProcessor 处理,目前所有浏览器均兼容,虽然是过时的方法,但更稳健,移动端性能比AudioWorklet强
|
|
533
|
+
var oldFn=ctx.createScriptProcessor||ctx.createJavaScriptNode;
|
|
534
|
+
var oldIsBest=$T("ZGlf::。由于{1}内部1秒375次回调,在移动端可能会有性能问题导致回调丢失录音变短,PC端无影响,暂不建议开启{1}。",0,audioWorklet);
|
|
535
|
+
var oldScript=function(){
|
|
536
|
+
isWorklet=stream.isWorklet=false;
|
|
537
|
+
_Disconn_n(stream);
|
|
538
|
+
CLog($T("7TU0::Connect采用老的{1},",0,scriptProcessor)
|
|
539
|
+
+i18n.get(Recorder[ConnectEnableWorklet]?
|
|
540
|
+
$T("JwCL::但已设置{1}尝试启用{2}",2)
|
|
541
|
+
:$T("VGjB::可设置{1}尝试启用{2}",2)
|
|
542
|
+
,[RecTxt+"."+ConnectEnableWorklet+"=true",audioWorklet]
|
|
543
|
+
)+webMTips+oldIsBest,3);
|
|
544
|
+
|
|
545
|
+
var process=stream._p=oldFn.call(ctx,bufferSize,1,1);//单声道,省的数据处理复杂
|
|
546
|
+
mediaConn(process);
|
|
547
|
+
|
|
548
|
+
process.onaudioprocess=function(e){
|
|
549
|
+
var arr=e.inputBuffer.getChannelData(0);
|
|
550
|
+
onReceive(arr, ctxSR);
|
|
551
|
+
};
|
|
552
|
+
};
|
|
553
|
+
|
|
554
|
+
|
|
555
|
+
//===================连接方式二=========================
|
|
556
|
+
var connWorklet=function(){
|
|
557
|
+
//尝试开启AudioWorklet处理
|
|
558
|
+
isWebM=stream.isWebM=false;
|
|
559
|
+
_Disconn_r(stream);
|
|
560
|
+
|
|
561
|
+
isWorklet=stream.isWorklet=!oldFn || Recorder[ConnectEnableWorklet];
|
|
562
|
+
var AwNode=window.AudioWorkletNode;
|
|
563
|
+
if(!(isWorklet && ctx[audioWorklet] && AwNode)){
|
|
564
|
+
oldScript();//被禁用 或 不支持,直接使用老的
|
|
565
|
+
return;
|
|
566
|
+
};
|
|
567
|
+
var clazzUrl=function(){
|
|
568
|
+
var xf=function(f){return f.toString().replace(/^function|DEL_/g,"").replace(/\$RA/g,recAudioWorklet)};
|
|
569
|
+
var clazz='class '+RecProc+' extends AudioWorkletProcessor{';
|
|
570
|
+
clazz+="constructor "+xf(function(option){
|
|
571
|
+
DEL_super(option);
|
|
572
|
+
var This=this,bufferSize=option.processorOptions.bufferSize;
|
|
573
|
+
This.bufferSize=bufferSize;
|
|
574
|
+
This.buffer=new Float32Array(bufferSize*2);//乱给size搞乱缓冲区不管
|
|
575
|
+
This.pos=0;
|
|
576
|
+
This.port.onmessage=function(e){
|
|
577
|
+
if(e.data.kill){
|
|
578
|
+
This.kill=true;
|
|
579
|
+
$C.log("$RA kill call");
|
|
580
|
+
}
|
|
581
|
+
};
|
|
582
|
+
$C.log("$RA .ctor call", option);
|
|
583
|
+
});
|
|
584
|
+
|
|
585
|
+
//https://developer.mozilla.org/en-US/docs/Web/API/AudioWorkletProcessor/process 每次回调128个采样数据,1秒375次回调,高频导致移动端性能问题,结果就是回调次数缺斤少两,进而导致丢失数据,PC端似乎没有性能问题
|
|
586
|
+
clazz+="process "+xf(function(input,b,c){//需要等到ctx激活后才会有回调
|
|
587
|
+
var This=this,bufferSize=This.bufferSize;
|
|
588
|
+
var buffer=This.buffer,pos=This.pos;
|
|
589
|
+
input=(input[0]||[])[0]||[];
|
|
590
|
+
if(input.length){
|
|
591
|
+
buffer.set(input,pos);
|
|
592
|
+
pos+=input.length;
|
|
593
|
+
|
|
594
|
+
var len=~~(pos/bufferSize)*bufferSize;
|
|
595
|
+
if(len){
|
|
596
|
+
this.port.postMessage({ val: buffer.slice(0,len) });
|
|
597
|
+
|
|
598
|
+
var more=buffer.subarray(len,pos);
|
|
599
|
+
buffer=new Float32Array(bufferSize*2);
|
|
600
|
+
buffer.set(more);
|
|
601
|
+
pos=more.length;
|
|
602
|
+
This.buffer=buffer;
|
|
603
|
+
}
|
|
604
|
+
This.pos=pos;
|
|
605
|
+
}
|
|
606
|
+
return !This.kill;
|
|
607
|
+
});
|
|
608
|
+
clazz+='}'
|
|
609
|
+
+'try{'
|
|
610
|
+
+'registerProcessor("'+RecProc+'", '+RecProc+')'
|
|
611
|
+
+'}catch(e){$C.error("'+recAudioWorklet+' Reg Error",e)}';
|
|
612
|
+
clazz=clazz.replace(/\$C\./g,"console.");//一些编译器会文本替换日志函数
|
|
613
|
+
//URL.createObjectURL 本地有些浏览器会报 Not allowed to load local resource,直接用dataurl
|
|
614
|
+
return "data:text/javascript;base64,"+btoa(unescape(encodeURIComponent(clazz)));
|
|
615
|
+
};
|
|
616
|
+
|
|
617
|
+
var awNext=function(){//可以继续,没有调用断开
|
|
618
|
+
return isWorklet && stream._na;
|
|
619
|
+
};
|
|
620
|
+
var nodeAlive=stream._na=function(){
|
|
621
|
+
//start时会调用,只要没有收到数据就断定AudioWorklet有问题,恢复用老的
|
|
622
|
+
if(badInt!==""){//没有回调过数据
|
|
623
|
+
clearTimeout(badInt);
|
|
624
|
+
badInt=setTimeout(function(){
|
|
625
|
+
badInt=0;
|
|
626
|
+
if(awNext()){
|
|
627
|
+
CLog($T("MxX1::{1}未返回任何音频,恢复使用{2}",0,audioWorklet,scriptProcessor),3);
|
|
628
|
+
oldFn&&oldScript();//未来没有老的,可能是误判
|
|
629
|
+
};
|
|
630
|
+
},500);
|
|
631
|
+
};
|
|
632
|
+
};
|
|
633
|
+
var createNode=function(){
|
|
634
|
+
if(!awNext())return;
|
|
635
|
+
var node=stream._n=new AwNode(ctx, RecProc, {
|
|
636
|
+
processorOptions:{bufferSize:bufferSize}
|
|
637
|
+
});
|
|
638
|
+
mediaConn(node);
|
|
639
|
+
node.port.onmessage=function(e){
|
|
640
|
+
if(badInt){
|
|
641
|
+
clearTimeout(badInt);badInt="";
|
|
642
|
+
};
|
|
643
|
+
if(awNext()){
|
|
644
|
+
onReceive(e.data.val, ctxSR);
|
|
645
|
+
}else if(!isWorklet){
|
|
646
|
+
CLog($T("XUap::{1}多余回调",0,audioWorklet),3);
|
|
647
|
+
};
|
|
648
|
+
};
|
|
649
|
+
CLog($T("yOta::Connect采用{1},设置{2}可恢复老式{3}",0,audioWorklet,RecTxt+"."+ConnectEnableWorklet+"=false",scriptProcessor)+webMTips+oldIsBest,3);
|
|
650
|
+
};
|
|
651
|
+
|
|
652
|
+
//如果start时的resume和下面的构造node同时进行,将会导致部分浏览器崩溃 (STATUS_ACCESS_VIOLATION),源码assets中 ztest_chrome_bug_AudioWorkletNode.html 可测试。所以,将所有代码套到resume里面(不管catch),避免出现这个问题
|
|
653
|
+
var ctxOK=function(){
|
|
654
|
+
if(!awNext())return;
|
|
655
|
+
if(ctx[RecProc]){
|
|
656
|
+
createNode();
|
|
657
|
+
return;
|
|
658
|
+
};
|
|
659
|
+
var url=clazzUrl();
|
|
660
|
+
ctx[audioWorklet].addModule(url).then(function(e){
|
|
661
|
+
if(!awNext())return;
|
|
662
|
+
ctx[RecProc]=1;
|
|
663
|
+
createNode();
|
|
664
|
+
if(badInt){//重新计时
|
|
665
|
+
nodeAlive();
|
|
666
|
+
};
|
|
667
|
+
})[CatchTxt](function(e){ //fix 关键字,保证catch压缩时保持字符串形式
|
|
668
|
+
CLog(audioWorklet+".addModule Error",1,e);
|
|
669
|
+
awNext()&&oldScript();
|
|
670
|
+
});
|
|
671
|
+
};
|
|
672
|
+
ResumeCtx(ctx,function(){ return awNext() } ,ctxOK,ctxOK);
|
|
673
|
+
};
|
|
674
|
+
|
|
675
|
+
|
|
676
|
+
//===================连接方式一=========================
|
|
677
|
+
var connWebM=function(){
|
|
678
|
+
//尝试开启MediaRecorder录制webm+pcm处理
|
|
679
|
+
var MR=window[MediaRecorderTxt];
|
|
680
|
+
var onData="ondataavailable";
|
|
681
|
+
var webmType="audio/webm; codecs=pcm";
|
|
682
|
+
isWebM=stream.isWebM=Recorder[ConnectEnableWebM];
|
|
683
|
+
|
|
684
|
+
var supportMR=MR && (onData in MR.prototype) && MR.isTypeSupported(webmType);
|
|
685
|
+
webMTips=supportMR?"":$T("VwPd::(此浏览器不支持{1})",0,MRWebMPCM);
|
|
686
|
+
if(!isWebM || !supportMR){
|
|
687
|
+
connWorklet(); //被禁用 或 不支持MediaRecorder 或 不支持webm+pcm
|
|
688
|
+
return;
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
var mrNext=function(){//可以继续,没有调用断开
|
|
692
|
+
return isWebM && stream._ra;
|
|
693
|
+
};
|
|
694
|
+
stream._ra=function(){
|
|
695
|
+
//start时会调用,只要没有收到数据就断定MediaRecorder有问题,降级处理
|
|
696
|
+
if(badInt!==""){//没有回调过数据
|
|
697
|
+
clearTimeout(badInt);
|
|
698
|
+
badInt=setTimeout(function(){
|
|
699
|
+
//badInt=0; 保留给nodeAlive继续判断
|
|
700
|
+
if(mrNext()){
|
|
701
|
+
CLog($T("vHnb::{1}未返回任何音频,降级使用{2}",0,MediaRecorderTxt,audioWorklet),3);
|
|
702
|
+
connWorklet();
|
|
703
|
+
};
|
|
704
|
+
},500);
|
|
705
|
+
};
|
|
706
|
+
};
|
|
707
|
+
|
|
708
|
+
var mrSet=Object.assign({mimeType:webmType}, Recorder.ConnectWebMOptions);
|
|
709
|
+
var mr=stream._r=new MR(stream, mrSet);
|
|
710
|
+
var webmData=stream._rd={};
|
|
711
|
+
mr[onData]=function(e){
|
|
712
|
+
//提取webm中的pcm数据,提取失败就等着badInt超时降级处理
|
|
713
|
+
var reader=new FileReader();
|
|
714
|
+
reader.onloadend=function(){
|
|
715
|
+
if(mrNext()){
|
|
716
|
+
var f32arr=WebM_Extract(new Uint8Array(reader.result),webmData);
|
|
717
|
+
if(!f32arr)return;
|
|
718
|
+
if(f32arr==-1){//无法提取,立即降级
|
|
719
|
+
connWorklet();
|
|
720
|
+
return;
|
|
721
|
+
};
|
|
722
|
+
|
|
723
|
+
if(badInt){
|
|
724
|
+
clearTimeout(badInt);badInt="";
|
|
725
|
+
};
|
|
726
|
+
onReceive(f32arr, webmData.webmSR);
|
|
727
|
+
}else if(!isWebM){
|
|
728
|
+
CLog($T("O9P7::{1}多余回调",0,MediaRecorderTxt),3);
|
|
729
|
+
};
|
|
730
|
+
};
|
|
731
|
+
reader.readAsArrayBuffer(e.data);
|
|
732
|
+
};
|
|
733
|
+
mr.start(~~(bufferSize/48));//按48k时的回调间隔
|
|
734
|
+
CLog($T("LMEm::Connect采用{1},设置{2}可恢复使用{3}或老式{4}",0,MRWebMPCM,RecTxt+"."+ConnectEnableWebM+"=false",audioWorklet,scriptProcessor));
|
|
735
|
+
};
|
|
736
|
+
|
|
737
|
+
connWebM();
|
|
738
|
+
};
|
|
739
|
+
var ConnAlive=function(stream){
|
|
740
|
+
if(stream._na) stream._na(); //检查AudioWorklet连接是否有效,无效就回滚到老的ScriptProcessor
|
|
741
|
+
if(stream._ra) stream._ra(); //检查MediaRecorder连接是否有效,无效就降级处理
|
|
742
|
+
};
|
|
743
|
+
var _Disconn_n=function(stream){
|
|
744
|
+
stream._na=null;
|
|
745
|
+
if(stream._n){
|
|
746
|
+
stream._n.port.postMessage({kill:true});
|
|
747
|
+
stream._n.disconnect();
|
|
748
|
+
stream._n=null;
|
|
749
|
+
};
|
|
750
|
+
};
|
|
751
|
+
var _Disconn_r=function(stream){
|
|
752
|
+
stream._ra=null;
|
|
753
|
+
if(stream._r){
|
|
754
|
+
try{ stream._r.stop() }catch(e){ CLog("mr stop err",1,e) }
|
|
755
|
+
stream._r=null;
|
|
756
|
+
};
|
|
757
|
+
};
|
|
758
|
+
var Disconnect=function(streamStore){
|
|
759
|
+
streamStore=streamStore||Recorder;
|
|
760
|
+
var isGlobal=streamStore==Recorder;
|
|
761
|
+
|
|
762
|
+
var stream=streamStore.Stream;
|
|
763
|
+
if(stream){
|
|
764
|
+
if(stream._m){
|
|
765
|
+
stream._m.disconnect();
|
|
766
|
+
stream._m=null;
|
|
767
|
+
};
|
|
768
|
+
if(!stream._RC && stream._c){//提供的runningContext不处理
|
|
769
|
+
Recorder.CloseNewCtx(stream._c);
|
|
770
|
+
};
|
|
771
|
+
stream._RC=null; stream._c=null;
|
|
772
|
+
if(stream._d){
|
|
773
|
+
StopS_(stream._d.stream);
|
|
774
|
+
stream._d=null;
|
|
775
|
+
};
|
|
776
|
+
if(stream._p){
|
|
777
|
+
stream._p.disconnect();
|
|
778
|
+
stream._p.onaudioprocess=stream._p=null;
|
|
779
|
+
};
|
|
780
|
+
_Disconn_n(stream);
|
|
781
|
+
_Disconn_r(stream);
|
|
782
|
+
|
|
783
|
+
if(isGlobal){//全局的时候,要把流关掉(麦克风),直接提供的流不处理
|
|
784
|
+
StopS_(stream);
|
|
785
|
+
};
|
|
786
|
+
};
|
|
787
|
+
streamStore.Stream=0;
|
|
788
|
+
};
|
|
789
|
+
//关闭一个音频流
|
|
790
|
+
var StopS_=Recorder.StopS_=function(stream){
|
|
791
|
+
var tracks=Tracks_(stream);
|
|
792
|
+
for(var i=0;i<tracks.length;i++){
|
|
793
|
+
var track=tracks[i];
|
|
794
|
+
track.stop&&track.stop();
|
|
795
|
+
};
|
|
796
|
+
stream.stop&&stream.stop();
|
|
797
|
+
};
|
|
798
|
+
//获取流中的所有轨道
|
|
799
|
+
var Tracks_=function(stream){
|
|
800
|
+
var arr1=0,arr2=0,arr=[];
|
|
801
|
+
//stream.getTracks() 得到的sourceStream还得去排序 不然第一个可能是video
|
|
802
|
+
if(stream.getAudioTracks){ arr1=stream.getAudioTracks(); arr2=stream.getVideoTracks(); }
|
|
803
|
+
if(!arr1){ arr1=stream.audioTracks; arr2=stream.videoTracks; }
|
|
804
|
+
for(var i=0,L=arr1?arr1.length:0;i<L;i++)arr.push(arr1[i]); //音频放前面,方便取[0]
|
|
805
|
+
for(var i=0,L=arr2?arr2.length:0;i<L;i++)arr.push(arr2[i]);
|
|
806
|
+
return arr;
|
|
807
|
+
};
|
|
808
|
+
|
|
809
|
+
/*对pcm数据的采样率进行转换
|
|
810
|
+
pcmDatas: [[Int16,...]] pcm片段列表,二维数组里面是Int16Array,也可传Float32Array(会转成Int16Array)
|
|
811
|
+
pcmSampleRate:48000 pcm数据的采样率
|
|
812
|
+
newSampleRate:16000 需要转换成的采样率,241020版本后支持转成任意采样率,之前老版本newSampleRate>=pcmSampleRate时不会进行任何处理,小于时会进行重新采样
|
|
813
|
+
prevChunkInfo:{} 可选,上次调用时的返回值,用于连续转换,本次调用将从上次结束位置开始进行处理。或可自行定义一个ChunkInfo从pcmDatas指定的位置开始进行转换
|
|
814
|
+
option:{ 可选,配置项
|
|
815
|
+
frameSize:123456 帧大小,每帧的PCM Int16的数量,采样率转换后的pcm长度为frameSize的整数倍,用于连续转换。目前仅在mp3格式时才有用,frameSize取值为1152,这样编码出来的mp3时长和pcm的时长完全一致,否则会因为mp3最后一帧录音不够填满时添加填充数据导致mp3的时长变长。
|
|
816
|
+
frameType:"" 帧类型,一般为rec.set.type,提供此参数时无需提供frameSize,会自动使用最佳的值给frameSize赋值,目前仅支持mp3=1152(MPEG1 Layer3的每帧采采样数),其他类型=1。
|
|
817
|
+
以上两个参数用于连续转换时使用,最多使用一个,不提供时不进行帧的特殊处理,提供时必须同时提供prevChunkInfo才有作用。最后一段数据处理时无需提供帧大小以便输出最后一丁点残留数据。
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
返回ChunkInfo:{
|
|
821
|
+
//可定义,从指定位置开始转换到结尾
|
|
822
|
+
index:0 pcmDatas已处理到的索引;比如每次都是单个pcm需要连续处理时,可每次调用前重置成0,pcmDatas仅需传入`[pcm]`固定一个元素
|
|
823
|
+
offset:0.0 已处理到的index对应的pcm中的偏移的下一个位置(提升采样率时为结果的pcm)
|
|
824
|
+
raisePrev:null 提升采样率时的前一个pcm结果采样值
|
|
825
|
+
|
|
826
|
+
//可定义,指定的一个滤波配置:默认使用Recorder.IIRFilter低通滤波(可有效抑制混叠产生的杂音,小采样率大于高采样率的75%时不默认滤波),如果提供了配置但fn为null时将不滤波;sr、srn为此滤波函数对应的初始化采样率,当采样率和参数的不一致时将重新设为默认函数
|
|
827
|
+
filter:null||{fn:fn(sample),sr:pcmSampleRate,srn:newSampleRate}
|
|
828
|
+
|
|
829
|
+
//仅作为返回值
|
|
830
|
+
frameNext:null||[Int16,...] 下一帧的部分数据,frameSize设置了的时候才可能会有
|
|
831
|
+
sampleRate:16000 结果的采样率=newSampleRate,老版本<=newSampleRate
|
|
832
|
+
data:[Int16,...] 转换后的PCM结果;如果是连续转换,并且pcmDatas中并没有新数据时,data的长度可能为0
|
|
833
|
+
}
|
|
834
|
+
*/
|
|
835
|
+
Recorder.SampleData=function(pcmDatas,pcmSampleRate,newSampleRate,prevChunkInfo,option){
|
|
836
|
+
var Txt="SampleData";
|
|
837
|
+
prevChunkInfo||(prevChunkInfo={});
|
|
838
|
+
var index=prevChunkInfo.index||0;
|
|
839
|
+
var offset=prevChunkInfo.offset||0;
|
|
840
|
+
var raisePrev=prevChunkInfo.raisePrev||0;
|
|
841
|
+
|
|
842
|
+
var filter=prevChunkInfo.filter;
|
|
843
|
+
if(filter&&filter.fn&&(filter.sr&&filter.sr!=pcmSampleRate || filter.srn&&filter.srn!=newSampleRate)){
|
|
844
|
+
filter=null; CLog($T("d48C::{1}的filter采样率变了,重设滤波",0,Txt),3);
|
|
845
|
+
};
|
|
846
|
+
if(!filter){ //采样率差距比较大才开启低通滤波
|
|
847
|
+
if(newSampleRate<=pcmSampleRate){ //降低采样率或不变,最高频率用新采样率频率的3/4
|
|
848
|
+
var freq=newSampleRate>pcmSampleRate*3/4?0: newSampleRate/2 *3/4;
|
|
849
|
+
filter={fn:freq?Recorder.IIRFilter(true,pcmSampleRate,freq):0};
|
|
850
|
+
}else{ //提升采样率,最高频率用原始采样率频率的3/4
|
|
851
|
+
var freq=pcmSampleRate>newSampleRate*3/4?0: pcmSampleRate/2 *3/4;
|
|
852
|
+
filter={fn:freq?Recorder.IIRFilter(true,newSampleRate,freq):0};
|
|
853
|
+
};
|
|
854
|
+
};
|
|
855
|
+
filter.sr=pcmSampleRate;
|
|
856
|
+
filter.srn=newSampleRate;
|
|
857
|
+
var filterFn=filter.fn;
|
|
858
|
+
|
|
859
|
+
var frameNext=prevChunkInfo.frameNext||[];
|
|
860
|
+
option||(option={});
|
|
861
|
+
var frameSize=option.frameSize||1;
|
|
862
|
+
if(option.frameType){
|
|
863
|
+
frameSize=option.frameType=="mp3"?1152:1;
|
|
864
|
+
};
|
|
865
|
+
var useSum=option._sum, _sum=0; //内部用的,sum不考虑配置了frame
|
|
866
|
+
|
|
867
|
+
var nLen=pcmDatas.length;
|
|
868
|
+
if(index>nLen+1){
|
|
869
|
+
CLog($T("tlbC::{1}似乎传入了未重置chunk {2}",0,Txt,index+">"+nLen),3);
|
|
870
|
+
};
|
|
871
|
+
var size=0;
|
|
872
|
+
for(var i=index;i<nLen;i++){
|
|
873
|
+
size+=pcmDatas[i].length;
|
|
874
|
+
};
|
|
875
|
+
|
|
876
|
+
//采样 https://www.cnblogs.com/blqw/p/3782420.html
|
|
877
|
+
var step=pcmSampleRate/newSampleRate;
|
|
878
|
+
if(step>1){//新采样低于录音采样,进行抽样
|
|
879
|
+
size=Math.max(0,size-Math.floor(offset));
|
|
880
|
+
size=Math.floor(size/step);
|
|
881
|
+
}else if(step<1){//新采样高于录音采样,插值处理
|
|
882
|
+
var raiseStep=1/step;
|
|
883
|
+
size=Math.floor(size*raiseStep);
|
|
884
|
+
};
|
|
885
|
+
|
|
886
|
+
size+=frameNext.length;
|
|
887
|
+
var res=new Int16Array(size);
|
|
888
|
+
var idx=0;
|
|
889
|
+
//添加上一次不够一帧的剩余数据
|
|
890
|
+
for(var i=0;i<frameNext.length;i++){
|
|
891
|
+
res[idx]=frameNext[i];
|
|
892
|
+
idx++;
|
|
893
|
+
};
|
|
894
|
+
//处理数据
|
|
895
|
+
for (;index<nLen;index++) {
|
|
896
|
+
var o=pcmDatas[index], isF32=o instanceof Float32Array;
|
|
897
|
+
var i=offset,il=o.length;
|
|
898
|
+
var F=filterFn&&filterFn.Embed,F1=0,F2=0,Fx=0,Fy=0;//低通滤波后的数据
|
|
899
|
+
|
|
900
|
+
if(step<1){ //提升采样率
|
|
901
|
+
var idx1=idx+i, prev=raisePrev;
|
|
902
|
+
for(var i0=0;i0<il;i0++){
|
|
903
|
+
var oVal=o[i0];
|
|
904
|
+
if(isF32){//floatTo16BitPCM
|
|
905
|
+
oVal=Math.max(-1,Math.min(1,oVal));
|
|
906
|
+
oVal=oVal<0?oVal*0x8000:oVal*0x7FFF;
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
var pos=Math.floor(idx1);
|
|
910
|
+
idx1+=raiseStep;
|
|
911
|
+
var end=Math.floor(idx1);
|
|
912
|
+
|
|
913
|
+
//简单的从prev平滑填充到cur,有效减少转换引入的杂音
|
|
914
|
+
var n=(oVal-prev)/(end-pos);
|
|
915
|
+
for(var j=1;pos<end;pos++,j++){
|
|
916
|
+
var s=Math.floor(prev+(j*n));
|
|
917
|
+
if(F){//IIRFilter代码内置,比函数调用快4倍
|
|
918
|
+
Fx=s;
|
|
919
|
+
Fy=F.b0 * Fx + F.b1 * F.x1 + F.b0 * F.x2 - F.a1 * F.y1 - F.a2 * F.y2;
|
|
920
|
+
F.x2 = F.x1; F.x1 = Fx; F.y2 = F.y1; F.y1 = Fy;
|
|
921
|
+
s=Fy;
|
|
922
|
+
}else{ s=filterFn?filterFn(s):s; }
|
|
923
|
+
|
|
924
|
+
if(s>0x7FFF) s=0x7FFF; else if(s<-0x8000) s=-0x8000; //Int16越界处理
|
|
925
|
+
if(useSum) _sum+=Math.abs(s);
|
|
926
|
+
res[pos]=s;
|
|
927
|
+
idx++;
|
|
928
|
+
};
|
|
929
|
+
|
|
930
|
+
prev=raisePrev=oVal;
|
|
931
|
+
i+=raiseStep;//插值
|
|
932
|
+
}
|
|
933
|
+
offset=i%1;
|
|
934
|
+
continue;
|
|
935
|
+
};
|
|
936
|
+
//降低采样率或不变
|
|
937
|
+
for(var i0=0,i2=0;i0<il;i0++,i2++){
|
|
938
|
+
if(i2<il){
|
|
939
|
+
var oVal=o[i2];
|
|
940
|
+
if(isF32){//floatTo16BitPCM
|
|
941
|
+
oVal=Math.max(-1,Math.min(1,oVal));
|
|
942
|
+
oVal=oVal<0?oVal*0x8000:oVal*0x7FFF;
|
|
943
|
+
}
|
|
944
|
+
if(F){//IIRFilter代码内置,比函数调用快4倍
|
|
945
|
+
Fx=oVal;
|
|
946
|
+
Fy=F.b0 * Fx + F.b1 * F.x1 + F.b0 * F.x2 - F.a1 * F.y1 - F.a2 * F.y2;
|
|
947
|
+
F.x2 = F.x1; F.x1 = Fx; F.y2 = F.y1; F.y1 = Fy;
|
|
948
|
+
}else{ Fy=filterFn?filterFn(oVal):oVal; }
|
|
949
|
+
}
|
|
950
|
+
F1=F2; F2=Fy;
|
|
951
|
+
if(i2==0){ i0--; continue; } //首次只计算o[0]
|
|
952
|
+
|
|
953
|
+
//https://www.cnblogs.com/xiaoqi/p/6993912.html
|
|
954
|
+
//当前点=当前点+到后面一个点之间的增量,音质比直接简单抽样好些
|
|
955
|
+
var before = Math.floor(i);
|
|
956
|
+
if(i0!=before)continue;
|
|
957
|
+
var after = Math.ceil(i);
|
|
958
|
+
var atPoint = i - before;
|
|
959
|
+
|
|
960
|
+
var beforeVal=F1;
|
|
961
|
+
var afterVal=after<il ? F2 : beforeVal; //后个点越界了,忽略不计
|
|
962
|
+
var val=beforeVal+(afterVal-beforeVal)*atPoint;
|
|
963
|
+
|
|
964
|
+
if(val>0x7FFF) val=0x7FFF; else if(val<-0x8000) val=-0x8000; //Int16越界处理
|
|
965
|
+
if(useSum) _sum+=Math.abs(val);
|
|
966
|
+
res[idx]=val;
|
|
967
|
+
|
|
968
|
+
idx++;
|
|
969
|
+
i+=step;//抽样
|
|
970
|
+
};
|
|
971
|
+
offset=Math.max(0, i-il); //不太可能出现负数
|
|
972
|
+
};
|
|
973
|
+
if(step<1 && idx+1==size){ //提升采样率时可能缺1个,直接删除结尾1个
|
|
974
|
+
size--; res=new Int16Array(res.buffer.slice(0, size*2));
|
|
975
|
+
};
|
|
976
|
+
if(idx-1!=size && idx!=size)CLog(Txt+" idx:"+idx+" != size:"+size,3); //越界1个
|
|
977
|
+
|
|
978
|
+
//帧处理
|
|
979
|
+
frameNext=null;
|
|
980
|
+
var frameNextSize=size%frameSize;
|
|
981
|
+
if(frameNextSize>0){
|
|
982
|
+
var u8Pos=(size-frameNextSize)*2;
|
|
983
|
+
frameNext=new Int16Array(res.buffer.slice(u8Pos));
|
|
984
|
+
res=new Int16Array(res.buffer.slice(0,u8Pos));
|
|
985
|
+
};
|
|
986
|
+
|
|
987
|
+
var obj={
|
|
988
|
+
index:index
|
|
989
|
+
,offset:offset
|
|
990
|
+
,raisePrev:raisePrev
|
|
991
|
+
,filter:filter
|
|
992
|
+
|
|
993
|
+
,frameNext:frameNext
|
|
994
|
+
,sampleRate:newSampleRate
|
|
995
|
+
,data:res
|
|
996
|
+
};
|
|
997
|
+
if(useSum) obj._sum=_sum;
|
|
998
|
+
return obj;
|
|
999
|
+
};
|
|
1000
|
+
|
|
1001
|
+
/*IIR低通、高通滤波,移植自:https://gitee.com/52jian/digital-audio-filter AudioFilter.java
|
|
1002
|
+
useLowPass: true或false,true为低通滤波,false为高通滤波
|
|
1003
|
+
sampleRate: 待处理pcm的采样率
|
|
1004
|
+
freq: 截止频率Hz,最大频率为sampleRate/2,低通时会切掉高于此频率的声音,高通时会切掉低于此频率的声音,注意滤波并非100%的切掉不需要的声音,而是减弱频率对应的声音,离截止频率越远对应声音减弱越厉害,离截止频率越近声音就几乎无衰减
|
|
1005
|
+
返回的是一个函数,用此函数对pcm的每个采样值按顺序进行处理即可(不同pcm不可共用);注意此函数返回值可能会越界超过Int16范围,自行限制一下即可:Math.min(Math.max(val,-0x8000),0x7FFF)
|
|
1006
|
+
可重新赋值一个函数,来改变Recorder的默认行为,比如SampleData中的低通滤波*/
|
|
1007
|
+
Recorder.IIRFilter=function(useLowPass, sampleRate, freq){
|
|
1008
|
+
var ov = 2 * Math.PI * freq / sampleRate;
|
|
1009
|
+
var sn = Math.sin(ov);
|
|
1010
|
+
var cs = Math.cos(ov);
|
|
1011
|
+
var alpha = sn / 2;
|
|
1012
|
+
|
|
1013
|
+
var a0 = 1 + alpha;
|
|
1014
|
+
var a1 = (-2 * cs) / a0;
|
|
1015
|
+
var a2 = (1 - alpha) / a0;
|
|
1016
|
+
if(useLowPass){
|
|
1017
|
+
var b0 = (1 - cs) / 2 / a0;
|
|
1018
|
+
var b1 = (1 - cs) / a0;
|
|
1019
|
+
}else{
|
|
1020
|
+
var b0 = (1 + cs) / 2 / a0;
|
|
1021
|
+
var b1 = -(1 + cs) / a0;
|
|
1022
|
+
}
|
|
1023
|
+
|
|
1024
|
+
var x1=0,x2=0,y=0,y1=0,y2=0;
|
|
1025
|
+
var fn=function(x){
|
|
1026
|
+
y = b0 * x + b1 * x1 + b0 * x2 - a1 * y1 - a2 * y2;
|
|
1027
|
+
x2 = x1; x1 = x;
|
|
1028
|
+
y2 = y1; y1 = y;
|
|
1029
|
+
return y;
|
|
1030
|
+
};
|
|
1031
|
+
fn.Embed={x1:0,x2:0,y1:0,y2:0,b0:b0,b1:b1,a1:a1,a2:a2};
|
|
1032
|
+
return fn;
|
|
1033
|
+
};
|
|
1034
|
+
|
|
1035
|
+
|
|
1036
|
+
/*计算音量百分比的一个方法
|
|
1037
|
+
pcmAbsSum: pcm Int16所有采样的绝对值的和
|
|
1038
|
+
pcmLength: pcm长度
|
|
1039
|
+
返回值:0-100,主要当做百分比用
|
|
1040
|
+
注意:这个不是分贝,因此没用volume当做名称*/
|
|
1041
|
+
Recorder.PowerLevel=function(pcmAbsSum,pcmLength){
|
|
1042
|
+
/*计算音量 https://blog.csdn.net/jody1989/article/details/73480259
|
|
1043
|
+
更高灵敏度算法:
|
|
1044
|
+
限定最大感应值10000
|
|
1045
|
+
线性曲线:低音量不友好
|
|
1046
|
+
power/10000*100
|
|
1047
|
+
对数曲线:低音量友好,但需限定最低感应值
|
|
1048
|
+
(1+Math.log10(power/10000))*100
|
|
1049
|
+
*/
|
|
1050
|
+
var power=(pcmAbsSum/pcmLength) || 0;//NaN
|
|
1051
|
+
var level;
|
|
1052
|
+
if(power<1251){//1250的结果10%,更小的音量采用线性取值
|
|
1053
|
+
level=Math.round(power/1250*10);
|
|
1054
|
+
}else{
|
|
1055
|
+
level=Math.round(Math.min(100,Math.max(0,(1+Math.log(power/10000)/Math.log(10))*100)));
|
|
1056
|
+
};
|
|
1057
|
+
return level;
|
|
1058
|
+
};
|
|
1059
|
+
|
|
1060
|
+
/*计算音量,单位dBFS(满刻度相对电平)
|
|
1061
|
+
maxSample: 为16位pcm采样的绝对值中最大的一个(计算峰值音量),或者为pcm中所有采样的绝对值的平局值
|
|
1062
|
+
返回值:-100~0 (最大值0dB,最小值-100代替-∞)
|
|
1063
|
+
*/
|
|
1064
|
+
Recorder.PowerDBFS=function(maxSample){
|
|
1065
|
+
var val=Math.max(0.1, maxSample||0),Pref=0x7FFF;
|
|
1066
|
+
val=Math.min(val,Pref);
|
|
1067
|
+
//https://www.logiclocmusic.com/can-you-tell-the-decibel/
|
|
1068
|
+
//https://blog.csdn.net/qq_17256689/article/details/120442510
|
|
1069
|
+
val=20*Math.log(val/Pref)/Math.log(10);
|
|
1070
|
+
return Math.max(-100,Math.round(val));
|
|
1071
|
+
};
|
|
1072
|
+
|
|
1073
|
+
|
|
1074
|
+
|
|
1075
|
+
|
|
1076
|
+
//带时间的日志输出,可设为一个空函数来屏蔽日志输出
|
|
1077
|
+
//CLog(msg,errOrLogMsg, logMsg...) err为数字时代表日志类型1:error 2:log默认 3:warn,否则当做内容输出,第一个参数不能是对象因为要拼接时间,后面可以接无数个输出参数
|
|
1078
|
+
Recorder.CLog=function(msg,err){
|
|
1079
|
+
if(typeof console!="object")return;
|
|
1080
|
+
var now=new Date();
|
|
1081
|
+
var t=("0"+now.getMinutes()).substr(-2)
|
|
1082
|
+
+":"+("0"+now.getSeconds()).substr(-2)
|
|
1083
|
+
+"."+("00"+now.getMilliseconds()).substr(-3);
|
|
1084
|
+
var recID=this&&this.envIn&&this.envCheck&&this.id;
|
|
1085
|
+
var arr=["["+t+" "+RecTxt+(recID?":"+recID:"")+"]"+msg];
|
|
1086
|
+
var a=arguments,cwe=Recorder.CLog;
|
|
1087
|
+
var i=2,fn=cwe.log||console.log;
|
|
1088
|
+
if(IsNum(err)){
|
|
1089
|
+
fn=err==1?cwe.error||console.error:err==3?cwe.warn||console.warn:fn;
|
|
1090
|
+
}else{
|
|
1091
|
+
i=1;
|
|
1092
|
+
};
|
|
1093
|
+
for(;i<a.length;i++){
|
|
1094
|
+
arr.push(a[i]);
|
|
1095
|
+
};
|
|
1096
|
+
if(IsLoser){//古董浏览器,仅保证基本的可执行不代码异常
|
|
1097
|
+
fn&&fn("[IsLoser]"+arr[0],arr.length>1?arr:"");
|
|
1098
|
+
}else{
|
|
1099
|
+
fn.apply(console,arr);
|
|
1100
|
+
};
|
|
1101
|
+
};
|
|
1102
|
+
var CLog=function(){ Recorder.CLog.apply(this,arguments); };
|
|
1103
|
+
var IsLoser=true;try{IsLoser=!console.log.apply;}catch(e){};
|
|
1104
|
+
|
|
1105
|
+
|
|
1106
|
+
|
|
1107
|
+
|
|
1108
|
+
var ID=0;
|
|
1109
|
+
function initFn(set){
|
|
1110
|
+
var This=this; This.id=++ID;
|
|
1111
|
+
|
|
1112
|
+
//如果开启了流量统计,这里将发送一个图片请求
|
|
1113
|
+
Traffic();
|
|
1114
|
+
|
|
1115
|
+
|
|
1116
|
+
var o={
|
|
1117
|
+
type:"mp3" //输出类型:mp3,wav,wav输出文件尺寸超大不推荐使用,但mp3编码支持会导致js文件超大,如果不需支持mp3可以使js文件大幅减小
|
|
1118
|
+
//,bitRate:16 //比特率 wav:16或8位,MP3:8kbps 1k/s,8kbps 2k/s 录音文件很小
|
|
1119
|
+
|
|
1120
|
+
//,sampleRate:16000 //采样率,wav格式大小=sampleRate*时间;mp3此项对低比特率有影响,高比特率几乎无影响。
|
|
1121
|
+
//wav任意值,mp3取值范围:48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000
|
|
1122
|
+
//采样率参考https://www.cnblogs.com/devin87/p/mp3-recorder.html
|
|
1123
|
+
|
|
1124
|
+
,onProcess:NOOP //fn(buffers,powerLevel,bufferDuration,bufferSampleRate,newBufferIdx,asyncEnd) buffers=[[Int16,...],...]:缓冲的PCM数据,为从开始录音到现在的所有pcm片段;powerLevel:当前缓冲的音量级别0-100,bufferDuration:已缓冲时长,bufferSampleRate:缓冲使用的采样率(当type支持边录边转码(Worker)时,此采样率和设置的采样率相同,否则不一定相同);newBufferIdx:本次回调新增的buffer起始索引;asyncEnd:fn() 如果onProcess是异步的(返回值为true时),处理完成时需要调用此回调,如果不是异步的请忽略此参数,此方法回调时必须是真异步(不能真异步时需用setTimeout包裹)。onProcess返回值:如果返回true代表开启异步模式,在某些大量运算的场合异步是必须的,必须在异步处理完成时调用asyncEnd(不能真异步时需用setTimeout包裹),在onProcess执行后新增的buffer会全部替换成空数组,因此本回调开头应立即将newBufferIdx到本次回调结尾位置的buffer全部保存到另外一个数组内,处理完成后写回buffers中本次回调的结尾位置。
|
|
1125
|
+
|
|
1126
|
+
//*******高级设置******
|
|
1127
|
+
//,sourceStream:MediaStream Object
|
|
1128
|
+
//可选直接提供一个媒体流,从这个流中录制、实时处理音频数据(当前Recorder实例独享此流);不提供时为普通的麦克风录音,由getUserMedia提供音频流(所有Recorder实例共享同一个流)
|
|
1129
|
+
//比如:audio、video标签dom节点的captureStream方法(实验特性,不同浏览器支持程度不高)返回的流;WebRTC中的remote流;自己创建的流等
|
|
1130
|
+
//注意:流内必须至少存在一条音轨(Audio Track),比如audio标签必须等待到可以开始播放后才会有音轨,否则open会失败
|
|
1131
|
+
|
|
1132
|
+
//,runningContext:AudioContext
|
|
1133
|
+
//可选提供一个state为running状态的AudioContext对象(ctx);默认会在rec.open时自动创建一个新的ctx,无用户操作(触摸、点击等)时调用rec.open的ctx.state可能为suspended,会在rec.start时尝试进行ctx.resume,如果也无用户操作ctx.resume可能不会恢复成running状态(目前仅iOS上有此兼容性问题),导致无法去读取媒体流,这时请提前在用户操作时调用Recorder.GetContext(true)来得到一个running状态AudioContext(用完需调用CloseNewCtx(ctx)关闭)
|
|
1134
|
+
|
|
1135
|
+
//,audioTrackSet:{ deviceId:"",groupId:"", autoGainControl:true, echoCancellation:true, noiseSuppression:true }
|
|
1136
|
+
//普通麦克风录音时getUserMedia方法的audio配置参数,比如指定设备id,回声消除、降噪开关;注意:提供的任何配置值都不一定会生效
|
|
1137
|
+
//由于麦克风是全局共享的,所以新配置后需要close掉以前的再重新open
|
|
1138
|
+
//同样可配置videoTrackSet,更多参考: https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackConstraints
|
|
1139
|
+
|
|
1140
|
+
//,disableEnvInFix:false 内部参数,禁用设备卡顿时音频输入丢失补偿功能
|
|
1141
|
+
|
|
1142
|
+
//,takeoffEncodeChunk:NOOP //fn(chunkBytes) chunkBytes=[Uint8,...]:实时编码环境下接管编码器输出,当编码器实时编码出一块有效的二进制音频数据时实时回调此方法;参数为二进制的Uint8Array,就是编码出来的音频数据片段,所有的chunkBytes拼接在一起即为完整音频。本实现的想法最初由QQ2543775048提出
|
|
1143
|
+
//当提供此回调方法时,将接管编码器的数据输出,编码器内部将放弃存储生成的音频数据;如果当前编码器或环境不支持实时编码处理,将在open时直接走fail逻辑
|
|
1144
|
+
//因此提供此回调后调用stop方法将无法获得有效的音频数据,因为编码器内没有音频数据,因此stop时返回的blob将是一个字节长度为0的blob
|
|
1145
|
+
//大部分录音格式编码器都支持实时编码(边录边转码),比如mp3格式:会实时的将编码出来的mp3片段通过此方法回调,所有的chunkBytes拼接到一起即为完整的mp3,此种拼接的结果比mock方法实时生成的音质更加,因为天然避免了首尾的静默
|
|
1146
|
+
//不支持实时编码的录音格式不可以提供此回调(wav格式不支持,因为wav文件头中需要提供文件最终长度),提供了将在open时直接走fail逻辑
|
|
1147
|
+
};
|
|
1148
|
+
|
|
1149
|
+
for(var k in set){
|
|
1150
|
+
o[k]=set[k];
|
|
1151
|
+
};
|
|
1152
|
+
This.set=o;
|
|
1153
|
+
|
|
1154
|
+
var vB=o[bitRateTxt],vS=o[sampleRateTxt]; //校验配置参数
|
|
1155
|
+
if(vB&&!IsNum(vB) || vS&&!IsNum(vS)){
|
|
1156
|
+
This.CLog($T.G("IllegalArgs-1",[$T("VtS4::{1}和{2}必须是数值",0,sampleRateTxt,bitRateTxt)]),1,set);
|
|
1157
|
+
};
|
|
1158
|
+
o[bitRateTxt]=+vB||16;
|
|
1159
|
+
o[sampleRateTxt]=+vS||16000;
|
|
1160
|
+
|
|
1161
|
+
This.state=0;//运行状态,0未录音 1录音中 2暂停 3等待ctx激活
|
|
1162
|
+
This._S=9;//stop同步锁,stop可以阻止open过程中还未运行的start
|
|
1163
|
+
This.Sync={O:9,C:9};//和Recorder.Sync一致,只不过这个是非全局的,仅用来简化代码逻辑,无实际作用
|
|
1164
|
+
};
|
|
1165
|
+
//同步锁,控制对Stream的竞争;用于close时中断异步的open;一个对象open如果变化了都要阻止close,Stream的控制权交个新的对象
|
|
1166
|
+
Recorder.Sync={/*open*/O:9,/*close*/C:9};
|
|
1167
|
+
|
|
1168
|
+
Recorder.prototype=initFn.prototype={
|
|
1169
|
+
CLog:CLog
|
|
1170
|
+
|
|
1171
|
+
//流相关的数据存储在哪个对象里面;如果提供了sourceStream,数据直接存储在当前对象中,否则存储在全局
|
|
1172
|
+
,_streamStore:function(){
|
|
1173
|
+
if(this.set.sourceStream){
|
|
1174
|
+
return this;
|
|
1175
|
+
}else{
|
|
1176
|
+
return Recorder;
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1179
|
+
//当前实例用到的Stream,可能是全局的,也可能是独享的
|
|
1180
|
+
,_streamGet:function(){
|
|
1181
|
+
return this._streamStore().Stream;
|
|
1182
|
+
}
|
|
1183
|
+
//当前实例用到的AudioContext,可能是全局的,也可能是独享的
|
|
1184
|
+
,_streamCtx:function(){
|
|
1185
|
+
var m=this._streamGet();
|
|
1186
|
+
return m&&m._c;
|
|
1187
|
+
}
|
|
1188
|
+
|
|
1189
|
+
//打开录音资源True(),False(msg,isUserNotAllow),需要调用close。注意:此方法是异步的;一般使用时打开,用完立即关闭;可重复调用,可用来测试是否能录音;open和start至少有一个应当在用户操作(触摸、点击等)下进行调用,原因参考runningContext配置
|
|
1190
|
+
,open:function(True,False){
|
|
1191
|
+
var This=this,set=This.set,streamStore=This._streamStore(),newCtx=0;
|
|
1192
|
+
True=True||NOOP;
|
|
1193
|
+
var failCall=function(errMsg,isUserNotAllow){
|
|
1194
|
+
isUserNotAllow=!!isUserNotAllow;
|
|
1195
|
+
This.CLog($T("5tWi::录音open失败:")+errMsg+",isUserNotAllow:"+isUserNotAllow,1);
|
|
1196
|
+
if(newCtx)Recorder.CloseNewCtx(newCtx);
|
|
1197
|
+
False&&False(errMsg,isUserNotAllow);
|
|
1198
|
+
};
|
|
1199
|
+
|
|
1200
|
+
This._streamTag=getUserMediaTxt;
|
|
1201
|
+
var ok=function(){
|
|
1202
|
+
This.CLog("open ok, id:"+This.id+" stream:"+This._streamTag);
|
|
1203
|
+
True();
|
|
1204
|
+
|
|
1205
|
+
This._SO=0;//解除stop对open中的start调用的阻止
|
|
1206
|
+
};
|
|
1207
|
+
|
|
1208
|
+
|
|
1209
|
+
//同步锁
|
|
1210
|
+
var Lock=streamStore.Sync;
|
|
1211
|
+
var lockOpen=++Lock.O,lockClose=Lock.C;
|
|
1212
|
+
This._O=This._O_=lockOpen;//记住当前的open,如果变化了要阻止close,这里假定了新对象已取代当前对象并且不再使用
|
|
1213
|
+
This._SO=This._S;//记住open过程中的stop,中途任何stop调用后都不能继续open中的start
|
|
1214
|
+
var lockFail=function(){
|
|
1215
|
+
//允许多次open,但不允许任何一次close,或者自身已经调用了关闭
|
|
1216
|
+
if(lockClose!=Lock.C || !This._O){
|
|
1217
|
+
var err=$T("dFm8::open被取消");
|
|
1218
|
+
if(lockOpen==Lock.O){
|
|
1219
|
+
//无新的open,已经调用了close进行取消,此处应让上次的close明确生效
|
|
1220
|
+
This.close();
|
|
1221
|
+
}else{
|
|
1222
|
+
err=$T("VtJO::open被中断");
|
|
1223
|
+
};
|
|
1224
|
+
failCall(err);
|
|
1225
|
+
return true;
|
|
1226
|
+
};
|
|
1227
|
+
};
|
|
1228
|
+
|
|
1229
|
+
//环境配置检查
|
|
1230
|
+
if(!isBrowser){
|
|
1231
|
+
failCall($T.G("NonBrowser-1",["open"])+$T("EMJq::,可尝试使用RecordApp解决方案")+"("+GitUrl+"/tree/master/app-support-sample)");
|
|
1232
|
+
return;
|
|
1233
|
+
};
|
|
1234
|
+
var checkMsg=This.envCheck({envName:"H5",canProcess:true});
|
|
1235
|
+
if(checkMsg){
|
|
1236
|
+
failCall($T("A5bm::不能录音:")+checkMsg);
|
|
1237
|
+
return;
|
|
1238
|
+
};
|
|
1239
|
+
|
|
1240
|
+
//尽量先创建好ctx,不然异步下创建可能不是running状态
|
|
1241
|
+
var ctx;
|
|
1242
|
+
var getCtx=function(){
|
|
1243
|
+
ctx=set.runningContext;
|
|
1244
|
+
if(!ctx)ctx=newCtx=Recorder.GetContext(true); //2023-06 尽量创建新的ctx,免得Safari再次连接无回调
|
|
1245
|
+
};
|
|
1246
|
+
|
|
1247
|
+
//***********已直接提供了音频流************
|
|
1248
|
+
if(set.sourceStream){
|
|
1249
|
+
This._streamTag="set.sourceStream";
|
|
1250
|
+
if(!Recorder.GetContext()){
|
|
1251
|
+
failCall($T("1iU7::不支持此浏览器从流中获取录音"));
|
|
1252
|
+
return;
|
|
1253
|
+
};
|
|
1254
|
+
getCtx();
|
|
1255
|
+
|
|
1256
|
+
Disconnect(streamStore);//可能已open过,直接先尝试断开
|
|
1257
|
+
var stream=This.Stream=set.sourceStream;
|
|
1258
|
+
stream._c=ctx;
|
|
1259
|
+
stream._RC=set.runningContext;
|
|
1260
|
+
stream._call={};
|
|
1261
|
+
|
|
1262
|
+
try{
|
|
1263
|
+
Connect(streamStore);
|
|
1264
|
+
}catch(e){
|
|
1265
|
+
Disconnect(streamStore);
|
|
1266
|
+
failCall($T("BTW2::从流中打开录音失败:")+e.message);
|
|
1267
|
+
return;
|
|
1268
|
+
}
|
|
1269
|
+
ok();
|
|
1270
|
+
return;
|
|
1271
|
+
};
|
|
1272
|
+
|
|
1273
|
+
|
|
1274
|
+
//***********打开麦克风得到全局的音频流************
|
|
1275
|
+
var codeFail=function(code,msg){
|
|
1276
|
+
try{//跨域的优先检测一下
|
|
1277
|
+
window.top.a;
|
|
1278
|
+
}catch(e){
|
|
1279
|
+
failCall($T("Nclz::无权录音(跨域,请尝试给iframe添加麦克风访问策略,如{1})",0,'allow="camera;microphone"'));
|
|
1280
|
+
return;
|
|
1281
|
+
};
|
|
1282
|
+
|
|
1283
|
+
if(codeErr1(1,code)){
|
|
1284
|
+
if(/Found/i.test(code)){//可能是非安全环境导致的没有设备
|
|
1285
|
+
failCall(msg+$T("jBa9::,无可用麦克风"));
|
|
1286
|
+
}else{
|
|
1287
|
+
failCall(msg);
|
|
1288
|
+
};
|
|
1289
|
+
};
|
|
1290
|
+
};
|
|
1291
|
+
var codeErr1=function(call,code){ //排除几个明确原因的错误
|
|
1292
|
+
if(/Permission|Allow/i.test(code)){
|
|
1293
|
+
if(call) failCall($T("gyO5::用户拒绝了录音权限"),true);
|
|
1294
|
+
}else if(window.isSecureContext===false){
|
|
1295
|
+
if(call) failCall($T("oWNo::浏览器禁止不安全页面录音,可开启https解决"));
|
|
1296
|
+
}else{
|
|
1297
|
+
return 1;
|
|
1298
|
+
};
|
|
1299
|
+
};
|
|
1300
|
+
|
|
1301
|
+
|
|
1302
|
+
//如果已打开并且有效就不要再打开了
|
|
1303
|
+
if(Recorder.IsOpen()){
|
|
1304
|
+
ok();
|
|
1305
|
+
return;
|
|
1306
|
+
};
|
|
1307
|
+
if(!Recorder.Support()){
|
|
1308
|
+
codeFail("",$T("COxc::此浏览器不支持录音"));
|
|
1309
|
+
return;
|
|
1310
|
+
};
|
|
1311
|
+
getCtx();
|
|
1312
|
+
|
|
1313
|
+
//请求权限,如果从未授权,一般浏览器会弹出权限请求弹框
|
|
1314
|
+
var f1=function(stream){ //请求成功回调
|
|
1315
|
+
//https://github.com/xiangyuecn/Recorder/issues/14 获取到的track.readyState!="live",刚刚回调时可能是正常的,但过一下可能就被关掉了,原因不明。延迟一下保证真异步。对正常浏览器不影响
|
|
1316
|
+
setTimeout(function(){
|
|
1317
|
+
stream._call={};
|
|
1318
|
+
var oldStream=Recorder.Stream;
|
|
1319
|
+
if(oldStream){
|
|
1320
|
+
Disconnect(); //直接断开已存在的,旧的Connect未完成会自动终止
|
|
1321
|
+
stream._call=oldStream._call;
|
|
1322
|
+
};
|
|
1323
|
+
Recorder.Stream=stream;
|
|
1324
|
+
stream._c=ctx;
|
|
1325
|
+
stream._RC=set.runningContext;
|
|
1326
|
+
if(lockFail())return;
|
|
1327
|
+
|
|
1328
|
+
if(Recorder.IsOpen()){
|
|
1329
|
+
if(oldStream)This.CLog($T("upb8::发现同时多次调用open"),1);
|
|
1330
|
+
|
|
1331
|
+
Connect(streamStore);
|
|
1332
|
+
ok(); //只连接,因为AudioContext不一定在运行,无法知道是否有数据回调
|
|
1333
|
+
}else{
|
|
1334
|
+
failCall($T("Q1GA::录音功能无效:无音频流"));
|
|
1335
|
+
};
|
|
1336
|
+
},100);
|
|
1337
|
+
};
|
|
1338
|
+
var f2=function(e){ //请求失败回调
|
|
1339
|
+
var code=e.name||e.message||e.code+":"+e;
|
|
1340
|
+
var tryMsg="";
|
|
1341
|
+
if(callUmCount==1 && codeErr1(0,code)){
|
|
1342
|
+
tryMsg=$T("KxE2::,将尝试禁用回声消除后重试");
|
|
1343
|
+
}
|
|
1344
|
+
This.CLog($T("xEQR::请求录音权限错误")+tryMsg+"|"+e,tryMsg?3:1,e);
|
|
1345
|
+
|
|
1346
|
+
if(tryMsg){//重试
|
|
1347
|
+
callUserMedia(1);
|
|
1348
|
+
}else{
|
|
1349
|
+
codeFail(code,$T("bDOG::无法录音:")+e);
|
|
1350
|
+
};
|
|
1351
|
+
};
|
|
1352
|
+
|
|
1353
|
+
var callUmCount=0;
|
|
1354
|
+
var callUserMedia=function(retry){
|
|
1355
|
+
callUmCount++;
|
|
1356
|
+
var atsTxt="audioTrackSet";
|
|
1357
|
+
var t_AGC="autoGainControl",t_AEC="echoCancellation",t_ANS="noiseSuppression";
|
|
1358
|
+
var atsTxtJs=atsTxt+":{"+t_AEC+","+t_ANS+","+t_AGC+"}";
|
|
1359
|
+
var trackSet=JSON.parse(ToJson(set[atsTxt]||true)); //true 跟 {} 兼容性?
|
|
1360
|
+
This.CLog("open... "+callUmCount+" "+atsTxt+":"+ToJson(trackSet));
|
|
1361
|
+
|
|
1362
|
+
if(retry){ //回声消除有些浏览器可能导致无法打开录音,尝试明确禁用来保证能最基础的录
|
|
1363
|
+
if(typeof(trackSet)!="object")trackSet={}; //默认true
|
|
1364
|
+
trackSet[t_AGC]=false;
|
|
1365
|
+
trackSet[t_AEC]=false;
|
|
1366
|
+
trackSet[t_ANS]=false;
|
|
1367
|
+
};
|
|
1368
|
+
//这里指明采样率,虽然可以解决手机上MediaRecorder采样率16k的问题,是回声消除导致的只能获取到16k的流,禁用回声消除可恢复48k。(issues#230)而且会导致乱用音频输入设备,MediaStreamTrack的applyConstraints也无法修改采样率
|
|
1369
|
+
//trackSet[sampleRateTxt]=ctx[sampleRateTxt];
|
|
1370
|
+
if(trackSet[sampleRateTxt]){
|
|
1371
|
+
This.CLog($T("IjL3::注意:已配置{1}参数,可能会出现浏览器不能正确选用麦克风、移动端无法启用回声消除等现象",0,atsTxt+"."+sampleRateTxt),3);
|
|
1372
|
+
};
|
|
1373
|
+
|
|
1374
|
+
var mSet={audio:trackSet, video:set.videoTrackSet||false};
|
|
1375
|
+
try{
|
|
1376
|
+
var pro=Recorder.Scope[getUserMediaTxt](mSet,f1,f2);
|
|
1377
|
+
}catch(e){//不能设置trackSet就算了
|
|
1378
|
+
This.CLog(getUserMediaTxt,3,e);
|
|
1379
|
+
mSet={audio:true, video:false};
|
|
1380
|
+
pro=Recorder.Scope[getUserMediaTxt](mSet,f1,f2);
|
|
1381
|
+
};
|
|
1382
|
+
This.CLog(getUserMediaTxt+"("+ToJson(mSet)+") "+CtxState(ctx)
|
|
1383
|
+
+$T("RiWe::,未配置 {1} 时浏览器可能会自动启用回声消除,移动端未禁用回声消除时可能会降低系统播放音量(关闭录音后可恢复)和仅提供16k采样率的音频流(不需要回声消除时可明确配置成禁用来获得48k高音质的流),请参阅文档中{2}配置",0,atsTxtJs,atsTxt)
|
|
1384
|
+
+"("+GitUrl+") LM:"+LM+" UA:"+navigator.userAgent);
|
|
1385
|
+
if(pro&&pro.then){
|
|
1386
|
+
pro.then(f1)[CatchTxt](f2); //fix 关键字,保证catch压缩时保持字符串形式
|
|
1387
|
+
};
|
|
1388
|
+
};
|
|
1389
|
+
callUserMedia();
|
|
1390
|
+
}
|
|
1391
|
+
//关闭释放录音资源
|
|
1392
|
+
,close:function(call){
|
|
1393
|
+
call=call||NOOP;
|
|
1394
|
+
|
|
1395
|
+
var This=this,streamStore=This._streamStore();
|
|
1396
|
+
This._stop();
|
|
1397
|
+
var sTag=" stream:"+This._streamTag;
|
|
1398
|
+
|
|
1399
|
+
var Lock=streamStore.Sync;
|
|
1400
|
+
This._O=0;
|
|
1401
|
+
if(This._O_!=Lock.O){
|
|
1402
|
+
//唯一资源Stream的控制权已交给新对象,这里不能关闭。此处在每次都弹权限的浏览器内可能存在泄漏,新对象被拒绝权限可能不会调用close,忽略这种不处理
|
|
1403
|
+
This.CLog($T("hWVz::close被忽略(因为同时open了多个rec,只有最后一个会真正close)")+sTag,3);
|
|
1404
|
+
call();
|
|
1405
|
+
return;
|
|
1406
|
+
};
|
|
1407
|
+
Lock.C++;//获得控制权
|
|
1408
|
+
|
|
1409
|
+
Disconnect(streamStore);
|
|
1410
|
+
|
|
1411
|
+
This.CLog("close,"+sTag);
|
|
1412
|
+
call();
|
|
1413
|
+
}
|
|
1414
|
+
|
|
1415
|
+
|
|
1416
|
+
|
|
1417
|
+
|
|
1418
|
+
|
|
1419
|
+
/*模拟一段录音数据,后面可以调用stop进行编码,需提供pcm数据[1,2,3...],pcm的采样率*/
|
|
1420
|
+
,mock:function(pcmData,pcmSampleRate){
|
|
1421
|
+
var This=this;
|
|
1422
|
+
This._stop();//清理掉已有的资源
|
|
1423
|
+
|
|
1424
|
+
This.isMock=1;
|
|
1425
|
+
This.mockEnvInfo=null;
|
|
1426
|
+
This.buffers=[pcmData];
|
|
1427
|
+
This.recSize=pcmData.length;
|
|
1428
|
+
This._setSrcSR(pcmSampleRate);
|
|
1429
|
+
This._streamTag="mock";
|
|
1430
|
+
return This;
|
|
1431
|
+
}
|
|
1432
|
+
,_setSrcSR:function(sampleRate){
|
|
1433
|
+
var This=this,set=This.set;
|
|
1434
|
+
var setSr=set[sampleRateTxt];
|
|
1435
|
+
if(setSr>sampleRate){
|
|
1436
|
+
set[sampleRateTxt]=sampleRate;
|
|
1437
|
+
}else{ setSr=0 }
|
|
1438
|
+
This[srcSampleRateTxt]=sampleRate;
|
|
1439
|
+
This.CLog(srcSampleRateTxt+": "+sampleRate+" set."+sampleRateTxt+": "+set[sampleRateTxt]+(setSr?" "+$T("UHvm::忽略")+": "+setSr:""), setSr?3:0);
|
|
1440
|
+
}
|
|
1441
|
+
,envCheck:function(envInfo){//平台环境下的可用性检查,任何时候都可以调用检查,返回errMsg:""正常,"失败原因"
|
|
1442
|
+
//envInfo={envName:"H5",canProcess:true}
|
|
1443
|
+
var errMsg,This=this,set=This.set;
|
|
1444
|
+
|
|
1445
|
+
//检测CPU的数字字节序,TypedArray字节序是个迷,直接拒绝罕见的大端模式,因为找不到这种CPU进行测试
|
|
1446
|
+
var tag="CPU_BE";
|
|
1447
|
+
if(!errMsg && !Recorder[tag] && typeof Int8Array=="function" && !new Int8Array(new Int32Array([1]).buffer)[0]){
|
|
1448
|
+
Traffic(tag); //如果开启了流量统计,这里将发送一个图片请求
|
|
1449
|
+
errMsg=$T("Essp::不支持{1}架构",0,tag);
|
|
1450
|
+
};
|
|
1451
|
+
|
|
1452
|
+
//编码器检查环境下配置是否可用
|
|
1453
|
+
if(!errMsg){
|
|
1454
|
+
var type=set.type,hasFn=This[type+"_envCheck"];
|
|
1455
|
+
if(set.takeoffEncodeChunk){//需要实时编码返回数据,此时需要检查环境是否有实时特性、和是否可实时编码
|
|
1456
|
+
if(!hasFn){
|
|
1457
|
+
errMsg=$T("2XBl::{1}类型不支持设置takeoffEncodeChunk",0,type)+(This[type]?"":$T("LG7e::(未加载编码器)"));
|
|
1458
|
+
}else if(!envInfo.canProcess){
|
|
1459
|
+
errMsg=$T("7uMV::{1}环境不支持实时处理",0,envInfo.envName);
|
|
1460
|
+
};
|
|
1461
|
+
};
|
|
1462
|
+
|
|
1463
|
+
if(!errMsg && hasFn){//编码器已实现环境检查
|
|
1464
|
+
errMsg=This[type+"_envCheck"](envInfo,set);
|
|
1465
|
+
};
|
|
1466
|
+
};
|
|
1467
|
+
|
|
1468
|
+
return errMsg||"";
|
|
1469
|
+
}
|
|
1470
|
+
,envStart:function(mockEnvInfo,sampleRate){//平台环境相关的start调用
|
|
1471
|
+
var This=this,set=This.set;
|
|
1472
|
+
This.isMock=mockEnvInfo?1:0;//非H5环境需要启用mock,并提供envCheck需要的环境信息
|
|
1473
|
+
This.mockEnvInfo=mockEnvInfo;
|
|
1474
|
+
This.buffers=[];//数据缓冲
|
|
1475
|
+
This.recSize=0;//数据大小
|
|
1476
|
+
if(mockEnvInfo){
|
|
1477
|
+
This._streamTag="env$"+mockEnvInfo.envName;
|
|
1478
|
+
};
|
|
1479
|
+
|
|
1480
|
+
This.state=1;//运行状态,0未录音 1录音中 2暂停 3等待ctx激活
|
|
1481
|
+
This.envInLast=0;//envIn接收到最后录音内容的时间
|
|
1482
|
+
This.envInFirst=0;//envIn接收到的首个录音内容的录制时间
|
|
1483
|
+
This.envInFix=0;//补偿的总时间
|
|
1484
|
+
This.envInFixTs=[];//补偿计数列表
|
|
1485
|
+
|
|
1486
|
+
//engineCtx需要提前确定最终的采样率
|
|
1487
|
+
This._setSrcSR(sampleRate);
|
|
1488
|
+
|
|
1489
|
+
This.engineCtx=0;
|
|
1490
|
+
//此类型有边录边转码(Worker)支持
|
|
1491
|
+
if(This[set.type+"_start"]){
|
|
1492
|
+
var engineCtx=This.engineCtx=This[set.type+"_start"](set);
|
|
1493
|
+
if(engineCtx){
|
|
1494
|
+
engineCtx.pcmDatas=[];
|
|
1495
|
+
engineCtx.pcmSize=0;
|
|
1496
|
+
};
|
|
1497
|
+
};
|
|
1498
|
+
}
|
|
1499
|
+
,envResume:function(){//和平台环境无关的恢复录音
|
|
1500
|
+
//重新开始计数
|
|
1501
|
+
this.envInFixTs=[];
|
|
1502
|
+
}
|
|
1503
|
+
,envIn:function(pcm,sum){//和平台环境无关的pcm[Int16]输入
|
|
1504
|
+
var This=this,set=This.set,engineCtx=This.engineCtx;
|
|
1505
|
+
if(This.state!=1){
|
|
1506
|
+
if(!This.state)This.CLog("envIn at state=0",3);
|
|
1507
|
+
return;
|
|
1508
|
+
};
|
|
1509
|
+
var bufferSampleRate=This[srcSampleRateTxt];
|
|
1510
|
+
var size=pcm.length;
|
|
1511
|
+
var powerLevel=Recorder.PowerLevel(sum,size);
|
|
1512
|
+
|
|
1513
|
+
var buffers=This.buffers;
|
|
1514
|
+
var bufferFirstIdx=buffers.length;//之前的buffer都是经过onProcess处理好的,不允许再修改
|
|
1515
|
+
buffers.push(pcm);
|
|
1516
|
+
|
|
1517
|
+
//有engineCtx时会被覆盖,这里保存一份
|
|
1518
|
+
var buffersThis=buffers;
|
|
1519
|
+
var bufferFirstIdxThis=bufferFirstIdx;
|
|
1520
|
+
|
|
1521
|
+
//卡顿丢失补偿:因为设备很卡的时候导致H5接收到的数据量不够造成播放时候变速,结果比实际的时长要短,此处保证了不会变短,但不能修复丢失的音频数据造成音质变差。当前算法采用输入时间侦测下一帧是否需要添加补偿帧,需要(6次输入||超过1秒)以上才会开始侦测,如果滑动窗口内丢失超过1/3就会进行补偿
|
|
1522
|
+
var now=Date.now();
|
|
1523
|
+
var pcmTime=Math.round(size/bufferSampleRate*1000);
|
|
1524
|
+
This.envInLast=now;
|
|
1525
|
+
if(This.buffers.length==1){//记下首个录音数据的录制时间
|
|
1526
|
+
This.envInFirst=now-pcmTime;
|
|
1527
|
+
};
|
|
1528
|
+
var envInFixTs=This.envInFixTs;
|
|
1529
|
+
envInFixTs.splice(0,0,{t:now,d:pcmTime});
|
|
1530
|
+
//保留3秒的计数滑动窗口,另外超过3秒的停顿不补偿
|
|
1531
|
+
var tsInStart=now,tsPcm=0;
|
|
1532
|
+
for(var i=0;i<envInFixTs.length;i++){
|
|
1533
|
+
var o=envInFixTs[i];
|
|
1534
|
+
if(now-o.t>3000){
|
|
1535
|
+
envInFixTs.length=i;
|
|
1536
|
+
break;
|
|
1537
|
+
};
|
|
1538
|
+
tsInStart=o.t;
|
|
1539
|
+
tsPcm+=o.d;
|
|
1540
|
+
};
|
|
1541
|
+
//达到需要的数据量,开始侦测是否需要补偿
|
|
1542
|
+
var tsInPrev=envInFixTs[1];
|
|
1543
|
+
var tsIn=now-tsInStart;
|
|
1544
|
+
var lost=tsIn-tsPcm;
|
|
1545
|
+
if( lost>tsIn/3 && (tsInPrev&&tsIn>1000 || envInFixTs.length>=6) ){
|
|
1546
|
+
//丢失过多,开始执行补偿
|
|
1547
|
+
var addTime=now-tsInPrev.t-pcmTime;//距离上次输入丢失这么多ms
|
|
1548
|
+
if(addTime>pcmTime/5){//丢失超过本帧的1/5
|
|
1549
|
+
var fixOpen=!set.disableEnvInFix;
|
|
1550
|
+
This.CLog("["+now+"]"+i18n.get(fixOpen?$T("4Kfd::补偿{1}ms",1):$T("bM5i::未补偿{1}ms",1),[addTime]),3);
|
|
1551
|
+
This.envInFix+=addTime;
|
|
1552
|
+
|
|
1553
|
+
//用静默进行补偿
|
|
1554
|
+
if(fixOpen){
|
|
1555
|
+
var addPcm=new Int16Array(addTime*bufferSampleRate/1000);
|
|
1556
|
+
size+=addPcm.length;
|
|
1557
|
+
buffers.push(addPcm);
|
|
1558
|
+
};
|
|
1559
|
+
};
|
|
1560
|
+
};
|
|
1561
|
+
|
|
1562
|
+
|
|
1563
|
+
var sizeOld=This.recSize,addSize=size;
|
|
1564
|
+
var bufferSize=sizeOld+addSize;
|
|
1565
|
+
This.recSize=bufferSize;//此值在onProcess后需要修正,可能新数据被修改
|
|
1566
|
+
|
|
1567
|
+
|
|
1568
|
+
//此类型有边录边转码(Worker)支持,开启实时转码
|
|
1569
|
+
if(engineCtx){
|
|
1570
|
+
//转换成set的采样率
|
|
1571
|
+
var chunkInfo=Recorder.SampleData(buffers,bufferSampleRate,set[sampleRateTxt],engineCtx.chunkInfo);
|
|
1572
|
+
engineCtx.chunkInfo=chunkInfo;
|
|
1573
|
+
|
|
1574
|
+
sizeOld=engineCtx.pcmSize;
|
|
1575
|
+
addSize=chunkInfo.data.length;
|
|
1576
|
+
bufferSize=sizeOld+addSize;
|
|
1577
|
+
engineCtx.pcmSize=bufferSize;//此值在onProcess后需要修正,可能新数据被修改
|
|
1578
|
+
|
|
1579
|
+
buffers=engineCtx.pcmDatas;
|
|
1580
|
+
bufferFirstIdx=buffers.length;
|
|
1581
|
+
buffers.push(chunkInfo.data);
|
|
1582
|
+
bufferSampleRate=chunkInfo[sampleRateTxt];
|
|
1583
|
+
};
|
|
1584
|
+
|
|
1585
|
+
var duration=Math.round(bufferSize/bufferSampleRate*1000);
|
|
1586
|
+
var bufferNextIdx=buffers.length;
|
|
1587
|
+
var bufferNextIdxThis=buffersThis.length;
|
|
1588
|
+
|
|
1589
|
+
//允许异步处理buffer数据
|
|
1590
|
+
var asyncEnd=function(){
|
|
1591
|
+
//重新计算size,异步的早已减去添加的,同步的需去掉本次添加的然后重新计算
|
|
1592
|
+
var num=asyncBegin?0:-addSize;
|
|
1593
|
+
var hasClear=buffers[0]==null;
|
|
1594
|
+
for(var i=bufferFirstIdx;i<bufferNextIdx;i++){
|
|
1595
|
+
var buffer=buffers[i];
|
|
1596
|
+
if(buffer==null){//已被主动释放内存,比如长时间实时传输录音时
|
|
1597
|
+
hasClear=1;
|
|
1598
|
+
}else{
|
|
1599
|
+
num+=buffer.length;
|
|
1600
|
+
|
|
1601
|
+
//推入后台边录边转码
|
|
1602
|
+
if(engineCtx&&buffer.length){
|
|
1603
|
+
This[set.type+"_encode"](engineCtx,buffer);
|
|
1604
|
+
};
|
|
1605
|
+
};
|
|
1606
|
+
};
|
|
1607
|
+
|
|
1608
|
+
//同步清理This.buffers,不管buffers到底清了多少个,buffersThis是使用不到的进行全清
|
|
1609
|
+
if(hasClear && engineCtx){
|
|
1610
|
+
var i=bufferFirstIdxThis;
|
|
1611
|
+
if(buffersThis[0]){
|
|
1612
|
+
i=0;
|
|
1613
|
+
};
|
|
1614
|
+
for(;i<bufferNextIdxThis;i++){
|
|
1615
|
+
buffersThis[i]=null;
|
|
1616
|
+
};
|
|
1617
|
+
};
|
|
1618
|
+
|
|
1619
|
+
//统计修改后的size,如果异步发生clear要原样加回来,同步的无需操作
|
|
1620
|
+
if(hasClear){
|
|
1621
|
+
num=asyncBegin?addSize:0;
|
|
1622
|
+
|
|
1623
|
+
buffers[0]=null;//彻底被清理
|
|
1624
|
+
};
|
|
1625
|
+
if(engineCtx){
|
|
1626
|
+
engineCtx.pcmSize+=num;
|
|
1627
|
+
}else{
|
|
1628
|
+
This.recSize+=num;
|
|
1629
|
+
};
|
|
1630
|
+
};
|
|
1631
|
+
//实时回调处理数据,允许修改或替换上次回调以来新增的数据 ,但是不允许修改已处理过的,不允许增删第一维数组 ,允许将第二维数组任意修改替换成空数组也可以
|
|
1632
|
+
var asyncBegin=0,procTxt="rec.set.onProcess";
|
|
1633
|
+
try{
|
|
1634
|
+
asyncBegin=set.onProcess(buffers,powerLevel,duration,bufferSampleRate,bufferFirstIdx,asyncEnd);
|
|
1635
|
+
}catch(e){
|
|
1636
|
+
//此错误显示不要用CLog,这样控制台内相同内容不会重复打印
|
|
1637
|
+
console.error(procTxt+$T("gFUF::回调出错是不允许的,需保证不会抛异常"),e);
|
|
1638
|
+
};
|
|
1639
|
+
|
|
1640
|
+
var slowT=Date.now()-now;
|
|
1641
|
+
if(slowT>10 && This.envInFirst-now>1000){ //1秒后开始onProcess性能监测
|
|
1642
|
+
This.CLog(procTxt+$T("2ghS::低性能,耗时{1}ms",0,slowT),3);
|
|
1643
|
+
};
|
|
1644
|
+
|
|
1645
|
+
if(asyncBegin===true){
|
|
1646
|
+
//开启了异步模式,onProcess已接管buffers新数据,立即清空,避免出现未处理的数据
|
|
1647
|
+
var hasClear=0;
|
|
1648
|
+
for(var i=bufferFirstIdx;i<bufferNextIdx;i++){
|
|
1649
|
+
if(buffers[i]==null){//已被主动释放内存,比如长时间实时传输录音时 ,但又要开启异步模式,此种情况是非法的
|
|
1650
|
+
hasClear=1;
|
|
1651
|
+
}else{
|
|
1652
|
+
buffers[i]=new Int16Array(0);
|
|
1653
|
+
};
|
|
1654
|
+
};
|
|
1655
|
+
|
|
1656
|
+
if(hasClear){
|
|
1657
|
+
This.CLog($T("ufqH::未进入异步前不能清除buffers"),3);
|
|
1658
|
+
}else{
|
|
1659
|
+
//还原size,异步结束后再统计仅修改后的size,如果发生clear要原样加回来
|
|
1660
|
+
if(engineCtx){
|
|
1661
|
+
engineCtx.pcmSize-=addSize;
|
|
1662
|
+
}else{
|
|
1663
|
+
This.recSize-=addSize;
|
|
1664
|
+
};
|
|
1665
|
+
};
|
|
1666
|
+
}else{
|
|
1667
|
+
asyncEnd();
|
|
1668
|
+
};
|
|
1669
|
+
}
|
|
1670
|
+
|
|
1671
|
+
|
|
1672
|
+
|
|
1673
|
+
|
|
1674
|
+
//开始录音,需先调用open;只要open成功时,调用此方法是安全的,如果未open强行调用导致的内部错误将不会有任何提示,stop时自然能得到错误;注意:open和start至少有一个应当在用户操作(触摸、点击等)下进行调用,原因参考runningContext配置
|
|
1675
|
+
,start:function(){
|
|
1676
|
+
var This=this;
|
|
1677
|
+
|
|
1678
|
+
var isOpen=1;
|
|
1679
|
+
if(This.set.sourceStream){//直接提供了流,仅判断是否调用了open
|
|
1680
|
+
if(!This.Stream){
|
|
1681
|
+
isOpen=0;
|
|
1682
|
+
}
|
|
1683
|
+
}else if(!Recorder.IsOpen()){//监测全局麦克风是否打开并且有效
|
|
1684
|
+
isOpen=0;
|
|
1685
|
+
};
|
|
1686
|
+
if(!isOpen){
|
|
1687
|
+
This.CLog($T("6WmN::start失败:未open"),1);
|
|
1688
|
+
return;
|
|
1689
|
+
};
|
|
1690
|
+
var ctx=This._streamCtx();
|
|
1691
|
+
This.CLog($T("kLDN::start 开始录音,")+CtxState(ctx)+" stream:"+This._streamTag);
|
|
1692
|
+
|
|
1693
|
+
This._stop();
|
|
1694
|
+
This.envStart(null, ctx[sampleRateTxt]);
|
|
1695
|
+
This.state=3;//0未录音 1录音中 2暂停 3等待ctx激活
|
|
1696
|
+
|
|
1697
|
+
//检查open过程中stop是否已经调用过
|
|
1698
|
+
if(This._SO&&This._SO+1!=This._S){//上面调用过一次 _stop
|
|
1699
|
+
//open未完成就调用了stop,此种情况终止start。也应尽量避免出现此情况
|
|
1700
|
+
This.CLog($T("Bp2y::start被中断"),3);
|
|
1701
|
+
return;
|
|
1702
|
+
};
|
|
1703
|
+
This._SO=0;
|
|
1704
|
+
|
|
1705
|
+
var end=function(){
|
|
1706
|
+
if(This.state==3){
|
|
1707
|
+
This.state=1;
|
|
1708
|
+
This.resume();
|
|
1709
|
+
}
|
|
1710
|
+
};
|
|
1711
|
+
var tag="AudioContext resume: ";
|
|
1712
|
+
|
|
1713
|
+
//如果有数据回调,就不等待ctx resume
|
|
1714
|
+
var stream=This._streamGet();
|
|
1715
|
+
stream._call[This.id]=function(){
|
|
1716
|
+
This.CLog(tag+ctx.state+'|stream ok');
|
|
1717
|
+
end();
|
|
1718
|
+
};
|
|
1719
|
+
ResumeCtx(ctx,function(runC){
|
|
1720
|
+
runC&&This.CLog(tag+"wait...");
|
|
1721
|
+
return This.state==3;
|
|
1722
|
+
},function(runC){
|
|
1723
|
+
runC&&This.CLog(tag+ctx.state);
|
|
1724
|
+
end();
|
|
1725
|
+
},function(err){ //比较少见,可能对录音没有影响
|
|
1726
|
+
This.CLog(tag+ctx.state+$T("upkE::,可能无法录音:")+err,1);
|
|
1727
|
+
end();
|
|
1728
|
+
});
|
|
1729
|
+
}
|
|
1730
|
+
|
|
1731
|
+
|
|
1732
|
+
|
|
1733
|
+
/*暂停录音*/
|
|
1734
|
+
,pause:function(){
|
|
1735
|
+
var This=this,stream=This._streamGet();
|
|
1736
|
+
if(This.state){
|
|
1737
|
+
This.state=2;
|
|
1738
|
+
This.CLog("pause");
|
|
1739
|
+
if(stream) delete stream._call[This.id];
|
|
1740
|
+
};
|
|
1741
|
+
}
|
|
1742
|
+
/*恢复录音*/
|
|
1743
|
+
,resume:function(){
|
|
1744
|
+
var This=this,stream=This._streamGet();
|
|
1745
|
+
var tag="resume",tag3=tag+"(wait ctx)";
|
|
1746
|
+
if(This.state==3){ //start还在等ctx恢复
|
|
1747
|
+
This.CLog(tag3);
|
|
1748
|
+
}else if(This.state){
|
|
1749
|
+
This.state=1;
|
|
1750
|
+
This.CLog(tag);
|
|
1751
|
+
This.envResume();
|
|
1752
|
+
|
|
1753
|
+
if(stream){
|
|
1754
|
+
stream._call[This.id]=function(pcm,sum){
|
|
1755
|
+
if(This.state==1){
|
|
1756
|
+
This.envIn(pcm,sum);
|
|
1757
|
+
};
|
|
1758
|
+
};
|
|
1759
|
+
ConnAlive(stream);//AudioWorklet只会在ctx激活后运行
|
|
1760
|
+
};
|
|
1761
|
+
|
|
1762
|
+
var ctx=This._streamCtx();
|
|
1763
|
+
if(ctx){ //AudioContext如果被暂停,尽量恢复
|
|
1764
|
+
ResumeCtx(ctx,function(runC){
|
|
1765
|
+
runC&&This.CLog(tag3+"...");
|
|
1766
|
+
return This.state==1;
|
|
1767
|
+
},function(runC){
|
|
1768
|
+
runC&&This.CLog(tag3+ctx.state);
|
|
1769
|
+
ConnAlive(stream);
|
|
1770
|
+
},function(err){
|
|
1771
|
+
This.CLog(tag3+ctx.state+"[err]"+err,1);
|
|
1772
|
+
});
|
|
1773
|
+
};
|
|
1774
|
+
};
|
|
1775
|
+
}
|
|
1776
|
+
|
|
1777
|
+
|
|
1778
|
+
|
|
1779
|
+
|
|
1780
|
+
,_stop:function(keepEngine){
|
|
1781
|
+
var This=this,set=This.set;
|
|
1782
|
+
if(!This.isMock){
|
|
1783
|
+
This._S++;
|
|
1784
|
+
};
|
|
1785
|
+
if(This.state){
|
|
1786
|
+
This.pause();
|
|
1787
|
+
This.state=0;
|
|
1788
|
+
};
|
|
1789
|
+
if(!keepEngine && This[set.type+"_stop"]){
|
|
1790
|
+
This[set.type+"_stop"](This.engineCtx);
|
|
1791
|
+
This.engineCtx=0;
|
|
1792
|
+
};
|
|
1793
|
+
}
|
|
1794
|
+
/*
|
|
1795
|
+
结束录音并返回录音数据blob对象
|
|
1796
|
+
True(blob,duration,mime)
|
|
1797
|
+
blob:录音数据audio/mp3|wav格式;默认是Blob对象,可设置rec.dataType="arraybuffer"改成ArrayBuffer
|
|
1798
|
+
duration:录音时长,单位毫秒
|
|
1799
|
+
mime:"auido/mp3" blob数据的类型,方便ArrayBuffer时区分类型
|
|
1800
|
+
False(msg)
|
|
1801
|
+
autoClose:false 可选,是否自动调用close,默认为false
|
|
1802
|
+
*/
|
|
1803
|
+
,stop:function(True,False,autoClose){
|
|
1804
|
+
var This=this,set=This.set,t1;
|
|
1805
|
+
var envInMS=This.envInLast-This.envInFirst, envInLen=envInMS&&This.buffers.length; //可能未start
|
|
1806
|
+
This.CLog($T("Xq4s::stop 和start时差:")
|
|
1807
|
+
+(envInMS?envInMS+"ms "+$T("3CQP::补偿:")+This.envInFix+"ms"
|
|
1808
|
+
+" envIn:"+envInLen+" fps:"+(envInLen/envInMS*1000).toFixed(1)
|
|
1809
|
+
:"-")+" stream:"+This._streamTag+" ("+GitUrl+") LM:"+LM);
|
|
1810
|
+
|
|
1811
|
+
var end=function(){
|
|
1812
|
+
This._stop();//彻底关掉engineCtx
|
|
1813
|
+
if(autoClose){
|
|
1814
|
+
This.close();
|
|
1815
|
+
};
|
|
1816
|
+
};
|
|
1817
|
+
var err=function(msg){
|
|
1818
|
+
This.CLog($T("u8JG::结束录音失败:")+msg,1);
|
|
1819
|
+
False&&False(msg);
|
|
1820
|
+
end();
|
|
1821
|
+
};
|
|
1822
|
+
var ok=function(blob,mime,duration){
|
|
1823
|
+
var tBlob="blob",tABuf="arraybuffer",tDT="dataType",tDDT="DefaultDataType";
|
|
1824
|
+
var dType=This[tDT]||Recorder[tDDT]||tBlob,dTag=tDT+"="+dType;
|
|
1825
|
+
var isAB=blob instanceof ArrayBuffer,dErr=0;
|
|
1826
|
+
var dLen=isAB?blob.byteLength:blob.size;
|
|
1827
|
+
if(dType==tABuf){
|
|
1828
|
+
if(!isAB) dErr=1;
|
|
1829
|
+
}else if(dType==tBlob){
|
|
1830
|
+
if(typeof Blob!="function"){
|
|
1831
|
+
dErr=$T.G("NonBrowser-1",[dTag])+$T("1skY::,请设置{1}",0,RecTxt+"."+tDDT+'="'+tABuf+'"');
|
|
1832
|
+
}else{
|
|
1833
|
+
if(isAB) blob=new Blob([blob],{type:mime});
|
|
1834
|
+
if(!(blob instanceof Blob)) dErr=1;
|
|
1835
|
+
mime=blob.type||mime;
|
|
1836
|
+
}
|
|
1837
|
+
}else{
|
|
1838
|
+
dErr=$T.G("NotSupport-1",[dTag]);
|
|
1839
|
+
};
|
|
1840
|
+
|
|
1841
|
+
This.CLog($T("Wv7l::结束录音 编码花{1}ms 音频时长{2}ms 文件大小{3}b",0,Date.now()-t1,duration,dLen)+" "+dTag+","+mime);
|
|
1842
|
+
if(dErr){
|
|
1843
|
+
err(dErr!=1?dErr:$T("Vkbd::{1}编码器返回的不是{2}",0,set.type,dType)+", "+dTag);
|
|
1844
|
+
return;
|
|
1845
|
+
};
|
|
1846
|
+
if(set.takeoffEncodeChunk){//接管了输出,此时blob长度为0
|
|
1847
|
+
This.CLog($T("QWnr::启用takeoffEncodeChunk后stop返回的blob长度为0不提供音频数据"),3);
|
|
1848
|
+
}else if(dLen<Math.max(50,duration/5)){//1秒小于0.2k?
|
|
1849
|
+
err($T("Sz2H::生成的{1}无效",0,set.type));
|
|
1850
|
+
return;
|
|
1851
|
+
};
|
|
1852
|
+
|
|
1853
|
+
True&&True(blob,duration,mime);
|
|
1854
|
+
end();
|
|
1855
|
+
};
|
|
1856
|
+
if(!This.isMock){
|
|
1857
|
+
var isCtxWait=This.state==3;
|
|
1858
|
+
if(!This.state || isCtxWait){
|
|
1859
|
+
err($T("wf9t::未开始录音")+(isCtxWait?$T("Dl2c::,开始录音前无用户交互导致AudioContext未运行"):""));
|
|
1860
|
+
return;
|
|
1861
|
+
};
|
|
1862
|
+
};
|
|
1863
|
+
This._stop(true); //将录音状态改成未录音
|
|
1864
|
+
var size=This.recSize;
|
|
1865
|
+
if(!size){
|
|
1866
|
+
err($T("Ltz3::未采集到录音"));
|
|
1867
|
+
return;
|
|
1868
|
+
};
|
|
1869
|
+
if(!This[set.type]){
|
|
1870
|
+
err($T("xGuI::未加载{1}编码器,请尝试到{2}的src/engine内找到{1}的编码器并加载",0,set.type,RecTxt));
|
|
1871
|
+
return;
|
|
1872
|
+
};
|
|
1873
|
+
|
|
1874
|
+
//环境配置检查,此处仅针对mock调用,因为open已经检查过了
|
|
1875
|
+
if(This.isMock){
|
|
1876
|
+
var checkMsg=This.envCheck(This.mockEnvInfo||{envName:"mock",canProcess:false});//没有提供环境信息的mock时没有onProcess回调
|
|
1877
|
+
if(checkMsg){
|
|
1878
|
+
err($T("AxOH::录音错误:")+checkMsg);
|
|
1879
|
+
return;
|
|
1880
|
+
};
|
|
1881
|
+
};
|
|
1882
|
+
|
|
1883
|
+
//此类型有边录边转码(Worker)支持
|
|
1884
|
+
var engineCtx=This.engineCtx;
|
|
1885
|
+
if(This[set.type+"_complete"]&&engineCtx){
|
|
1886
|
+
var duration=Math.round(engineCtx.pcmSize/set[sampleRateTxt]*1000);//采用后的数据长度和buffers的长度可能微小的不一致,是采样率连续转换的精度问题
|
|
1887
|
+
|
|
1888
|
+
t1=Date.now();
|
|
1889
|
+
This[set.type+"_complete"](engineCtx,function(blob,mime){
|
|
1890
|
+
ok(blob,mime,duration);
|
|
1891
|
+
},err);
|
|
1892
|
+
return;
|
|
1893
|
+
};
|
|
1894
|
+
|
|
1895
|
+
//标准UI线程转码,调整采样率
|
|
1896
|
+
t1=Date.now();
|
|
1897
|
+
if(!This.buffers[0]){
|
|
1898
|
+
err($T("xkKd::音频buffers被释放"));
|
|
1899
|
+
return;
|
|
1900
|
+
};
|
|
1901
|
+
var chunk=Recorder.SampleData(This.buffers,This[srcSampleRateTxt],set[sampleRateTxt]);
|
|
1902
|
+
|
|
1903
|
+
set[sampleRateTxt]=chunk[sampleRateTxt];
|
|
1904
|
+
var res=chunk.data;
|
|
1905
|
+
var duration=Math.round(res.length/set[sampleRateTxt]*1000);
|
|
1906
|
+
|
|
1907
|
+
This.CLog($T("CxeT::采样:{1} 花:{2}ms",0,size+"->"+res.length,Date.now()-t1));
|
|
1908
|
+
|
|
1909
|
+
setTimeout(function(){
|
|
1910
|
+
t1=Date.now();
|
|
1911
|
+
This[set.type](res,function(blob,mime){
|
|
1912
|
+
ok(blob,mime,duration);
|
|
1913
|
+
},function(msg){
|
|
1914
|
+
err(msg);
|
|
1915
|
+
});
|
|
1916
|
+
});
|
|
1917
|
+
}
|
|
1918
|
+
|
|
1919
|
+
};
|
|
34
1920
|
|
|
35
|
-
module.exports = __webpack_require__(5425);
|
|
36
1921
|
|
|
37
1922
|
|
|
1923
|
+
|
|
1924
|
+
|
|
1925
|
+
//=======从WebM字节流中提取pcm数据,提取成功返回Float32Array,失败返回null||-1=====
|
|
1926
|
+
var WebM_Extract=function(inBytes, scope){
|
|
1927
|
+
if(!scope.pos){
|
|
1928
|
+
scope.pos=[0]; scope.tracks={}; scope.bytes=[];
|
|
1929
|
+
};
|
|
1930
|
+
var tracks=scope.tracks, position=[scope.pos[0]];
|
|
1931
|
+
var endPos=function(){ scope.pos[0]=position[0] };
|
|
1932
|
+
|
|
1933
|
+
var sBL=scope.bytes.length;
|
|
1934
|
+
var bytes=new Uint8Array(sBL+inBytes.length);
|
|
1935
|
+
bytes.set(scope.bytes); bytes.set(inBytes,sBL);
|
|
1936
|
+
scope.bytes=bytes;
|
|
1937
|
+
|
|
1938
|
+
//先读取文件头和Track信息
|
|
1939
|
+
if(!scope._ht){
|
|
1940
|
+
readMatroskaVInt(bytes, position);//EBML Header
|
|
1941
|
+
readMatroskaBlock(bytes, position);//跳过EBML Header内容
|
|
1942
|
+
if(!BytesEq(readMatroskaVInt(bytes, position), [0x18,0x53,0x80,0x67])){
|
|
1943
|
+
return;//未识别到Segment
|
|
1944
|
+
}
|
|
1945
|
+
readMatroskaVInt(bytes, position);//跳过Segment长度值
|
|
1946
|
+
while(position[0]<bytes.length){
|
|
1947
|
+
var eid0=readMatroskaVInt(bytes, position);
|
|
1948
|
+
var bytes0=readMatroskaBlock(bytes, position);
|
|
1949
|
+
var pos0=[0],audioIdx=0;
|
|
1950
|
+
if(!bytes0)return;//数据不全,等待缓冲
|
|
1951
|
+
//Track完整数据,循环读取TrackEntry
|
|
1952
|
+
if(BytesEq(eid0, [0x16,0x54,0xAE,0x6B])){
|
|
1953
|
+
while(pos0[0]<bytes0.length){
|
|
1954
|
+
var eid1=readMatroskaVInt(bytes0, pos0);
|
|
1955
|
+
var bytes1=readMatroskaBlock(bytes0, pos0);
|
|
1956
|
+
var pos1=[0],track={channels:0,sampleRate:0};
|
|
1957
|
+
if(BytesEq(eid1, [0xAE])){//TrackEntry
|
|
1958
|
+
while(pos1[0]<bytes1.length){
|
|
1959
|
+
var eid2=readMatroskaVInt(bytes1, pos1);
|
|
1960
|
+
var bytes2=readMatroskaBlock(bytes1, pos1);
|
|
1961
|
+
var pos2=[0];
|
|
1962
|
+
if(BytesEq(eid2, [0xD7])){//Track Number
|
|
1963
|
+
var val=BytesInt(bytes2);
|
|
1964
|
+
track.number=val;
|
|
1965
|
+
tracks[val]=track;
|
|
1966
|
+
}else if(BytesEq(eid2, [0x83])){//Track Type
|
|
1967
|
+
var val=BytesInt(bytes2);
|
|
1968
|
+
if(val==1) track.type="video";
|
|
1969
|
+
else if(val==2) {
|
|
1970
|
+
track.type="audio";
|
|
1971
|
+
if(!audioIdx) scope.track0=track;
|
|
1972
|
+
track.idx=audioIdx++;
|
|
1973
|
+
}else track.type="Type-"+val;
|
|
1974
|
+
}else if(BytesEq(eid2, [0x86])){//Track Codec
|
|
1975
|
+
var str="";
|
|
1976
|
+
for(var i=0;i<bytes2.length;i++){
|
|
1977
|
+
str+=String.fromCharCode(bytes2[i]);
|
|
1978
|
+
}
|
|
1979
|
+
track.codec=str;
|
|
1980
|
+
}else if(BytesEq(eid2, [0xE1])){
|
|
1981
|
+
while(pos2[0]<bytes2.length){//循环读取 Audio 属性
|
|
1982
|
+
var eid3=readMatroskaVInt(bytes2, pos2);
|
|
1983
|
+
var bytes3=readMatroskaBlock(bytes2, pos2);
|
|
1984
|
+
//采样率、位数、声道数
|
|
1985
|
+
if(BytesEq(eid3, [0xB5])){
|
|
1986
|
+
var val=0,arr=new Uint8Array(bytes3.reverse()).buffer;
|
|
1987
|
+
if(bytes3.length==4) val=new Float32Array(arr)[0];
|
|
1988
|
+
else if(bytes3.length==8) val=new Float64Array(arr)[0];
|
|
1989
|
+
else CLog("WebM Track !Float",1,bytes3);
|
|
1990
|
+
track[sampleRateTxt]=Math.round(val);
|
|
1991
|
+
}else if(BytesEq(eid3, [0x62,0x64])) track.bitDepth=BytesInt(bytes3);
|
|
1992
|
+
else if(BytesEq(eid3, [0x9F])) track.channels=BytesInt(bytes3);
|
|
1993
|
+
}
|
|
1994
|
+
}
|
|
1995
|
+
}
|
|
1996
|
+
}
|
|
1997
|
+
};
|
|
1998
|
+
scope._ht=1;
|
|
1999
|
+
CLog("WebM Tracks",tracks);
|
|
2000
|
+
endPos();
|
|
2001
|
+
break;
|
|
2002
|
+
}
|
|
2003
|
+
}
|
|
2004
|
+
}
|
|
2005
|
+
|
|
2006
|
+
//校验音频参数信息,如果不符合代码要求,统统拒绝处理
|
|
2007
|
+
var track0=scope.track0;
|
|
2008
|
+
if(!track0)return;
|
|
2009
|
+
var trackSR=track0[sampleRateTxt]; scope.webmSR=trackSR;
|
|
2010
|
+
if(track0.bitDepth==16 && /FLOAT/i.test(track0.codec)){
|
|
2011
|
+
track0.bitDepth=32; //chrome v66 实际为浮点数
|
|
2012
|
+
CLog("WebM 16->32 bit",3);
|
|
2013
|
+
}
|
|
2014
|
+
if(trackSR<8000 || track0.bitDepth!=32 || track0.channels<1 || !/(\b|_)PCM\b/i.test(track0.codec)){
|
|
2015
|
+
scope.bytes=[];//格式非预期 无法处理,清空缓冲数据
|
|
2016
|
+
if(!scope.bad)CLog("WebM Track Unexpected",3,scope);
|
|
2017
|
+
scope.bad=1;
|
|
2018
|
+
return -1;
|
|
2019
|
+
}
|
|
2020
|
+
|
|
2021
|
+
//循环读取Cluster内的SimpleBlock
|
|
2022
|
+
var datas=[],dataLen=0;
|
|
2023
|
+
while(position[0]<bytes.length){
|
|
2024
|
+
var eid1=readMatroskaVInt(bytes, position);
|
|
2025
|
+
var bytes1=readMatroskaBlock(bytes, position);
|
|
2026
|
+
if(!bytes1)break;//数据不全,等待缓冲
|
|
2027
|
+
if(BytesEq(eid1, [0xA3])){//SimpleBlock完整数据
|
|
2028
|
+
var trackNo=bytes1[0]&0xf;
|
|
2029
|
+
var track=tracks[trackNo];
|
|
2030
|
+
if(!track){//不可能没有,数据出错?
|
|
2031
|
+
CLog("WebM !Track"+trackNo,1,tracks);
|
|
2032
|
+
}else if(track.idx===0){
|
|
2033
|
+
var u8arr=new Uint8Array(bytes1.length-4);
|
|
2034
|
+
for(var i=4;i<bytes1.length;i++){
|
|
2035
|
+
u8arr[i-4]=bytes1[i];
|
|
2036
|
+
}
|
|
2037
|
+
datas.push(u8arr); dataLen+=u8arr.length;
|
|
2038
|
+
}
|
|
2039
|
+
}
|
|
2040
|
+
endPos();
|
|
2041
|
+
}
|
|
2042
|
+
|
|
2043
|
+
if(dataLen){
|
|
2044
|
+
var more=new Uint8Array(bytes.length-scope.pos[0]);
|
|
2045
|
+
more.set(bytes.subarray(scope.pos[0]));
|
|
2046
|
+
scope.bytes=more; //清理已读取了的缓冲数据
|
|
2047
|
+
scope.pos[0]=0;
|
|
2048
|
+
|
|
2049
|
+
var u8arr=new Uint8Array(dataLen); //已获取的音频数据
|
|
2050
|
+
for(var i=0,i2=0;i<datas.length;i++){
|
|
2051
|
+
u8arr.set(datas[i],i2);
|
|
2052
|
+
i2+=datas[i].length;
|
|
2053
|
+
}
|
|
2054
|
+
var arr=new Float32Array(u8arr.buffer);
|
|
2055
|
+
|
|
2056
|
+
if(track0.channels>1){//多声道,提取一个声道
|
|
2057
|
+
var arr2=[];
|
|
2058
|
+
for(var i=0;i<arr.length;){
|
|
2059
|
+
arr2.push(arr[i]);
|
|
2060
|
+
i+=track0.channels;
|
|
2061
|
+
}
|
|
2062
|
+
arr=new Float32Array(arr2);
|
|
2063
|
+
};
|
|
2064
|
+
return arr;
|
|
2065
|
+
}
|
|
2066
|
+
};
|
|
2067
|
+
//两个字节数组内容是否相同
|
|
2068
|
+
var BytesEq=function(bytes1,bytes2){
|
|
2069
|
+
if(!bytes1 || bytes1.length!=bytes2.length) return false;
|
|
2070
|
+
if(bytes1.length==1) return bytes1[0]==bytes2[0];
|
|
2071
|
+
for(var i=0;i<bytes1.length;i++){
|
|
2072
|
+
if(bytes1[i]!=bytes2[i]) return false;
|
|
2073
|
+
}
|
|
2074
|
+
return true;
|
|
2075
|
+
};
|
|
2076
|
+
//字节数组BE转成int数字
|
|
2077
|
+
var BytesInt=function(bytes){
|
|
2078
|
+
var s="";//0-8字节,js位运算只支持4字节
|
|
2079
|
+
for(var i=0;i<bytes.length;i++){var n=bytes[i];s+=(n<16?"0":"")+n.toString(16)};
|
|
2080
|
+
return parseInt(s,16)||0;
|
|
2081
|
+
};
|
|
2082
|
+
//读取一个可变长数值字节数组
|
|
2083
|
+
var readMatroskaVInt=function(arr,pos,trim){
|
|
2084
|
+
var i=pos[0];
|
|
2085
|
+
if(i>=arr.length)return;
|
|
2086
|
+
var b0=arr[i],b2=("0000000"+b0.toString(2)).substr(-8);
|
|
2087
|
+
var m=/^(0*1)(\d*)$/.exec(b2);
|
|
2088
|
+
if(!m)return;
|
|
2089
|
+
var len=m[1].length, val=[];
|
|
2090
|
+
if(i+len>arr.length)return;
|
|
2091
|
+
for(var i2=0;i2<len;i2++){ val[i2]=arr[i]; i++; }
|
|
2092
|
+
if(trim) val[0]=parseInt(m[2]||'0',2);
|
|
2093
|
+
pos[0]=i;
|
|
2094
|
+
return val;
|
|
2095
|
+
};
|
|
2096
|
+
//读取一个自带长度的内容字节数组
|
|
2097
|
+
var readMatroskaBlock=function(arr,pos){
|
|
2098
|
+
var lenVal=readMatroskaVInt(arr,pos,1);
|
|
2099
|
+
if(!lenVal)return;
|
|
2100
|
+
var len=BytesInt(lenVal);
|
|
2101
|
+
var i=pos[0], val=[];
|
|
2102
|
+
if(len<0x7FFFFFFF){ //超大值代表没有长度
|
|
2103
|
+
if(i+len>arr.length)return;
|
|
2104
|
+
for(var i2=0;i2<len;i2++){ val[i2]=arr[i]; i++; }
|
|
2105
|
+
}
|
|
2106
|
+
pos[0]=i;
|
|
2107
|
+
return val;
|
|
2108
|
+
};
|
|
2109
|
+
//=====End WebM读取=====
|
|
2110
|
+
|
|
2111
|
+
|
|
2112
|
+
//=====i18n 简版国际化多语言支持=====
|
|
2113
|
+
var i18n=Recorder.i18n={
|
|
2114
|
+
lang: "zh-CN" //默认中文
|
|
2115
|
+
,alias:{"zh-CN":"zh","en-US":"en"} //别名配置,映射到一个语言实例
|
|
2116
|
+
,locales:{} //语言实例:zh:{key:"text"}
|
|
2117
|
+
,data:{} //各种数据,desc$xx:语言描述,rtl$xx:文本方向是否从右到左 rtl$zh:false rtl$ar:true
|
|
2118
|
+
//添加语言文本内容,set={lang:"",overwrite:true},texts=["key:text{1}",...]
|
|
2119
|
+
,put:function(set,texts){
|
|
2120
|
+
var tag=RecTxt+".i18n.put: ";
|
|
2121
|
+
var overwrite=set.overwrite; overwrite=overwrite==null||overwrite;
|
|
2122
|
+
var lang=set.lang; lang=i18n.alias[lang]||lang;
|
|
2123
|
+
if(!lang)throw new Error(tag+"set.lang?");
|
|
2124
|
+
var locale=i18n.locales[lang];
|
|
2125
|
+
if(!locale){ locale={}; i18n.locales[lang]=locale };
|
|
2126
|
+
var exp=/^([\w\-]+):/,m;
|
|
2127
|
+
for(var i=0;i<texts.length;i++){
|
|
2128
|
+
var v=texts[i]; m=exp.exec(v);
|
|
2129
|
+
if(!m){ CLog(tag+"'key:'? "+v,3,set); continue }
|
|
2130
|
+
var key=m[1],v=v.substr(key.length+1);
|
|
2131
|
+
if(!overwrite && locale[key]) continue;
|
|
2132
|
+
locale[key]=v;
|
|
2133
|
+
}
|
|
2134
|
+
}
|
|
2135
|
+
//获取key对应的文本,如果没有对应文本,将返回en的,en的也没有将返回zh的
|
|
2136
|
+
,get:function(/*key,args,lang*/){
|
|
2137
|
+
return i18n.v_G.apply(null,arguments);
|
|
2138
|
+
}, v_G:function(key,args,lang){ //全局可重写get
|
|
2139
|
+
args=args||[];
|
|
2140
|
+
lang=lang||i18n.lang; lang=i18n.alias[lang]||lang;
|
|
2141
|
+
var locale=i18n.locales[lang];
|
|
2142
|
+
var val=locale&&locale[key]||"";
|
|
2143
|
+
if(!val&&lang!="zh"){
|
|
2144
|
+
if(lang=="en")return i18n.v_G(key,args,"zh");
|
|
2145
|
+
return i18n.v_G(key,args,"en");
|
|
2146
|
+
}
|
|
2147
|
+
i18n.lastLang=lang;
|
|
2148
|
+
if(val=="=Empty")return "";
|
|
2149
|
+
return val.replace(/\{(\d+)(\!?)\}/g,function(v,a,b){
|
|
2150
|
+
a=+a||0; v=args[a-1];
|
|
2151
|
+
if(a<1 || a>args.length){ v="{?}"; CLog("i18n["+key+"] no {"+a+"}: "+val,3) }
|
|
2152
|
+
return b?"":v;
|
|
2153
|
+
});
|
|
2154
|
+
}
|
|
2155
|
+
/**返回一个国际化文本,返回的文本取决于i18n.lang。
|
|
2156
|
+
调用参数:T("key:[lang]:中文{1}","[lang]:英文{1}",...,0,"args1","args2"),除了key:,其他都是可选的,文本如果在语言实例中不存在会push进去,第一个文本无lang时默认zh,第二个无lang时默认en,文本中用{1-n}来插入args
|
|
2157
|
+
第一个args前面这个参数必须是0;也可以不提供args,这个参数填args的数量,此时不返回文本,只返回key,再用i18n.get提供参数获取文本
|
|
2158
|
+
本函数调用,第一个文本需中文,调用尽量简单,不要换行,方便后续自动提取翻译列表
|
|
2159
|
+
args如果旧的参数位置发生了变更,应当使用新的key,让旧的翻译失效,增加args无需更换key
|
|
2160
|
+
key的生成使用随机字符串,不同源码里面可以搞个不同前缀:
|
|
2161
|
+
s="";L=4; for(var i=0,n;i<L;i++){ n=~~(Math.random()*62);s+=n<10?n:String.fromCharCode(n<36?55+n:61+n); }; s
|
|
2162
|
+
**/
|
|
2163
|
+
,$T:function(){
|
|
2164
|
+
return i18n.v_T.apply(null,arguments);
|
|
2165
|
+
} ,v_T:function(){ //全局可重写$T
|
|
2166
|
+
var a=arguments,key="",args=[],isArgs=0,tag=RecTxt+".i18n.$T:";
|
|
2167
|
+
var exp=/^([\w\-]*):/,m;
|
|
2168
|
+
for(var i=0;i<a.length;i++){
|
|
2169
|
+
var v=a[i];
|
|
2170
|
+
if(i==0){
|
|
2171
|
+
m=exp.exec(v); key=m&&m[1];
|
|
2172
|
+
if(!key)throw new Error(tag+"0 'key:'?");
|
|
2173
|
+
v=v.substr(key.length+1);
|
|
2174
|
+
}
|
|
2175
|
+
if(isArgs===-1) args.push(v);
|
|
2176
|
+
else if(isArgs) throw new Error(tag+" bad args");
|
|
2177
|
+
else if(v===0) isArgs=-1;
|
|
2178
|
+
else if(IsNum(v)){
|
|
2179
|
+
if(v<1) throw new Error(tag+" bad args");
|
|
2180
|
+
isArgs=v;
|
|
2181
|
+
}else{
|
|
2182
|
+
var lang=i==1?"en":i?"":"zh";
|
|
2183
|
+
m=exp.exec(v); if(m){ lang=m[1]||lang; v=v.substr(m[1].length+1); }
|
|
2184
|
+
if(!m || !lang)throw new Error(tag+i+" 'lang:'?");
|
|
2185
|
+
i18n.put({lang:lang,overwrite:false},[key+":"+v]);
|
|
2186
|
+
}
|
|
2187
|
+
}
|
|
2188
|
+
if(!key)return "";
|
|
2189
|
+
if(isArgs>0)return key;
|
|
2190
|
+
return i18n.v_G(key,args);
|
|
2191
|
+
}
|
|
2192
|
+
};
|
|
2193
|
+
var $T=i18n.$T; $T.G=i18n.get;
|
|
2194
|
+
//预定义文本
|
|
2195
|
+
$T("NonBrowser-1::非浏览器环境,不支持{1}",1);
|
|
2196
|
+
$T("IllegalArgs-1::参数错误:{1}",1);
|
|
2197
|
+
$T("NeedImport-2::调用{1}需要先导入{2}",2);
|
|
2198
|
+
$T("NotSupport-1::不支持:{1}",1);
|
|
2199
|
+
//=====End i18n=====
|
|
2200
|
+
|
|
2201
|
+
|
|
2202
|
+
|
|
2203
|
+
//流量统计用1像素图片地址,设置为空将不参与统计
|
|
2204
|
+
Recorder.TrafficImgUrl="//ia.51.la/go1?id=20469973&pvFlag=1";
|
|
2205
|
+
var Traffic=Recorder.Traffic=function(report){
|
|
2206
|
+
if(!isBrowser)return;
|
|
2207
|
+
report=report?"/"+RecTxt+"/Report/"+report:"";
|
|
2208
|
+
var imgUrl=Recorder.TrafficImgUrl;
|
|
2209
|
+
if(imgUrl){
|
|
2210
|
+
var data=Recorder.Traffic;
|
|
2211
|
+
var m=/^(https?:..[^\/#]*\/?)[^#]*/i.exec(location.href)||[];
|
|
2212
|
+
var host=(m[1]||"http://file/");
|
|
2213
|
+
var idf=(m[0]||host)+report;
|
|
2214
|
+
|
|
2215
|
+
if(imgUrl.indexOf("//")==0){
|
|
2216
|
+
//给url加上http前缀,如果是file协议下,不加前缀没法用
|
|
2217
|
+
if(/^https:/i.test(idf)){
|
|
2218
|
+
imgUrl="https:"+imgUrl;
|
|
2219
|
+
}else{
|
|
2220
|
+
imgUrl="http:"+imgUrl;
|
|
2221
|
+
};
|
|
2222
|
+
};
|
|
2223
|
+
if(report){
|
|
2224
|
+
imgUrl=imgUrl+"&cu="+encodeURIComponent(host+report);
|
|
2225
|
+
};
|
|
2226
|
+
|
|
2227
|
+
if(!data[idf]){
|
|
2228
|
+
data[idf]=1;
|
|
2229
|
+
|
|
2230
|
+
var img=new Image();
|
|
2231
|
+
img.src=imgUrl;
|
|
2232
|
+
CLog("Traffic Analysis Image: "+(report||RecTxt+".TrafficImgUrl="+Recorder.TrafficImgUrl));
|
|
2233
|
+
};
|
|
2234
|
+
};
|
|
2235
|
+
};
|
|
2236
|
+
|
|
2237
|
+
|
|
2238
|
+
|
|
2239
|
+
if(WRec2){
|
|
2240
|
+
CLog($T("8HO5::覆盖导入{1}",0,RecTxt),1);
|
|
2241
|
+
WRec2.Destroy();
|
|
2242
|
+
};
|
|
2243
|
+
Export[RecTxt]=Recorder;
|
|
2244
|
+
|
|
2245
|
+
}));
|
|
2246
|
+
|
|
38
2247
|
/***/ }),
|
|
39
2248
|
|
|
40
2249
|
/***/ 6262:
|
|
@@ -122,6 +2331,24 @@ module.exports = function (argument) {
|
|
|
122
2331
|
};
|
|
123
2332
|
|
|
124
2333
|
|
|
2334
|
+
/***/ }),
|
|
2335
|
+
|
|
2336
|
+
/***/ 3506:
|
|
2337
|
+
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {
|
|
2338
|
+
|
|
2339
|
+
"use strict";
|
|
2340
|
+
|
|
2341
|
+
var isPossiblePrototype = __webpack_require__(3925);
|
|
2342
|
+
|
|
2343
|
+
var $String = String;
|
|
2344
|
+
var $TypeError = TypeError;
|
|
2345
|
+
|
|
2346
|
+
module.exports = function (argument) {
|
|
2347
|
+
if (isPossiblePrototype(argument)) return argument;
|
|
2348
|
+
throw new $TypeError("Can't set " + $String(argument) + ' as a prototype');
|
|
2349
|
+
};
|
|
2350
|
+
|
|
2351
|
+
|
|
125
2352
|
/***/ }),
|
|
126
2353
|
|
|
127
2354
|
/***/ 8551:
|
|
@@ -141,6 +2368,356 @@ module.exports = function (argument) {
|
|
|
141
2368
|
};
|
|
142
2369
|
|
|
143
2370
|
|
|
2371
|
+
/***/ }),
|
|
2372
|
+
|
|
2373
|
+
/***/ 7811:
|
|
2374
|
+
/***/ (function(module) {
|
|
2375
|
+
|
|
2376
|
+
"use strict";
|
|
2377
|
+
|
|
2378
|
+
// eslint-disable-next-line es/no-typed-arrays -- safe
|
|
2379
|
+
module.exports = typeof ArrayBuffer != 'undefined' && typeof DataView != 'undefined';
|
|
2380
|
+
|
|
2381
|
+
|
|
2382
|
+
/***/ }),
|
|
2383
|
+
|
|
2384
|
+
/***/ 7394:
|
|
2385
|
+
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {
|
|
2386
|
+
|
|
2387
|
+
"use strict";
|
|
2388
|
+
|
|
2389
|
+
var globalThis = __webpack_require__(4576);
|
|
2390
|
+
var uncurryThisAccessor = __webpack_require__(6706);
|
|
2391
|
+
var classof = __webpack_require__(2195);
|
|
2392
|
+
|
|
2393
|
+
var ArrayBuffer = globalThis.ArrayBuffer;
|
|
2394
|
+
var TypeError = globalThis.TypeError;
|
|
2395
|
+
|
|
2396
|
+
// Includes
|
|
2397
|
+
// - Perform ? RequireInternalSlot(O, [[ArrayBufferData]]).
|
|
2398
|
+
// - If IsSharedArrayBuffer(O) is true, throw a TypeError exception.
|
|
2399
|
+
module.exports = ArrayBuffer && uncurryThisAccessor(ArrayBuffer.prototype, 'byteLength', 'get') || function (O) {
|
|
2400
|
+
if (classof(O) !== 'ArrayBuffer') throw new TypeError('ArrayBuffer expected');
|
|
2401
|
+
return O.byteLength;
|
|
2402
|
+
};
|
|
2403
|
+
|
|
2404
|
+
|
|
2405
|
+
/***/ }),
|
|
2406
|
+
|
|
2407
|
+
/***/ 3238:
|
|
2408
|
+
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {
|
|
2409
|
+
|
|
2410
|
+
"use strict";
|
|
2411
|
+
|
|
2412
|
+
var globalThis = __webpack_require__(4576);
|
|
2413
|
+
var uncurryThis = __webpack_require__(7476);
|
|
2414
|
+
var arrayBufferByteLength = __webpack_require__(7394);
|
|
2415
|
+
|
|
2416
|
+
var ArrayBuffer = globalThis.ArrayBuffer;
|
|
2417
|
+
var ArrayBufferPrototype = ArrayBuffer && ArrayBuffer.prototype;
|
|
2418
|
+
var slice = ArrayBufferPrototype && uncurryThis(ArrayBufferPrototype.slice);
|
|
2419
|
+
|
|
2420
|
+
module.exports = function (O) {
|
|
2421
|
+
if (arrayBufferByteLength(O) !== 0) return false;
|
|
2422
|
+
if (!slice) return false;
|
|
2423
|
+
try {
|
|
2424
|
+
slice(O, 0, 0);
|
|
2425
|
+
return false;
|
|
2426
|
+
} catch (error) {
|
|
2427
|
+
return true;
|
|
2428
|
+
}
|
|
2429
|
+
};
|
|
2430
|
+
|
|
2431
|
+
|
|
2432
|
+
/***/ }),
|
|
2433
|
+
|
|
2434
|
+
/***/ 5169:
|
|
2435
|
+
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {
|
|
2436
|
+
|
|
2437
|
+
"use strict";
|
|
2438
|
+
|
|
2439
|
+
var isDetached = __webpack_require__(3238);
|
|
2440
|
+
|
|
2441
|
+
var $TypeError = TypeError;
|
|
2442
|
+
|
|
2443
|
+
module.exports = function (it) {
|
|
2444
|
+
if (isDetached(it)) throw new $TypeError('ArrayBuffer is detached');
|
|
2445
|
+
return it;
|
|
2446
|
+
};
|
|
2447
|
+
|
|
2448
|
+
|
|
2449
|
+
/***/ }),
|
|
2450
|
+
|
|
2451
|
+
/***/ 5636:
|
|
2452
|
+
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {
|
|
2453
|
+
|
|
2454
|
+
"use strict";
|
|
2455
|
+
|
|
2456
|
+
var globalThis = __webpack_require__(4576);
|
|
2457
|
+
var uncurryThis = __webpack_require__(9504);
|
|
2458
|
+
var uncurryThisAccessor = __webpack_require__(6706);
|
|
2459
|
+
var toIndex = __webpack_require__(7696);
|
|
2460
|
+
var notDetached = __webpack_require__(5169);
|
|
2461
|
+
var arrayBufferByteLength = __webpack_require__(7394);
|
|
2462
|
+
var detachTransferable = __webpack_require__(4483);
|
|
2463
|
+
var PROPER_STRUCTURED_CLONE_TRANSFER = __webpack_require__(1548);
|
|
2464
|
+
|
|
2465
|
+
var structuredClone = globalThis.structuredClone;
|
|
2466
|
+
var ArrayBuffer = globalThis.ArrayBuffer;
|
|
2467
|
+
var DataView = globalThis.DataView;
|
|
2468
|
+
var min = Math.min;
|
|
2469
|
+
var ArrayBufferPrototype = ArrayBuffer.prototype;
|
|
2470
|
+
var DataViewPrototype = DataView.prototype;
|
|
2471
|
+
var slice = uncurryThis(ArrayBufferPrototype.slice);
|
|
2472
|
+
var isResizable = uncurryThisAccessor(ArrayBufferPrototype, 'resizable', 'get');
|
|
2473
|
+
var maxByteLength = uncurryThisAccessor(ArrayBufferPrototype, 'maxByteLength', 'get');
|
|
2474
|
+
var getInt8 = uncurryThis(DataViewPrototype.getInt8);
|
|
2475
|
+
var setInt8 = uncurryThis(DataViewPrototype.setInt8);
|
|
2476
|
+
|
|
2477
|
+
module.exports = (PROPER_STRUCTURED_CLONE_TRANSFER || detachTransferable) && function (arrayBuffer, newLength, preserveResizability) {
|
|
2478
|
+
var byteLength = arrayBufferByteLength(arrayBuffer);
|
|
2479
|
+
var newByteLength = newLength === undefined ? byteLength : toIndex(newLength);
|
|
2480
|
+
var fixedLength = !isResizable || !isResizable(arrayBuffer);
|
|
2481
|
+
var newBuffer;
|
|
2482
|
+
notDetached(arrayBuffer);
|
|
2483
|
+
if (PROPER_STRUCTURED_CLONE_TRANSFER) {
|
|
2484
|
+
arrayBuffer = structuredClone(arrayBuffer, { transfer: [arrayBuffer] });
|
|
2485
|
+
if (byteLength === newByteLength && (preserveResizability || fixedLength)) return arrayBuffer;
|
|
2486
|
+
}
|
|
2487
|
+
if (byteLength >= newByteLength && (!preserveResizability || fixedLength)) {
|
|
2488
|
+
newBuffer = slice(arrayBuffer, 0, newByteLength);
|
|
2489
|
+
} else {
|
|
2490
|
+
var options = preserveResizability && !fixedLength && maxByteLength ? { maxByteLength: maxByteLength(arrayBuffer) } : undefined;
|
|
2491
|
+
newBuffer = new ArrayBuffer(newByteLength, options);
|
|
2492
|
+
var a = new DataView(arrayBuffer);
|
|
2493
|
+
var b = new DataView(newBuffer);
|
|
2494
|
+
var copyLength = min(newByteLength, byteLength);
|
|
2495
|
+
for (var i = 0; i < copyLength; i++) setInt8(b, i, getInt8(a, i));
|
|
2496
|
+
}
|
|
2497
|
+
if (!PROPER_STRUCTURED_CLONE_TRANSFER) detachTransferable(arrayBuffer);
|
|
2498
|
+
return newBuffer;
|
|
2499
|
+
};
|
|
2500
|
+
|
|
2501
|
+
|
|
2502
|
+
/***/ }),
|
|
2503
|
+
|
|
2504
|
+
/***/ 4644:
|
|
2505
|
+
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {
|
|
2506
|
+
|
|
2507
|
+
"use strict";
|
|
2508
|
+
|
|
2509
|
+
var NATIVE_ARRAY_BUFFER = __webpack_require__(7811);
|
|
2510
|
+
var DESCRIPTORS = __webpack_require__(3724);
|
|
2511
|
+
var globalThis = __webpack_require__(4576);
|
|
2512
|
+
var isCallable = __webpack_require__(4901);
|
|
2513
|
+
var isObject = __webpack_require__(34);
|
|
2514
|
+
var hasOwn = __webpack_require__(9297);
|
|
2515
|
+
var classof = __webpack_require__(6955);
|
|
2516
|
+
var tryToString = __webpack_require__(6823);
|
|
2517
|
+
var createNonEnumerableProperty = __webpack_require__(6699);
|
|
2518
|
+
var defineBuiltIn = __webpack_require__(6840);
|
|
2519
|
+
var defineBuiltInAccessor = __webpack_require__(2106);
|
|
2520
|
+
var isPrototypeOf = __webpack_require__(1625);
|
|
2521
|
+
var getPrototypeOf = __webpack_require__(2787);
|
|
2522
|
+
var setPrototypeOf = __webpack_require__(2967);
|
|
2523
|
+
var wellKnownSymbol = __webpack_require__(8227);
|
|
2524
|
+
var uid = __webpack_require__(3392);
|
|
2525
|
+
var InternalStateModule = __webpack_require__(1181);
|
|
2526
|
+
|
|
2527
|
+
var enforceInternalState = InternalStateModule.enforce;
|
|
2528
|
+
var getInternalState = InternalStateModule.get;
|
|
2529
|
+
var Int8Array = globalThis.Int8Array;
|
|
2530
|
+
var Int8ArrayPrototype = Int8Array && Int8Array.prototype;
|
|
2531
|
+
var Uint8ClampedArray = globalThis.Uint8ClampedArray;
|
|
2532
|
+
var Uint8ClampedArrayPrototype = Uint8ClampedArray && Uint8ClampedArray.prototype;
|
|
2533
|
+
var TypedArray = Int8Array && getPrototypeOf(Int8Array);
|
|
2534
|
+
var TypedArrayPrototype = Int8ArrayPrototype && getPrototypeOf(Int8ArrayPrototype);
|
|
2535
|
+
var ObjectPrototype = Object.prototype;
|
|
2536
|
+
var TypeError = globalThis.TypeError;
|
|
2537
|
+
|
|
2538
|
+
var TO_STRING_TAG = wellKnownSymbol('toStringTag');
|
|
2539
|
+
var TYPED_ARRAY_TAG = uid('TYPED_ARRAY_TAG');
|
|
2540
|
+
var TYPED_ARRAY_CONSTRUCTOR = 'TypedArrayConstructor';
|
|
2541
|
+
// Fixing native typed arrays in Opera Presto crashes the browser, see #595
|
|
2542
|
+
var NATIVE_ARRAY_BUFFER_VIEWS = NATIVE_ARRAY_BUFFER && !!setPrototypeOf && classof(globalThis.opera) !== 'Opera';
|
|
2543
|
+
var TYPED_ARRAY_TAG_REQUIRED = false;
|
|
2544
|
+
var NAME, Constructor, Prototype;
|
|
2545
|
+
|
|
2546
|
+
var TypedArrayConstructorsList = {
|
|
2547
|
+
Int8Array: 1,
|
|
2548
|
+
Uint8Array: 1,
|
|
2549
|
+
Uint8ClampedArray: 1,
|
|
2550
|
+
Int16Array: 2,
|
|
2551
|
+
Uint16Array: 2,
|
|
2552
|
+
Int32Array: 4,
|
|
2553
|
+
Uint32Array: 4,
|
|
2554
|
+
Float32Array: 4,
|
|
2555
|
+
Float64Array: 8
|
|
2556
|
+
};
|
|
2557
|
+
|
|
2558
|
+
var BigIntArrayConstructorsList = {
|
|
2559
|
+
BigInt64Array: 8,
|
|
2560
|
+
BigUint64Array: 8
|
|
2561
|
+
};
|
|
2562
|
+
|
|
2563
|
+
var isView = function isView(it) {
|
|
2564
|
+
if (!isObject(it)) return false;
|
|
2565
|
+
var klass = classof(it);
|
|
2566
|
+
return klass === 'DataView'
|
|
2567
|
+
|| hasOwn(TypedArrayConstructorsList, klass)
|
|
2568
|
+
|| hasOwn(BigIntArrayConstructorsList, klass);
|
|
2569
|
+
};
|
|
2570
|
+
|
|
2571
|
+
var getTypedArrayConstructor = function (it) {
|
|
2572
|
+
var proto = getPrototypeOf(it);
|
|
2573
|
+
if (!isObject(proto)) return;
|
|
2574
|
+
var state = getInternalState(proto);
|
|
2575
|
+
return (state && hasOwn(state, TYPED_ARRAY_CONSTRUCTOR)) ? state[TYPED_ARRAY_CONSTRUCTOR] : getTypedArrayConstructor(proto);
|
|
2576
|
+
};
|
|
2577
|
+
|
|
2578
|
+
var isTypedArray = function (it) {
|
|
2579
|
+
if (!isObject(it)) return false;
|
|
2580
|
+
var klass = classof(it);
|
|
2581
|
+
return hasOwn(TypedArrayConstructorsList, klass)
|
|
2582
|
+
|| hasOwn(BigIntArrayConstructorsList, klass);
|
|
2583
|
+
};
|
|
2584
|
+
|
|
2585
|
+
var aTypedArray = function (it) {
|
|
2586
|
+
if (isTypedArray(it)) return it;
|
|
2587
|
+
throw new TypeError('Target is not a typed array');
|
|
2588
|
+
};
|
|
2589
|
+
|
|
2590
|
+
var aTypedArrayConstructor = function (C) {
|
|
2591
|
+
if (isCallable(C) && (!setPrototypeOf || isPrototypeOf(TypedArray, C))) return C;
|
|
2592
|
+
throw new TypeError(tryToString(C) + ' is not a typed array constructor');
|
|
2593
|
+
};
|
|
2594
|
+
|
|
2595
|
+
var exportTypedArrayMethod = function (KEY, property, forced, options) {
|
|
2596
|
+
if (!DESCRIPTORS) return;
|
|
2597
|
+
if (forced) for (var ARRAY in TypedArrayConstructorsList) {
|
|
2598
|
+
var TypedArrayConstructor = globalThis[ARRAY];
|
|
2599
|
+
if (TypedArrayConstructor && hasOwn(TypedArrayConstructor.prototype, KEY)) try {
|
|
2600
|
+
delete TypedArrayConstructor.prototype[KEY];
|
|
2601
|
+
} catch (error) {
|
|
2602
|
+
// old WebKit bug - some methods are non-configurable
|
|
2603
|
+
try {
|
|
2604
|
+
TypedArrayConstructor.prototype[KEY] = property;
|
|
2605
|
+
} catch (error2) { /* empty */ }
|
|
2606
|
+
}
|
|
2607
|
+
}
|
|
2608
|
+
if (!TypedArrayPrototype[KEY] || forced) {
|
|
2609
|
+
defineBuiltIn(TypedArrayPrototype, KEY, forced ? property
|
|
2610
|
+
: NATIVE_ARRAY_BUFFER_VIEWS && Int8ArrayPrototype[KEY] || property, options);
|
|
2611
|
+
}
|
|
2612
|
+
};
|
|
2613
|
+
|
|
2614
|
+
var exportTypedArrayStaticMethod = function (KEY, property, forced) {
|
|
2615
|
+
var ARRAY, TypedArrayConstructor;
|
|
2616
|
+
if (!DESCRIPTORS) return;
|
|
2617
|
+
if (setPrototypeOf) {
|
|
2618
|
+
if (forced) for (ARRAY in TypedArrayConstructorsList) {
|
|
2619
|
+
TypedArrayConstructor = globalThis[ARRAY];
|
|
2620
|
+
if (TypedArrayConstructor && hasOwn(TypedArrayConstructor, KEY)) try {
|
|
2621
|
+
delete TypedArrayConstructor[KEY];
|
|
2622
|
+
} catch (error) { /* empty */ }
|
|
2623
|
+
}
|
|
2624
|
+
if (!TypedArray[KEY] || forced) {
|
|
2625
|
+
// V8 ~ Chrome 49-50 `%TypedArray%` methods are non-writable non-configurable
|
|
2626
|
+
try {
|
|
2627
|
+
return defineBuiltIn(TypedArray, KEY, forced ? property : NATIVE_ARRAY_BUFFER_VIEWS && TypedArray[KEY] || property);
|
|
2628
|
+
} catch (error) { /* empty */ }
|
|
2629
|
+
} else return;
|
|
2630
|
+
}
|
|
2631
|
+
for (ARRAY in TypedArrayConstructorsList) {
|
|
2632
|
+
TypedArrayConstructor = globalThis[ARRAY];
|
|
2633
|
+
if (TypedArrayConstructor && (!TypedArrayConstructor[KEY] || forced)) {
|
|
2634
|
+
defineBuiltIn(TypedArrayConstructor, KEY, property);
|
|
2635
|
+
}
|
|
2636
|
+
}
|
|
2637
|
+
};
|
|
2638
|
+
|
|
2639
|
+
for (NAME in TypedArrayConstructorsList) {
|
|
2640
|
+
Constructor = globalThis[NAME];
|
|
2641
|
+
Prototype = Constructor && Constructor.prototype;
|
|
2642
|
+
if (Prototype) enforceInternalState(Prototype)[TYPED_ARRAY_CONSTRUCTOR] = Constructor;
|
|
2643
|
+
else NATIVE_ARRAY_BUFFER_VIEWS = false;
|
|
2644
|
+
}
|
|
2645
|
+
|
|
2646
|
+
for (NAME in BigIntArrayConstructorsList) {
|
|
2647
|
+
Constructor = globalThis[NAME];
|
|
2648
|
+
Prototype = Constructor && Constructor.prototype;
|
|
2649
|
+
if (Prototype) enforceInternalState(Prototype)[TYPED_ARRAY_CONSTRUCTOR] = Constructor;
|
|
2650
|
+
}
|
|
2651
|
+
|
|
2652
|
+
// WebKit bug - typed arrays constructors prototype is Object.prototype
|
|
2653
|
+
if (!NATIVE_ARRAY_BUFFER_VIEWS || !isCallable(TypedArray) || TypedArray === Function.prototype) {
|
|
2654
|
+
// eslint-disable-next-line no-shadow -- safe
|
|
2655
|
+
TypedArray = function TypedArray() {
|
|
2656
|
+
throw new TypeError('Incorrect invocation');
|
|
2657
|
+
};
|
|
2658
|
+
if (NATIVE_ARRAY_BUFFER_VIEWS) for (NAME in TypedArrayConstructorsList) {
|
|
2659
|
+
if (globalThis[NAME]) setPrototypeOf(globalThis[NAME], TypedArray);
|
|
2660
|
+
}
|
|
2661
|
+
}
|
|
2662
|
+
|
|
2663
|
+
if (!NATIVE_ARRAY_BUFFER_VIEWS || !TypedArrayPrototype || TypedArrayPrototype === ObjectPrototype) {
|
|
2664
|
+
TypedArrayPrototype = TypedArray.prototype;
|
|
2665
|
+
if (NATIVE_ARRAY_BUFFER_VIEWS) for (NAME in TypedArrayConstructorsList) {
|
|
2666
|
+
if (globalThis[NAME]) setPrototypeOf(globalThis[NAME].prototype, TypedArrayPrototype);
|
|
2667
|
+
}
|
|
2668
|
+
}
|
|
2669
|
+
|
|
2670
|
+
// WebKit bug - one more object in Uint8ClampedArray prototype chain
|
|
2671
|
+
if (NATIVE_ARRAY_BUFFER_VIEWS && getPrototypeOf(Uint8ClampedArrayPrototype) !== TypedArrayPrototype) {
|
|
2672
|
+
setPrototypeOf(Uint8ClampedArrayPrototype, TypedArrayPrototype);
|
|
2673
|
+
}
|
|
2674
|
+
|
|
2675
|
+
if (DESCRIPTORS && !hasOwn(TypedArrayPrototype, TO_STRING_TAG)) {
|
|
2676
|
+
TYPED_ARRAY_TAG_REQUIRED = true;
|
|
2677
|
+
defineBuiltInAccessor(TypedArrayPrototype, TO_STRING_TAG, {
|
|
2678
|
+
configurable: true,
|
|
2679
|
+
get: function () {
|
|
2680
|
+
return isObject(this) ? this[TYPED_ARRAY_TAG] : undefined;
|
|
2681
|
+
}
|
|
2682
|
+
});
|
|
2683
|
+
for (NAME in TypedArrayConstructorsList) if (globalThis[NAME]) {
|
|
2684
|
+
createNonEnumerableProperty(globalThis[NAME], TYPED_ARRAY_TAG, NAME);
|
|
2685
|
+
}
|
|
2686
|
+
}
|
|
2687
|
+
|
|
2688
|
+
module.exports = {
|
|
2689
|
+
NATIVE_ARRAY_BUFFER_VIEWS: NATIVE_ARRAY_BUFFER_VIEWS,
|
|
2690
|
+
TYPED_ARRAY_TAG: TYPED_ARRAY_TAG_REQUIRED && TYPED_ARRAY_TAG,
|
|
2691
|
+
aTypedArray: aTypedArray,
|
|
2692
|
+
aTypedArrayConstructor: aTypedArrayConstructor,
|
|
2693
|
+
exportTypedArrayMethod: exportTypedArrayMethod,
|
|
2694
|
+
exportTypedArrayStaticMethod: exportTypedArrayStaticMethod,
|
|
2695
|
+
getTypedArrayConstructor: getTypedArrayConstructor,
|
|
2696
|
+
isView: isView,
|
|
2697
|
+
isTypedArray: isTypedArray,
|
|
2698
|
+
TypedArray: TypedArray,
|
|
2699
|
+
TypedArrayPrototype: TypedArrayPrototype
|
|
2700
|
+
};
|
|
2701
|
+
|
|
2702
|
+
|
|
2703
|
+
/***/ }),
|
|
2704
|
+
|
|
2705
|
+
/***/ 5370:
|
|
2706
|
+
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {
|
|
2707
|
+
|
|
2708
|
+
"use strict";
|
|
2709
|
+
|
|
2710
|
+
var lengthOfArrayLike = __webpack_require__(6198);
|
|
2711
|
+
|
|
2712
|
+
module.exports = function (Constructor, list, $length) {
|
|
2713
|
+
var index = 0;
|
|
2714
|
+
var length = arguments.length > 2 ? $length : lengthOfArrayLike(list);
|
|
2715
|
+
var result = new Constructor(length);
|
|
2716
|
+
while (length > index) result[index] = list[index++];
|
|
2717
|
+
return result;
|
|
2718
|
+
};
|
|
2719
|
+
|
|
2720
|
+
|
|
144
2721
|
/***/ }),
|
|
145
2722
|
|
|
146
2723
|
/***/ 9617:
|
|
@@ -218,6 +2795,52 @@ module.exports = SILENT_ON_NON_WRITABLE_LENGTH_SET ? function (O, length) {
|
|
|
218
2795
|
};
|
|
219
2796
|
|
|
220
2797
|
|
|
2798
|
+
/***/ }),
|
|
2799
|
+
|
|
2800
|
+
/***/ 7628:
|
|
2801
|
+
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {
|
|
2802
|
+
|
|
2803
|
+
"use strict";
|
|
2804
|
+
|
|
2805
|
+
var lengthOfArrayLike = __webpack_require__(6198);
|
|
2806
|
+
|
|
2807
|
+
// https://tc39.es/proposal-change-array-by-copy/#sec-array.prototype.toReversed
|
|
2808
|
+
// https://tc39.es/proposal-change-array-by-copy/#sec-%typedarray%.prototype.toReversed
|
|
2809
|
+
module.exports = function (O, C) {
|
|
2810
|
+
var len = lengthOfArrayLike(O);
|
|
2811
|
+
var A = new C(len);
|
|
2812
|
+
var k = 0;
|
|
2813
|
+
for (; k < len; k++) A[k] = O[len - k - 1];
|
|
2814
|
+
return A;
|
|
2815
|
+
};
|
|
2816
|
+
|
|
2817
|
+
|
|
2818
|
+
/***/ }),
|
|
2819
|
+
|
|
2820
|
+
/***/ 9928:
|
|
2821
|
+
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {
|
|
2822
|
+
|
|
2823
|
+
"use strict";
|
|
2824
|
+
|
|
2825
|
+
var lengthOfArrayLike = __webpack_require__(6198);
|
|
2826
|
+
var toIntegerOrInfinity = __webpack_require__(1291);
|
|
2827
|
+
|
|
2828
|
+
var $RangeError = RangeError;
|
|
2829
|
+
|
|
2830
|
+
// https://tc39.es/proposal-change-array-by-copy/#sec-array.prototype.with
|
|
2831
|
+
// https://tc39.es/proposal-change-array-by-copy/#sec-%typedarray%.prototype.with
|
|
2832
|
+
module.exports = function (O, C, index, value) {
|
|
2833
|
+
var len = lengthOfArrayLike(O);
|
|
2834
|
+
var relativeIndex = toIntegerOrInfinity(index);
|
|
2835
|
+
var actualIndex = relativeIndex < 0 ? len + relativeIndex : relativeIndex;
|
|
2836
|
+
if (actualIndex >= len || actualIndex < 0) throw new $RangeError('Incorrect index');
|
|
2837
|
+
var A = new C(len);
|
|
2838
|
+
var k = 0;
|
|
2839
|
+
for (; k < len; k++) A[k] = k === actualIndex ? value : O[k];
|
|
2840
|
+
return A;
|
|
2841
|
+
};
|
|
2842
|
+
|
|
2843
|
+
|
|
221
2844
|
/***/ }),
|
|
222
2845
|
|
|
223
2846
|
/***/ 2195:
|
|
@@ -298,6 +2921,23 @@ module.exports = function (target, source, exceptions) {
|
|
|
298
2921
|
};
|
|
299
2922
|
|
|
300
2923
|
|
|
2924
|
+
/***/ }),
|
|
2925
|
+
|
|
2926
|
+
/***/ 2211:
|
|
2927
|
+
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {
|
|
2928
|
+
|
|
2929
|
+
"use strict";
|
|
2930
|
+
|
|
2931
|
+
var fails = __webpack_require__(9039);
|
|
2932
|
+
|
|
2933
|
+
module.exports = !fails(function () {
|
|
2934
|
+
function F() { /* empty */ }
|
|
2935
|
+
F.prototype.constructor = null;
|
|
2936
|
+
// eslint-disable-next-line es/no-object-getprototypeof -- required for testing
|
|
2937
|
+
return Object.getPrototypeOf(new F()) !== F.prototype;
|
|
2938
|
+
});
|
|
2939
|
+
|
|
2940
|
+
|
|
301
2941
|
/***/ }),
|
|
302
2942
|
|
|
303
2943
|
/***/ 6699:
|
|
@@ -424,6 +3064,51 @@ module.exports = !fails(function () {
|
|
|
424
3064
|
});
|
|
425
3065
|
|
|
426
3066
|
|
|
3067
|
+
/***/ }),
|
|
3068
|
+
|
|
3069
|
+
/***/ 4483:
|
|
3070
|
+
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {
|
|
3071
|
+
|
|
3072
|
+
"use strict";
|
|
3073
|
+
|
|
3074
|
+
var globalThis = __webpack_require__(4576);
|
|
3075
|
+
var getBuiltInNodeModule = __webpack_require__(9429);
|
|
3076
|
+
var PROPER_STRUCTURED_CLONE_TRANSFER = __webpack_require__(1548);
|
|
3077
|
+
|
|
3078
|
+
var structuredClone = globalThis.structuredClone;
|
|
3079
|
+
var $ArrayBuffer = globalThis.ArrayBuffer;
|
|
3080
|
+
var $MessageChannel = globalThis.MessageChannel;
|
|
3081
|
+
var detach = false;
|
|
3082
|
+
var WorkerThreads, channel, buffer, $detach;
|
|
3083
|
+
|
|
3084
|
+
if (PROPER_STRUCTURED_CLONE_TRANSFER) {
|
|
3085
|
+
detach = function (transferable) {
|
|
3086
|
+
structuredClone(transferable, { transfer: [transferable] });
|
|
3087
|
+
};
|
|
3088
|
+
} else if ($ArrayBuffer) try {
|
|
3089
|
+
if (!$MessageChannel) {
|
|
3090
|
+
WorkerThreads = getBuiltInNodeModule('worker_threads');
|
|
3091
|
+
if (WorkerThreads) $MessageChannel = WorkerThreads.MessageChannel;
|
|
3092
|
+
}
|
|
3093
|
+
|
|
3094
|
+
if ($MessageChannel) {
|
|
3095
|
+
channel = new $MessageChannel();
|
|
3096
|
+
buffer = new $ArrayBuffer(2);
|
|
3097
|
+
|
|
3098
|
+
$detach = function (transferable) {
|
|
3099
|
+
channel.port1.postMessage(null, [transferable]);
|
|
3100
|
+
};
|
|
3101
|
+
|
|
3102
|
+
if (buffer.byteLength === 2) {
|
|
3103
|
+
$detach(buffer);
|
|
3104
|
+
if (buffer.byteLength === 0) detach = $detach;
|
|
3105
|
+
}
|
|
3106
|
+
}
|
|
3107
|
+
} catch (error) { /* empty */ }
|
|
3108
|
+
|
|
3109
|
+
module.exports = detach;
|
|
3110
|
+
|
|
3111
|
+
|
|
427
3112
|
/***/ }),
|
|
428
3113
|
|
|
429
3114
|
/***/ 4055:
|
|
@@ -478,6 +3163,18 @@ module.exports = [
|
|
|
478
3163
|
];
|
|
479
3164
|
|
|
480
3165
|
|
|
3166
|
+
/***/ }),
|
|
3167
|
+
|
|
3168
|
+
/***/ 6193:
|
|
3169
|
+
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {
|
|
3170
|
+
|
|
3171
|
+
"use strict";
|
|
3172
|
+
|
|
3173
|
+
var ENVIRONMENT = __webpack_require__(4215);
|
|
3174
|
+
|
|
3175
|
+
module.exports = ENVIRONMENT === 'NODE';
|
|
3176
|
+
|
|
3177
|
+
|
|
481
3178
|
/***/ }),
|
|
482
3179
|
|
|
483
3180
|
/***/ 2839:
|
|
@@ -529,6 +3226,35 @@ if (!version && userAgent) {
|
|
|
529
3226
|
module.exports = version;
|
|
530
3227
|
|
|
531
3228
|
|
|
3229
|
+
/***/ }),
|
|
3230
|
+
|
|
3231
|
+
/***/ 4215:
|
|
3232
|
+
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {
|
|
3233
|
+
|
|
3234
|
+
"use strict";
|
|
3235
|
+
|
|
3236
|
+
/* global Bun, Deno -- detection */
|
|
3237
|
+
var globalThis = __webpack_require__(4576);
|
|
3238
|
+
var userAgent = __webpack_require__(2839);
|
|
3239
|
+
var classof = __webpack_require__(2195);
|
|
3240
|
+
|
|
3241
|
+
var userAgentStartsWith = function (string) {
|
|
3242
|
+
return userAgent.slice(0, string.length) === string;
|
|
3243
|
+
};
|
|
3244
|
+
|
|
3245
|
+
module.exports = (function () {
|
|
3246
|
+
if (userAgentStartsWith('Bun/')) return 'BUN';
|
|
3247
|
+
if (userAgentStartsWith('Cloudflare-Workers')) return 'CLOUDFLARE';
|
|
3248
|
+
if (userAgentStartsWith('Deno/')) return 'DENO';
|
|
3249
|
+
if (userAgentStartsWith('Node.js/')) return 'NODE';
|
|
3250
|
+
if (globalThis.Bun && typeof Bun.version == 'string') return 'BUN';
|
|
3251
|
+
if (globalThis.Deno && typeof Deno.version == 'object') return 'DENO';
|
|
3252
|
+
if (classof(globalThis.process) === 'process') return 'NODE';
|
|
3253
|
+
if (globalThis.window && globalThis.document) return 'BROWSER';
|
|
3254
|
+
return 'REST';
|
|
3255
|
+
})();
|
|
3256
|
+
|
|
3257
|
+
|
|
532
3258
|
/***/ }),
|
|
533
3259
|
|
|
534
3260
|
/***/ 6518:
|
|
@@ -667,6 +3393,42 @@ module.exports = {
|
|
|
667
3393
|
};
|
|
668
3394
|
|
|
669
3395
|
|
|
3396
|
+
/***/ }),
|
|
3397
|
+
|
|
3398
|
+
/***/ 6706:
|
|
3399
|
+
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {
|
|
3400
|
+
|
|
3401
|
+
"use strict";
|
|
3402
|
+
|
|
3403
|
+
var uncurryThis = __webpack_require__(9504);
|
|
3404
|
+
var aCallable = __webpack_require__(9306);
|
|
3405
|
+
|
|
3406
|
+
module.exports = function (object, key, method) {
|
|
3407
|
+
try {
|
|
3408
|
+
// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe
|
|
3409
|
+
return uncurryThis(aCallable(Object.getOwnPropertyDescriptor(object, key)[method]));
|
|
3410
|
+
} catch (error) { /* empty */ }
|
|
3411
|
+
};
|
|
3412
|
+
|
|
3413
|
+
|
|
3414
|
+
/***/ }),
|
|
3415
|
+
|
|
3416
|
+
/***/ 7476:
|
|
3417
|
+
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {
|
|
3418
|
+
|
|
3419
|
+
"use strict";
|
|
3420
|
+
|
|
3421
|
+
var classofRaw = __webpack_require__(2195);
|
|
3422
|
+
var uncurryThis = __webpack_require__(9504);
|
|
3423
|
+
|
|
3424
|
+
module.exports = function (fn) {
|
|
3425
|
+
// Nashorn bug:
|
|
3426
|
+
// https://github.com/zloirock/core-js/issues/1128
|
|
3427
|
+
// https://github.com/zloirock/core-js/issues/1130
|
|
3428
|
+
if (classofRaw(fn) === 'Function') return uncurryThis(fn);
|
|
3429
|
+
};
|
|
3430
|
+
|
|
3431
|
+
|
|
670
3432
|
/***/ }),
|
|
671
3433
|
|
|
672
3434
|
/***/ 9504:
|
|
@@ -687,6 +3449,29 @@ module.exports = NATIVE_BIND ? uncurryThisWithBind : function (fn) {
|
|
|
687
3449
|
};
|
|
688
3450
|
|
|
689
3451
|
|
|
3452
|
+
/***/ }),
|
|
3453
|
+
|
|
3454
|
+
/***/ 9429:
|
|
3455
|
+
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {
|
|
3456
|
+
|
|
3457
|
+
"use strict";
|
|
3458
|
+
|
|
3459
|
+
var globalThis = __webpack_require__(4576);
|
|
3460
|
+
var IS_NODE = __webpack_require__(6193);
|
|
3461
|
+
|
|
3462
|
+
module.exports = function (name) {
|
|
3463
|
+
if (IS_NODE) {
|
|
3464
|
+
try {
|
|
3465
|
+
return globalThis.process.getBuiltinModule(name);
|
|
3466
|
+
} catch (error) { /* empty */ }
|
|
3467
|
+
try {
|
|
3468
|
+
// eslint-disable-next-line no-new-func -- safe
|
|
3469
|
+
return Function('return require("' + name + '")')();
|
|
3470
|
+
} catch (error) { /* empty */ }
|
|
3471
|
+
}
|
|
3472
|
+
};
|
|
3473
|
+
|
|
3474
|
+
|
|
690
3475
|
/***/ }),
|
|
691
3476
|
|
|
692
3477
|
/***/ 7751:
|
|
@@ -941,6 +3726,21 @@ module.exports = Array.isArray || function isArray(argument) {
|
|
|
941
3726
|
};
|
|
942
3727
|
|
|
943
3728
|
|
|
3729
|
+
/***/ }),
|
|
3730
|
+
|
|
3731
|
+
/***/ 1108:
|
|
3732
|
+
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {
|
|
3733
|
+
|
|
3734
|
+
"use strict";
|
|
3735
|
+
|
|
3736
|
+
var classof = __webpack_require__(6955);
|
|
3737
|
+
|
|
3738
|
+
module.exports = function (it) {
|
|
3739
|
+
var klass = classof(it);
|
|
3740
|
+
return klass === 'BigInt64Array' || klass === 'BigUint64Array';
|
|
3741
|
+
};
|
|
3742
|
+
|
|
3743
|
+
|
|
944
3744
|
/***/ }),
|
|
945
3745
|
|
|
946
3746
|
/***/ 4901:
|
|
@@ -1020,6 +3820,20 @@ module.exports = function (it) {
|
|
|
1020
3820
|
};
|
|
1021
3821
|
|
|
1022
3822
|
|
|
3823
|
+
/***/ }),
|
|
3824
|
+
|
|
3825
|
+
/***/ 3925:
|
|
3826
|
+
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {
|
|
3827
|
+
|
|
3828
|
+
"use strict";
|
|
3829
|
+
|
|
3830
|
+
var isObject = __webpack_require__(34);
|
|
3831
|
+
|
|
3832
|
+
module.exports = function (argument) {
|
|
3833
|
+
return isObject(argument) || argument === null;
|
|
3834
|
+
};
|
|
3835
|
+
|
|
3836
|
+
|
|
1023
3837
|
/***/ }),
|
|
1024
3838
|
|
|
1025
3839
|
/***/ 6395:
|
|
@@ -1264,6 +4078,36 @@ exports.f = Object.getOwnPropertyNames || function getOwnPropertyNames(O) {
|
|
|
1264
4078
|
exports.f = Object.getOwnPropertySymbols;
|
|
1265
4079
|
|
|
1266
4080
|
|
|
4081
|
+
/***/ }),
|
|
4082
|
+
|
|
4083
|
+
/***/ 2787:
|
|
4084
|
+
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {
|
|
4085
|
+
|
|
4086
|
+
"use strict";
|
|
4087
|
+
|
|
4088
|
+
var hasOwn = __webpack_require__(9297);
|
|
4089
|
+
var isCallable = __webpack_require__(4901);
|
|
4090
|
+
var toObject = __webpack_require__(8981);
|
|
4091
|
+
var sharedKey = __webpack_require__(6119);
|
|
4092
|
+
var CORRECT_PROTOTYPE_GETTER = __webpack_require__(2211);
|
|
4093
|
+
|
|
4094
|
+
var IE_PROTO = sharedKey('IE_PROTO');
|
|
4095
|
+
var $Object = Object;
|
|
4096
|
+
var ObjectPrototype = $Object.prototype;
|
|
4097
|
+
|
|
4098
|
+
// `Object.getPrototypeOf` method
|
|
4099
|
+
// https://tc39.es/ecma262/#sec-object.getprototypeof
|
|
4100
|
+
// eslint-disable-next-line es/no-object-getprototypeof -- safe
|
|
4101
|
+
module.exports = CORRECT_PROTOTYPE_GETTER ? $Object.getPrototypeOf : function (O) {
|
|
4102
|
+
var object = toObject(O);
|
|
4103
|
+
if (hasOwn(object, IE_PROTO)) return object[IE_PROTO];
|
|
4104
|
+
var constructor = object.constructor;
|
|
4105
|
+
if (isCallable(constructor) && object instanceof constructor) {
|
|
4106
|
+
return constructor.prototype;
|
|
4107
|
+
} return object instanceof $Object ? ObjectPrototype : null;
|
|
4108
|
+
};
|
|
4109
|
+
|
|
4110
|
+
|
|
1267
4111
|
/***/ }),
|
|
1268
4112
|
|
|
1269
4113
|
/***/ 1625:
|
|
@@ -1327,6 +4171,43 @@ exports.f = NASHORN_BUG ? function propertyIsEnumerable(V) {
|
|
|
1327
4171
|
} : $propertyIsEnumerable;
|
|
1328
4172
|
|
|
1329
4173
|
|
|
4174
|
+
/***/ }),
|
|
4175
|
+
|
|
4176
|
+
/***/ 2967:
|
|
4177
|
+
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {
|
|
4178
|
+
|
|
4179
|
+
"use strict";
|
|
4180
|
+
|
|
4181
|
+
/* eslint-disable no-proto -- safe */
|
|
4182
|
+
var uncurryThisAccessor = __webpack_require__(6706);
|
|
4183
|
+
var isObject = __webpack_require__(34);
|
|
4184
|
+
var requireObjectCoercible = __webpack_require__(7750);
|
|
4185
|
+
var aPossiblePrototype = __webpack_require__(3506);
|
|
4186
|
+
|
|
4187
|
+
// `Object.setPrototypeOf` method
|
|
4188
|
+
// https://tc39.es/ecma262/#sec-object.setprototypeof
|
|
4189
|
+
// Works with __proto__ only. Old v8 can't work with null proto objects.
|
|
4190
|
+
// eslint-disable-next-line es/no-object-setprototypeof -- safe
|
|
4191
|
+
module.exports = Object.setPrototypeOf || ('__proto__' in {} ? function () {
|
|
4192
|
+
var CORRECT_SETTER = false;
|
|
4193
|
+
var test = {};
|
|
4194
|
+
var setter;
|
|
4195
|
+
try {
|
|
4196
|
+
setter = uncurryThisAccessor(Object.prototype, '__proto__', 'set');
|
|
4197
|
+
setter(test, []);
|
|
4198
|
+
CORRECT_SETTER = test instanceof Array;
|
|
4199
|
+
} catch (error) { /* empty */ }
|
|
4200
|
+
return function setPrototypeOf(O, proto) {
|
|
4201
|
+
requireObjectCoercible(O);
|
|
4202
|
+
aPossiblePrototype(proto);
|
|
4203
|
+
if (!isObject(O)) return O;
|
|
4204
|
+
if (CORRECT_SETTER) setter(O, proto);
|
|
4205
|
+
else O.__proto__ = proto;
|
|
4206
|
+
return O;
|
|
4207
|
+
};
|
|
4208
|
+
}() : undefined);
|
|
4209
|
+
|
|
4210
|
+
|
|
1330
4211
|
/***/ }),
|
|
1331
4212
|
|
|
1332
4213
|
/***/ 4270:
|
|
@@ -1447,6 +4328,30 @@ module.exports = function (key, value) {
|
|
|
1447
4328
|
};
|
|
1448
4329
|
|
|
1449
4330
|
|
|
4331
|
+
/***/ }),
|
|
4332
|
+
|
|
4333
|
+
/***/ 1548:
|
|
4334
|
+
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {
|
|
4335
|
+
|
|
4336
|
+
"use strict";
|
|
4337
|
+
|
|
4338
|
+
var globalThis = __webpack_require__(4576);
|
|
4339
|
+
var fails = __webpack_require__(9039);
|
|
4340
|
+
var V8 = __webpack_require__(9519);
|
|
4341
|
+
var ENVIRONMENT = __webpack_require__(4215);
|
|
4342
|
+
|
|
4343
|
+
var structuredClone = globalThis.structuredClone;
|
|
4344
|
+
|
|
4345
|
+
module.exports = !!structuredClone && !fails(function () {
|
|
4346
|
+
// prevent V8 ArrayBufferDetaching protector cell invalidation and performance degradation
|
|
4347
|
+
// https://github.com/zloirock/core-js/issues/679
|
|
4348
|
+
if ((ENVIRONMENT === 'DENO' && V8 > 92) || (ENVIRONMENT === 'NODE' && V8 > 94) || (ENVIRONMENT === 'BROWSER' && V8 > 97)) return false;
|
|
4349
|
+
var buffer = new ArrayBuffer(8);
|
|
4350
|
+
var clone = structuredClone(buffer, { transfer: [buffer] });
|
|
4351
|
+
return buffer.byteLength !== 0 || clone.byteLength !== 8;
|
|
4352
|
+
});
|
|
4353
|
+
|
|
4354
|
+
|
|
1450
4355
|
/***/ }),
|
|
1451
4356
|
|
|
1452
4357
|
/***/ 4495:
|
|
@@ -1495,6 +4400,50 @@ module.exports = function (index, length) {
|
|
|
1495
4400
|
};
|
|
1496
4401
|
|
|
1497
4402
|
|
|
4403
|
+
/***/ }),
|
|
4404
|
+
|
|
4405
|
+
/***/ 5854:
|
|
4406
|
+
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {
|
|
4407
|
+
|
|
4408
|
+
"use strict";
|
|
4409
|
+
|
|
4410
|
+
var toPrimitive = __webpack_require__(2777);
|
|
4411
|
+
|
|
4412
|
+
var $TypeError = TypeError;
|
|
4413
|
+
|
|
4414
|
+
// `ToBigInt` abstract operation
|
|
4415
|
+
// https://tc39.es/ecma262/#sec-tobigint
|
|
4416
|
+
module.exports = function (argument) {
|
|
4417
|
+
var prim = toPrimitive(argument, 'number');
|
|
4418
|
+
if (typeof prim == 'number') throw new $TypeError("Can't convert number to bigint");
|
|
4419
|
+
// eslint-disable-next-line es/no-bigint -- safe
|
|
4420
|
+
return BigInt(prim);
|
|
4421
|
+
};
|
|
4422
|
+
|
|
4423
|
+
|
|
4424
|
+
/***/ }),
|
|
4425
|
+
|
|
4426
|
+
/***/ 7696:
|
|
4427
|
+
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {
|
|
4428
|
+
|
|
4429
|
+
"use strict";
|
|
4430
|
+
|
|
4431
|
+
var toIntegerOrInfinity = __webpack_require__(1291);
|
|
4432
|
+
var toLength = __webpack_require__(8014);
|
|
4433
|
+
|
|
4434
|
+
var $RangeError = RangeError;
|
|
4435
|
+
|
|
4436
|
+
// `ToIndex` abstract operation
|
|
4437
|
+
// https://tc39.es/ecma262/#sec-toindex
|
|
4438
|
+
module.exports = function (it) {
|
|
4439
|
+
if (it === undefined) return 0;
|
|
4440
|
+
var number = toIntegerOrInfinity(it);
|
|
4441
|
+
var length = toLength(number);
|
|
4442
|
+
if (number !== length) throw new $RangeError('Wrong length or index');
|
|
4443
|
+
return length;
|
|
4444
|
+
};
|
|
4445
|
+
|
|
4446
|
+
|
|
1498
4447
|
/***/ }),
|
|
1499
4448
|
|
|
1500
4449
|
/***/ 5397:
|
|
@@ -1635,23 +4584,6 @@ test[TO_STRING_TAG] = 'z';
|
|
|
1635
4584
|
module.exports = String(test) === '[object z]';
|
|
1636
4585
|
|
|
1637
4586
|
|
|
1638
|
-
/***/ }),
|
|
1639
|
-
|
|
1640
|
-
/***/ 655:
|
|
1641
|
-
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {
|
|
1642
|
-
|
|
1643
|
-
"use strict";
|
|
1644
|
-
|
|
1645
|
-
var classof = __webpack_require__(6955);
|
|
1646
|
-
|
|
1647
|
-
var $String = String;
|
|
1648
|
-
|
|
1649
|
-
module.exports = function (argument) {
|
|
1650
|
-
if (classof(argument) === 'Symbol') throw new TypeError('Cannot convert a Symbol value to a string');
|
|
1651
|
-
return $String(argument);
|
|
1652
|
-
};
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
4587
|
/***/ }),
|
|
1656
4588
|
|
|
1657
4589
|
/***/ 6823:
|
|
@@ -1713,30 +4645,15 @@ module.exports = NATIVE_SYMBOL
|
|
|
1713
4645
|
var DESCRIPTORS = __webpack_require__(3724);
|
|
1714
4646
|
var fails = __webpack_require__(9039);
|
|
1715
4647
|
|
|
1716
|
-
// V8 ~ Chrome 36-
|
|
1717
|
-
// https://bugs.chromium.org/p/v8/issues/detail?id=3334
|
|
1718
|
-
module.exports = DESCRIPTORS && fails(function () {
|
|
1719
|
-
// eslint-disable-next-line es/no-object-defineproperty -- required for testing
|
|
1720
|
-
return Object.defineProperty(function () { /* empty */ }, 'prototype', {
|
|
1721
|
-
value: 42,
|
|
1722
|
-
writable: false
|
|
1723
|
-
}).prototype !== 42;
|
|
1724
|
-
});
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
/***/ }),
|
|
1728
|
-
|
|
1729
|
-
/***/ 2812:
|
|
1730
|
-
/***/ (function(module) {
|
|
1731
|
-
|
|
1732
|
-
"use strict";
|
|
1733
|
-
|
|
1734
|
-
var $TypeError = TypeError;
|
|
1735
|
-
|
|
1736
|
-
module.exports = function (passed, required) {
|
|
1737
|
-
if (passed < required) throw new $TypeError('Not enough arguments');
|
|
1738
|
-
return passed;
|
|
1739
|
-
};
|
|
4648
|
+
// V8 ~ Chrome 36-
|
|
4649
|
+
// https://bugs.chromium.org/p/v8/issues/detail?id=3334
|
|
4650
|
+
module.exports = DESCRIPTORS && fails(function () {
|
|
4651
|
+
// eslint-disable-next-line es/no-object-defineproperty -- required for testing
|
|
4652
|
+
return Object.defineProperty(function () { /* empty */ }, 'prototype', {
|
|
4653
|
+
value: 42,
|
|
4654
|
+
writable: false
|
|
4655
|
+
}).prototype !== 42;
|
|
4656
|
+
});
|
|
1740
4657
|
|
|
1741
4658
|
|
|
1742
4659
|
/***/ }),
|
|
@@ -1781,6 +4698,67 @@ module.exports = function (name) {
|
|
|
1781
4698
|
};
|
|
1782
4699
|
|
|
1783
4700
|
|
|
4701
|
+
/***/ }),
|
|
4702
|
+
|
|
4703
|
+
/***/ 6573:
|
|
4704
|
+
/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) {
|
|
4705
|
+
|
|
4706
|
+
"use strict";
|
|
4707
|
+
|
|
4708
|
+
var DESCRIPTORS = __webpack_require__(3724);
|
|
4709
|
+
var defineBuiltInAccessor = __webpack_require__(2106);
|
|
4710
|
+
var isDetached = __webpack_require__(3238);
|
|
4711
|
+
|
|
4712
|
+
var ArrayBufferPrototype = ArrayBuffer.prototype;
|
|
4713
|
+
|
|
4714
|
+
if (DESCRIPTORS && !('detached' in ArrayBufferPrototype)) {
|
|
4715
|
+
defineBuiltInAccessor(ArrayBufferPrototype, 'detached', {
|
|
4716
|
+
configurable: true,
|
|
4717
|
+
get: function detached() {
|
|
4718
|
+
return isDetached(this);
|
|
4719
|
+
}
|
|
4720
|
+
});
|
|
4721
|
+
}
|
|
4722
|
+
|
|
4723
|
+
|
|
4724
|
+
/***/ }),
|
|
4725
|
+
|
|
4726
|
+
/***/ 7936:
|
|
4727
|
+
/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) {
|
|
4728
|
+
|
|
4729
|
+
"use strict";
|
|
4730
|
+
|
|
4731
|
+
var $ = __webpack_require__(6518);
|
|
4732
|
+
var $transfer = __webpack_require__(5636);
|
|
4733
|
+
|
|
4734
|
+
// `ArrayBuffer.prototype.transferToFixedLength` method
|
|
4735
|
+
// https://tc39.es/proposal-arraybuffer-transfer/#sec-arraybuffer.prototype.transfertofixedlength
|
|
4736
|
+
if ($transfer) $({ target: 'ArrayBuffer', proto: true }, {
|
|
4737
|
+
transferToFixedLength: function transferToFixedLength() {
|
|
4738
|
+
return $transfer(this, arguments.length ? arguments[0] : undefined, false);
|
|
4739
|
+
}
|
|
4740
|
+
});
|
|
4741
|
+
|
|
4742
|
+
|
|
4743
|
+
/***/ }),
|
|
4744
|
+
|
|
4745
|
+
/***/ 8100:
|
|
4746
|
+
/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) {
|
|
4747
|
+
|
|
4748
|
+
"use strict";
|
|
4749
|
+
|
|
4750
|
+
var $ = __webpack_require__(6518);
|
|
4751
|
+
var $transfer = __webpack_require__(5636);
|
|
4752
|
+
|
|
4753
|
+
// `ArrayBuffer.prototype.transfer` method
|
|
4754
|
+
// https://tc39.es/proposal-arraybuffer-transfer/#sec-arraybuffer.prototype.transfer
|
|
4755
|
+
if ($transfer) $({ target: 'ArrayBuffer', proto: true }, {
|
|
4756
|
+
transfer: function transfer() {
|
|
4757
|
+
return $transfer(this, arguments.length ? arguments[0] : undefined, true);
|
|
4758
|
+
}
|
|
4759
|
+
});
|
|
4760
|
+
|
|
4761
|
+
|
|
1784
4762
|
/***/ }),
|
|
1785
4763
|
|
|
1786
4764
|
/***/ 4114:
|
|
@@ -1833,124 +4811,88 @@ $({ target: 'Array', proto: true, arity: 1, forced: FORCED }, {
|
|
|
1833
4811
|
|
|
1834
4812
|
/***/ }),
|
|
1835
4813
|
|
|
1836
|
-
/***/
|
|
4814
|
+
/***/ 7467:
|
|
1837
4815
|
/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) {
|
|
1838
4816
|
|
|
1839
4817
|
"use strict";
|
|
1840
4818
|
|
|
1841
|
-
var
|
|
1842
|
-
var
|
|
1843
|
-
|
|
1844
|
-
var
|
|
1845
|
-
|
|
1846
|
-
var
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
params['delete']('a', 1);
|
|
1855
|
-
// `undefined` case is a Chromium 117 bug
|
|
1856
|
-
// https://bugs.chromium.org/p/v8/issues/detail?id=14222
|
|
1857
|
-
params['delete']('b', undefined);
|
|
1858
|
-
|
|
1859
|
-
if (params + '' !== 'a=2') {
|
|
1860
|
-
defineBuiltIn(URLSearchParamsPrototype, 'delete', function (name /* , value */) {
|
|
1861
|
-
var length = arguments.length;
|
|
1862
|
-
var $value = length < 2 ? undefined : arguments[1];
|
|
1863
|
-
if (length && $value === undefined) return $delete(this, name);
|
|
1864
|
-
var entries = [];
|
|
1865
|
-
forEach(this, function (v, k) { // also validates `this`
|
|
1866
|
-
push(entries, { key: k, value: v });
|
|
1867
|
-
});
|
|
1868
|
-
validateArgumentsLength(length, 1);
|
|
1869
|
-
var key = toString(name);
|
|
1870
|
-
var value = toString($value);
|
|
1871
|
-
var index = 0;
|
|
1872
|
-
var dindex = 0;
|
|
1873
|
-
var found = false;
|
|
1874
|
-
var entriesLength = entries.length;
|
|
1875
|
-
var entry;
|
|
1876
|
-
while (index < entriesLength) {
|
|
1877
|
-
entry = entries[index++];
|
|
1878
|
-
if (found || entry.key === key) {
|
|
1879
|
-
found = true;
|
|
1880
|
-
$delete(this, entry.key);
|
|
1881
|
-
} else dindex++;
|
|
1882
|
-
}
|
|
1883
|
-
while (dindex < entriesLength) {
|
|
1884
|
-
entry = entries[dindex++];
|
|
1885
|
-
if (!(entry.key === key && entry.value === value)) append(this, entry.key, entry.value);
|
|
1886
|
-
}
|
|
1887
|
-
}, { enumerable: true, unsafe: true });
|
|
1888
|
-
}
|
|
4819
|
+
var arrayToReversed = __webpack_require__(7628);
|
|
4820
|
+
var ArrayBufferViewCore = __webpack_require__(4644);
|
|
4821
|
+
|
|
4822
|
+
var aTypedArray = ArrayBufferViewCore.aTypedArray;
|
|
4823
|
+
var exportTypedArrayMethod = ArrayBufferViewCore.exportTypedArrayMethod;
|
|
4824
|
+
var getTypedArrayConstructor = ArrayBufferViewCore.getTypedArrayConstructor;
|
|
4825
|
+
|
|
4826
|
+
// `%TypedArray%.prototype.toReversed` method
|
|
4827
|
+
// https://tc39.es/ecma262/#sec-%typedarray%.prototype.toreversed
|
|
4828
|
+
exportTypedArrayMethod('toReversed', function toReversed() {
|
|
4829
|
+
return arrayToReversed(aTypedArray(this), getTypedArrayConstructor(this));
|
|
4830
|
+
});
|
|
1889
4831
|
|
|
1890
4832
|
|
|
1891
4833
|
/***/ }),
|
|
1892
4834
|
|
|
1893
|
-
/***/
|
|
4835
|
+
/***/ 4732:
|
|
1894
4836
|
/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) {
|
|
1895
4837
|
|
|
1896
4838
|
"use strict";
|
|
1897
4839
|
|
|
1898
|
-
var
|
|
4840
|
+
var ArrayBufferViewCore = __webpack_require__(4644);
|
|
1899
4841
|
var uncurryThis = __webpack_require__(9504);
|
|
1900
|
-
var
|
|
1901
|
-
var
|
|
1902
|
-
|
|
1903
|
-
var
|
|
1904
|
-
var
|
|
1905
|
-
var
|
|
1906
|
-
var
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
//
|
|
1910
|
-
|
|
1911
|
-
if (
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
var values = getAll(this, name); // also validates `this`
|
|
1917
|
-
validateArgumentsLength(length, 1);
|
|
1918
|
-
var value = toString($value);
|
|
1919
|
-
var index = 0;
|
|
1920
|
-
while (index < values.length) {
|
|
1921
|
-
if (values[index++] === value) return true;
|
|
1922
|
-
} return false;
|
|
1923
|
-
}, { enumerable: true, unsafe: true });
|
|
1924
|
-
}
|
|
4842
|
+
var aCallable = __webpack_require__(9306);
|
|
4843
|
+
var arrayFromConstructorAndList = __webpack_require__(5370);
|
|
4844
|
+
|
|
4845
|
+
var aTypedArray = ArrayBufferViewCore.aTypedArray;
|
|
4846
|
+
var getTypedArrayConstructor = ArrayBufferViewCore.getTypedArrayConstructor;
|
|
4847
|
+
var exportTypedArrayMethod = ArrayBufferViewCore.exportTypedArrayMethod;
|
|
4848
|
+
var sort = uncurryThis(ArrayBufferViewCore.TypedArrayPrototype.sort);
|
|
4849
|
+
|
|
4850
|
+
// `%TypedArray%.prototype.toSorted` method
|
|
4851
|
+
// https://tc39.es/ecma262/#sec-%typedarray%.prototype.tosorted
|
|
4852
|
+
exportTypedArrayMethod('toSorted', function toSorted(compareFn) {
|
|
4853
|
+
if (compareFn !== undefined) aCallable(compareFn);
|
|
4854
|
+
var O = aTypedArray(this);
|
|
4855
|
+
var A = arrayFromConstructorAndList(getTypedArrayConstructor(O), O);
|
|
4856
|
+
return sort(A, compareFn);
|
|
4857
|
+
});
|
|
1925
4858
|
|
|
1926
4859
|
|
|
1927
4860
|
/***/ }),
|
|
1928
4861
|
|
|
1929
|
-
/***/
|
|
4862
|
+
/***/ 9577:
|
|
1930
4863
|
/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) {
|
|
1931
4864
|
|
|
1932
4865
|
"use strict";
|
|
1933
4866
|
|
|
1934
|
-
var
|
|
1935
|
-
var
|
|
1936
|
-
var
|
|
4867
|
+
var arrayWith = __webpack_require__(9928);
|
|
4868
|
+
var ArrayBufferViewCore = __webpack_require__(4644);
|
|
4869
|
+
var isBigIntArray = __webpack_require__(1108);
|
|
4870
|
+
var toIntegerOrInfinity = __webpack_require__(1291);
|
|
4871
|
+
var toBigInt = __webpack_require__(5854);
|
|
1937
4872
|
|
|
1938
|
-
var
|
|
1939
|
-
var
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
4873
|
+
var aTypedArray = ArrayBufferViewCore.aTypedArray;
|
|
4874
|
+
var getTypedArrayConstructor = ArrayBufferViewCore.getTypedArrayConstructor;
|
|
4875
|
+
var exportTypedArrayMethod = ArrayBufferViewCore.exportTypedArrayMethod;
|
|
4876
|
+
|
|
4877
|
+
var PROPER_ORDER = !!function () {
|
|
4878
|
+
try {
|
|
4879
|
+
// eslint-disable-next-line no-throw-literal, es/no-typed-arrays, es/no-array-prototype-with -- required for testing
|
|
4880
|
+
new Int8Array(1)['with'](2, { valueOf: function () { throw 8; } });
|
|
4881
|
+
} catch (error) {
|
|
4882
|
+
// some early implementations, like WebKit, does not follow the final semantic
|
|
4883
|
+
// https://github.com/tc39/proposal-change-array-by-copy/pull/86
|
|
4884
|
+
return error === 8;
|
|
4885
|
+
}
|
|
4886
|
+
}();
|
|
4887
|
+
|
|
4888
|
+
// `%TypedArray%.prototype.with` method
|
|
4889
|
+
// https://tc39.es/ecma262/#sec-%typedarray%.prototype.with
|
|
4890
|
+
exportTypedArrayMethod('with', { 'with': function (index, value) {
|
|
4891
|
+
var O = aTypedArray(this);
|
|
4892
|
+
var relativeIndex = toIntegerOrInfinity(index);
|
|
4893
|
+
var actualValue = isBigIntArray(O) ? toBigInt(value) : +value;
|
|
4894
|
+
return arrayWith(O, getTypedArrayConstructor(O), relativeIndex, actualValue);
|
|
4895
|
+
} }['with'], !PROPER_ORDER);
|
|
1954
4896
|
|
|
1955
4897
|
|
|
1956
4898
|
/***/ })
|
|
@@ -2083,15 +5025,21 @@ if (typeof window !== 'undefined') {
|
|
|
2083
5025
|
var external_commonjs_vue_commonjs2_vue_root_Vue_ = __webpack_require__(9274);
|
|
2084
5026
|
// EXTERNAL MODULE: ./node_modules/core-js/modules/es.array.push.js
|
|
2085
5027
|
var es_array_push = __webpack_require__(4114);
|
|
2086
|
-
// EXTERNAL MODULE: ./node_modules/core-js/modules/
|
|
2087
|
-
var
|
|
2088
|
-
// EXTERNAL MODULE: ./node_modules/core-js/modules/
|
|
2089
|
-
var
|
|
2090
|
-
// EXTERNAL MODULE: ./node_modules/core-js/modules/
|
|
2091
|
-
var
|
|
2092
|
-
// EXTERNAL MODULE: ./node_modules/js-
|
|
2093
|
-
var
|
|
2094
|
-
|
|
5028
|
+
// EXTERNAL MODULE: ./node_modules/core-js/modules/es.array-buffer.detached.js
|
|
5029
|
+
var es_array_buffer_detached = __webpack_require__(6573);
|
|
5030
|
+
// EXTERNAL MODULE: ./node_modules/core-js/modules/es.array-buffer.transfer.js
|
|
5031
|
+
var es_array_buffer_transfer = __webpack_require__(8100);
|
|
5032
|
+
// EXTERNAL MODULE: ./node_modules/core-js/modules/es.array-buffer.transfer-to-fixed-length.js
|
|
5033
|
+
var es_array_buffer_transfer_to_fixed_length = __webpack_require__(7936);
|
|
5034
|
+
// EXTERNAL MODULE: ./node_modules/core-js/modules/es.typed-array.to-reversed.js
|
|
5035
|
+
var es_typed_array_to_reversed = __webpack_require__(7467);
|
|
5036
|
+
// EXTERNAL MODULE: ./node_modules/core-js/modules/es.typed-array.to-sorted.js
|
|
5037
|
+
var es_typed_array_to_sorted = __webpack_require__(4732);
|
|
5038
|
+
// EXTERNAL MODULE: ./node_modules/core-js/modules/es.typed-array.with.js
|
|
5039
|
+
var es_typed_array_with = __webpack_require__(9577);
|
|
5040
|
+
// EXTERNAL MODULE: ./node_modules/recorder-core/src/recorder-core.js
|
|
5041
|
+
var recorder_core = __webpack_require__(2346);
|
|
5042
|
+
var recorder_core_default = /*#__PURE__*/__webpack_require__.n(recorder_core);
|
|
2095
5043
|
;// CONCATENATED MODULE: ./node_modules/axios/lib/helpers/bind.js
|
|
2096
5044
|
|
|
2097
5045
|
|
|
@@ -6085,7 +9033,7 @@ axios.default = axios;
|
|
|
6085
9033
|
const audioConfig = {
|
|
6086
9034
|
// here: "https://wiki.keepsoft.net:39002/uploadAudio/here.mp3",
|
|
6087
9035
|
here: "https://saas.keepsoft.net:20003/uploadAudio/here.mp3",
|
|
6088
|
-
xiaogui: [
|
|
9036
|
+
xiaogui: ["xiaoguixiaogui", " xiaohuixiaohui", "xiaoguaixiaoguai", "xiaokuixiaokui"]
|
|
6089
9037
|
};
|
|
6090
9038
|
;// CONCATENATED MODULE: ./node_modules/pinyin-pro/dist/index.mjs
|
|
6091
9039
|
const DoubleUnicodePrefixReg = /^[\uD800-\uDBFF]$/;
|
|
@@ -31229,13 +34177,113 @@ function segment(word, options) {
|
|
|
31229
34177
|
|
|
31230
34178
|
|
|
31231
34179
|
|
|
34180
|
+
;// CONCATENATED MODULE: ./src/package/src/utils/wsconnecter.js
|
|
34181
|
+
/**
|
|
34182
|
+
* Copyright FunASR (https://github.com/alibaba-damo-academy/FunASR). All Rights
|
|
34183
|
+
* Reserved. MIT License (https://opensource.org/licenses/MIT)
|
|
34184
|
+
*/
|
|
34185
|
+
/* 2021-2023 by zhaoming,mali aihealthx.com */
|
|
34186
|
+
|
|
34187
|
+
function WebSocketConnectMethod(config) {
|
|
34188
|
+
//定义socket连接方法类
|
|
34189
|
+
|
|
34190
|
+
var speechSokt;
|
|
34191
|
+
var msgHandle = config.msgHandle;
|
|
34192
|
+
var stateHandle = config.stateHandle;
|
|
34193
|
+
var url = config.url || "wss://172.16.103.188:10096/";
|
|
34194
|
+
var mode = "2pass";
|
|
34195
|
+
this.wsStart = function (modeStr = "2pass") {
|
|
34196
|
+
console.log(modeStr);
|
|
34197
|
+
mode = modeStr;
|
|
34198
|
+
if (url.match(/wss:\S*|ws:\S*/)) {
|
|
34199
|
+
console.log("url" + url);
|
|
34200
|
+
} else {
|
|
34201
|
+
alert("请检查wss地址正确性");
|
|
34202
|
+
return 0;
|
|
34203
|
+
}
|
|
34204
|
+
if ("WebSocket" in window) {
|
|
34205
|
+
speechSokt = new WebSocket(url); // 定义socket连接对象
|
|
34206
|
+
speechSokt.onopen = function (e) {
|
|
34207
|
+
onOpen(e);
|
|
34208
|
+
}; // 定义响应函数
|
|
34209
|
+
speechSokt.onclose = function (e) {
|
|
34210
|
+
console.log("onclose ws!", e);
|
|
34211
|
+
onClose(e);
|
|
34212
|
+
};
|
|
34213
|
+
speechSokt.onmessage = function (e) {
|
|
34214
|
+
onMessage(e);
|
|
34215
|
+
};
|
|
34216
|
+
speechSokt.onerror = function (e) {
|
|
34217
|
+
onError(e);
|
|
34218
|
+
};
|
|
34219
|
+
return 1;
|
|
34220
|
+
} else {
|
|
34221
|
+
alert("当前浏览器不支持 WebSocket");
|
|
34222
|
+
return 0;
|
|
34223
|
+
}
|
|
34224
|
+
};
|
|
34225
|
+
|
|
34226
|
+
// 定义停止与发送函数
|
|
34227
|
+
this.wsStop = function () {
|
|
34228
|
+
if (speechSokt != undefined) {
|
|
34229
|
+
console.log("stop ws!");
|
|
34230
|
+
speechSokt.close();
|
|
34231
|
+
}
|
|
34232
|
+
};
|
|
34233
|
+
this.wsSend = function (oneData) {
|
|
34234
|
+
if (speechSokt == undefined) return;
|
|
34235
|
+
if (speechSokt.readyState === 1) {
|
|
34236
|
+
// 0:CONNECTING, 1:OPEN, 2:CLOSING, 3:CLOSED
|
|
34237
|
+
|
|
34238
|
+
speechSokt.send(oneData);
|
|
34239
|
+
}
|
|
34240
|
+
};
|
|
34241
|
+
|
|
34242
|
+
// SOCEKT连接中的消息与状态响应
|
|
34243
|
+
function onOpen(e) {
|
|
34244
|
+
// 发送json
|
|
34245
|
+
var chunk_size = [5, 10, 5];
|
|
34246
|
+
var request = {
|
|
34247
|
+
"chunk_size": chunk_size,
|
|
34248
|
+
"wav_name": "h5",
|
|
34249
|
+
"is_speaking": true,
|
|
34250
|
+
"chunk_interval": 10,
|
|
34251
|
+
"itn": false,
|
|
34252
|
+
"mode": mode
|
|
34253
|
+
};
|
|
34254
|
+
var hotwords = null;
|
|
34255
|
+
if (hotwords != null) {
|
|
34256
|
+
request.hotwords = hotwords;
|
|
34257
|
+
}
|
|
34258
|
+
console.log(JSON.stringify(request));
|
|
34259
|
+
speechSokt.send(JSON.stringify(request));
|
|
34260
|
+
console.log("连接成功");
|
|
34261
|
+
stateHandle(0);
|
|
34262
|
+
}
|
|
34263
|
+
function onClose(e) {
|
|
34264
|
+
// stateHandle(1);
|
|
34265
|
+
}
|
|
34266
|
+
function onMessage(e) {
|
|
34267
|
+
msgHandle(e);
|
|
34268
|
+
}
|
|
34269
|
+
function onError(e) {
|
|
34270
|
+
// info_div.innerHTML = "连接" + e;
|
|
34271
|
+
console.log(e);
|
|
34272
|
+
stateHandle(2);
|
|
34273
|
+
}
|
|
34274
|
+
}
|
|
34275
|
+
// EXTERNAL MODULE: ./node_modules/recorder-core/src/extensions/waveview.js
|
|
34276
|
+
var waveview = __webpack_require__(9243);
|
|
31232
34277
|
;// CONCATENATED MODULE: ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-82.use[1]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/package/src/main.vue?vue&type=script&setup=true&lang=js
|
|
31233
34278
|
|
|
31234
34279
|
|
|
31235
34280
|
|
|
31236
34281
|
|
|
31237
34282
|
|
|
31238
|
-
|
|
34283
|
+
|
|
34284
|
+
|
|
34285
|
+
|
|
34286
|
+
const _withScopeId = n => (_pushScopeId("data-v-16bd8825"), n = n(), _popScopeId(), n);
|
|
31239
34287
|
const _hoisted_1 = ["src"];
|
|
31240
34288
|
const _hoisted_2 = {
|
|
31241
34289
|
key: 0,
|
|
@@ -31283,6 +34331,9 @@ const _hoisted_19 = ["src"];
|
|
|
31283
34331
|
|
|
31284
34332
|
|
|
31285
34333
|
|
|
34334
|
+
|
|
34335
|
+
//可选的插件支持项,这个是波形可视化插件
|
|
34336
|
+
|
|
31286
34337
|
/* harmony default export */ var mainvue_type_script_setup_true_lang_js = ({
|
|
31287
34338
|
__name: 'main',
|
|
31288
34339
|
props: {
|
|
@@ -31351,6 +34402,10 @@ const _hoisted_19 = ["src"];
|
|
|
31351
34402
|
bot_id: "7431129126334955530"
|
|
31352
34403
|
})
|
|
31353
34404
|
},
|
|
34405
|
+
audioWs: {
|
|
34406
|
+
type: String,
|
|
34407
|
+
default: "wss://172.16.103.188:10096/"
|
|
34408
|
+
},
|
|
31354
34409
|
wsServer: {
|
|
31355
34410
|
type: String,
|
|
31356
34411
|
default: "wss://wiki.keepsoft.net:39002/ws"
|
|
@@ -31393,14 +34448,8 @@ const _hoisted_19 = ["src"];
|
|
|
31393
34448
|
setup(__props, {
|
|
31394
34449
|
expose: __expose
|
|
31395
34450
|
}) {
|
|
31396
|
-
|
|
31397
|
-
let pCanvas = null;
|
|
31398
|
-
let drawPlayId = null;
|
|
31399
|
-
let wenetWs = null;
|
|
34451
|
+
//必须引入的核心
|
|
31400
34452
|
let audioSound = null;
|
|
31401
|
-
let recognition = null; //浏览器实时监听API
|
|
31402
|
-
// let instructWs = null;
|
|
31403
|
-
|
|
31404
34453
|
const contentRef = (0,external_commonjs_vue_commonjs2_vue_root_Vue_.ref)(null);
|
|
31405
34454
|
const scrollContainer = (0,external_commonjs_vue_commonjs2_vue_root_Vue_.ref)(null);
|
|
31406
34455
|
const props = __props;
|
|
@@ -31416,26 +34465,26 @@ const _hoisted_19 = ["src"];
|
|
|
31416
34465
|
audioSoundType: "",
|
|
31417
34466
|
recorderCode: 0,
|
|
31418
34467
|
//1唤醒 0沉睡
|
|
31419
|
-
recorder: new (
|
|
31420
|
-
sampleBits: 16,
|
|
31421
|
-
// 采样位数,支持 8 或 16,默认是16
|
|
31422
|
-
sampleRate: 48000,
|
|
31423
|
-
// 采样率,支持 11025、16000、22050、24000、44100、48000,根据浏览器默认值,我的chrome是48000
|
|
31424
|
-
numChannels: 1 // 声道,支持 1 或 2, 默认是1
|
|
31425
|
-
// compiling: false,(0.x版本中生效,1.x增加中) // 是否边录边转换,默认是false
|
|
31426
|
-
}),
|
|
31427
|
-
recorder2: new (js_audio_recorder_default())({
|
|
34468
|
+
recorder: new (recorder_core_default())({
|
|
31428
34469
|
sampleBits: 16,
|
|
31429
34470
|
// 采样位数,支持 8 或 16,默认是16
|
|
31430
34471
|
sampleRate: 48000,
|
|
31431
34472
|
// 采样率,支持 11025、16000、22050、24000、44100、48000,根据浏览器默认值,我的chrome是48000
|
|
31432
|
-
numChannels: 1
|
|
34473
|
+
numChannels: 1,
|
|
34474
|
+
// 声道,支持 1 或 2, 默认是1
|
|
34475
|
+
onProcess: recProcess
|
|
31433
34476
|
// compiling: false,(0.x版本中生效,1.x增加中) // 是否边录边转换,默认是false
|
|
31434
34477
|
})
|
|
31435
34478
|
});
|
|
34479
|
+
const wave = (0,external_commonjs_vue_commonjs2_vue_root_Vue_.ref)(null);
|
|
34480
|
+
const waveRef = (0,external_commonjs_vue_commonjs2_vue_root_Vue_.ref)(null);
|
|
34481
|
+
const wsconnecter = new WebSocketConnectMethod({
|
|
34482
|
+
url: props.audioWs,
|
|
34483
|
+
msgHandle: getJsonMessage,
|
|
34484
|
+
stateHandle: getConnState
|
|
34485
|
+
});
|
|
31436
34486
|
(0,external_commonjs_vue_commonjs2_vue_root_Vue_.onMounted)(() => {
|
|
31437
|
-
|
|
31438
|
-
setRecording();
|
|
34487
|
+
startApiMonitorAudio();
|
|
31439
34488
|
});
|
|
31440
34489
|
const startApiMonitorAudio = () => {
|
|
31441
34490
|
if (props.mode == "audio") {
|
|
@@ -31443,14 +34492,81 @@ const _hoisted_19 = ["src"];
|
|
|
31443
34492
|
}
|
|
31444
34493
|
};
|
|
31445
34494
|
|
|
34495
|
+
// 语音识别结果; 对jsonMsg数据解析,将识别结果附加到编辑框中
|
|
34496
|
+
function getJsonMessage(jsonMsg) {
|
|
34497
|
+
const data = JSON.parse(jsonMsg.data);
|
|
34498
|
+
// console.log(data);
|
|
34499
|
+
if (state.isAudio === "start") {
|
|
34500
|
+
state.input = data.text;
|
|
34501
|
+
} else {
|
|
34502
|
+
if (data.mode === "2pass-offline") {
|
|
34503
|
+
//唤醒状态下请求后端
|
|
34504
|
+
if (state.recorderCode === 1) {
|
|
34505
|
+
getAnswer(data.text);
|
|
34506
|
+
} else {
|
|
34507
|
+
//沉睡状态下识别是否是唤醒词
|
|
34508
|
+
discernHere(data.text);
|
|
34509
|
+
}
|
|
34510
|
+
}
|
|
34511
|
+
}
|
|
34512
|
+
}
|
|
34513
|
+
|
|
34514
|
+
// 连接状态响应
|
|
34515
|
+
function getConnState(connState) {
|
|
34516
|
+
if (connState === 0) {//on open
|
|
34517
|
+
} else if (connState === 1) {
|
|
34518
|
+
//close
|
|
34519
|
+
startRecognition();
|
|
34520
|
+
} else if (connState === 2) {
|
|
34521
|
+
//error
|
|
34522
|
+
console.log("connecttion error");
|
|
34523
|
+
startRecognition();
|
|
34524
|
+
}
|
|
34525
|
+
}
|
|
34526
|
+
let sampleBuf = new Int16Array();
|
|
34527
|
+
function recProcess(buffer, powerLevel, bufferDuration, bufferSampleRate) {
|
|
34528
|
+
if (wave.value) wave.value?.input(buffer[buffer.length - 1], powerLevel, bufferSampleRate);
|
|
34529
|
+
var data_48k = buffer[buffer.length - 1];
|
|
34530
|
+
var array_48k = new Array(data_48k);
|
|
34531
|
+
var data_16k = recorder_core_default().SampleData(array_48k, bufferSampleRate, 16000).data;
|
|
34532
|
+
sampleBuf = Int16Array.from([...sampleBuf, ...data_16k]);
|
|
34533
|
+
var chunk_size = 960; // for asr chunk_size [5, 10, 5]
|
|
34534
|
+
while (sampleBuf.length >= chunk_size) {
|
|
34535
|
+
const sendBuf = sampleBuf.slice(0, chunk_size);
|
|
34536
|
+
sampleBuf = sampleBuf.slice(chunk_size, sampleBuf.length);
|
|
34537
|
+
wsconnecter.wsSend(sendBuf);
|
|
34538
|
+
}
|
|
34539
|
+
}
|
|
34540
|
+
const startRecognition = () => {
|
|
34541
|
+
const recognition = wsconnecter.wsStart();
|
|
34542
|
+
if (recognition === 1) {
|
|
34543
|
+
console.log("recognition start");
|
|
34544
|
+
setRecording();
|
|
34545
|
+
} else {
|
|
34546
|
+
startRecognition();
|
|
34547
|
+
console.log("recognition error");
|
|
34548
|
+
}
|
|
34549
|
+
};
|
|
34550
|
+
const closeRecognition = () => {
|
|
34551
|
+
wsconnecter.wsStop();
|
|
34552
|
+
state.recorder.pause();
|
|
34553
|
+
};
|
|
34554
|
+
|
|
34555
|
+
// 开始监听
|
|
34556
|
+
const setRecording = () => {
|
|
34557
|
+
state.recorder.open(() => {
|
|
34558
|
+
console.log("recorder open");
|
|
34559
|
+
state.recorder.start();
|
|
34560
|
+
});
|
|
34561
|
+
};
|
|
34562
|
+
|
|
31446
34563
|
// 识别小贵
|
|
31447
34564
|
const discernHere = val => {
|
|
31448
34565
|
let pinyinStr = pinyin(val, {
|
|
31449
34566
|
toneType: "none",
|
|
31450
34567
|
type: "array"
|
|
31451
34568
|
});
|
|
31452
|
-
pinyinStr = pinyinStr.join("");
|
|
31453
|
-
// console.log(pinyinStr, "pinyinStr");
|
|
34569
|
+
pinyinStr = pinyinStr.filter(i => i !== "," && i !== "。").join("");
|
|
31454
34570
|
let {
|
|
31455
34571
|
xiaogui
|
|
31456
34572
|
} = audioConfig;
|
|
@@ -31460,230 +34576,46 @@ const _hoisted_19 = ["src"];
|
|
|
31460
34576
|
}
|
|
31461
34577
|
if (bol) {
|
|
31462
34578
|
state.recorderCode = 1;
|
|
31463
|
-
// recognition.stop();
|
|
31464
34579
|
iAmHere();
|
|
31465
|
-
window.setTimeout(() => {
|
|
31466
|
-
setRecording();
|
|
31467
|
-
}, 2500);
|
|
31468
34580
|
}
|
|
31469
34581
|
};
|
|
31470
|
-
const
|
|
31471
|
-
|
|
31472
|
-
let
|
|
31473
|
-
|
|
31474
|
-
|
|
31475
|
-
|
|
31476
|
-
lastArgs = args;
|
|
31477
|
-
timeout = setTimeout(() => {
|
|
31478
|
-
timeout = null;
|
|
31479
|
-
}, wait);
|
|
31480
|
-
} else {
|
|
31481
|
-
lastArgs = args;
|
|
31482
|
-
}
|
|
31483
|
-
};
|
|
31484
|
-
};
|
|
31485
|
-
const throttledLogMessage = throttle(discernHere, 2000);
|
|
31486
|
-
const startRecognition = () => {
|
|
31487
|
-
recognition = new (window.SpeechRecognition || window.webkitSpeechRecognition)();
|
|
31488
|
-
recognition.continuous = true; // 设置为 true 以持续监听
|
|
31489
|
-
recognition.interimResults = true; // 不显示中间结果
|
|
31490
|
-
recognition.lang = "ZH-cn";
|
|
31491
|
-
recognition.onresult = function (event) {
|
|
31492
|
-
var last = event.results.length - 1;
|
|
31493
|
-
var text = event.results[last][0].transcript;
|
|
31494
|
-
if (props.isDebug) {
|
|
31495
|
-
console.log("你说的是: " + text);
|
|
31496
|
-
}
|
|
31497
|
-
if (state.recorderCode === 0) {
|
|
31498
|
-
discernHere(text);
|
|
31499
|
-
}
|
|
31500
|
-
};
|
|
31501
|
-
recognition.onend = function () {
|
|
31502
|
-
console.log("Recognition ended.");
|
|
31503
|
-
// 这里可以采取措施,比如重新启动语音识别
|
|
31504
|
-
restartRecognition();
|
|
31505
|
-
// alert("监听到1分钟未说话,刷新页面后可使用!");
|
|
31506
|
-
};
|
|
31507
|
-
recognition.onerror = function (event) {
|
|
31508
|
-
console.error("Error occurred in recognition: " + event.error);
|
|
31509
|
-
// 这里也可以采取措施,比如重新启动语音识别
|
|
31510
|
-
restartRecognition();
|
|
34582
|
+
const getAnswer = text => {
|
|
34583
|
+
// 拿到的语音进行问答
|
|
34584
|
+
let option = {
|
|
34585
|
+
searchText: text,
|
|
34586
|
+
use_tts: "True",
|
|
34587
|
+
coze_info: props.cozeInfo || {}
|
|
31511
34588
|
};
|
|
31512
|
-
|
|
31513
|
-
|
|
31514
|
-
|
|
31515
|
-
|
|
31516
|
-
|
|
31517
|
-
|
|
31518
|
-
|
|
31519
|
-
// 唤醒后的录音
|
|
31520
|
-
const setRecording = () => {
|
|
31521
|
-
// state.recorder.stop();
|
|
31522
|
-
state.recorder.start().then(() => {
|
|
31523
|
-
window.setTimeout(() => {
|
|
31524
|
-
let wavBlob = state.recorder.getWAVBlob();
|
|
31525
|
-
let newbolb = new Blob([wavBlob], {
|
|
31526
|
-
type: "audio/wav"
|
|
31527
|
-
});
|
|
31528
|
-
//获取当时时间戳作为文件名
|
|
31529
|
-
let fileOfBlob = new File([newbolb], new Date().getTime() + ".wav");
|
|
31530
|
-
|
|
31531
|
-
// 本地播放录音文件流
|
|
31532
|
-
if (props.isDebug) {
|
|
31533
|
-
let sound = new Audio();
|
|
31534
|
-
let src = URL.createObjectURL(fileOfBlob);
|
|
31535
|
-
sound.src = src;
|
|
31536
|
-
sound.play();
|
|
34589
|
+
state.recorderCode = 0;
|
|
34590
|
+
searchText(option).then(q => {
|
|
34591
|
+
let data = q.data;
|
|
34592
|
+
if (data && data.code == 200) {
|
|
34593
|
+
// 讲回答后的内容返回给业务系统
|
|
34594
|
+
if (props.searchTextCallback) {
|
|
34595
|
+
props.searchTextCallback(data.detail[0]);
|
|
31537
34596
|
}
|
|
31538
|
-
|
|
31539
|
-
|
|
31540
|
-
|
|
31541
|
-
|
|
31542
|
-
|
|
31543
|
-
|
|
31544
|
-
|
|
31545
|
-
|
|
31546
|
-
|
|
31547
|
-
|
|
31548
|
-
|
|
31549
|
-
let text = audioToText;
|
|
31550
|
-
|
|
31551
|
-
// let text = "回到2023年7月22日时刻";
|
|
31552
|
-
|
|
31553
|
-
// 拿到的语音进行问答
|
|
31554
|
-
let option = {
|
|
31555
|
-
searchText: text,
|
|
31556
|
-
use_tts: "True",
|
|
31557
|
-
coze_info: props.cozeInfo || {}
|
|
31558
|
-
};
|
|
31559
|
-
searchText(option).then(q => {
|
|
31560
|
-
let data = q.data;
|
|
31561
|
-
if (data && data.code == 200) {
|
|
31562
|
-
// 检索场景
|
|
31563
|
-
// matching(text, data.detail[0]);
|
|
31564
|
-
|
|
31565
|
-
// 讲回答后的内容返回给业务系统
|
|
31566
|
-
if (props.searchTextCallback) {
|
|
31567
|
-
props.searchTextCallback(data.detail[0]);
|
|
31568
|
-
}
|
|
31569
|
-
let {
|
|
31570
|
-
ttsMaleAddress
|
|
31571
|
-
} = data.detail[0];
|
|
31572
|
-
// 播放回答内容和进行小G动作
|
|
31573
|
-
if (ttsMaleAddress) {
|
|
31574
|
-
playAudio(ttsMaleAddress, "sys");
|
|
31575
|
-
}
|
|
31576
|
-
// if (state.findMatch && state.findMatch.fun) {
|
|
31577
|
-
// if (state.findMatch.trigger == "together") {
|
|
31578
|
-
// state.findMatch.fun({
|
|
31579
|
-
// ...data.detail[0],
|
|
31580
|
-
// });
|
|
31581
|
-
// }
|
|
31582
|
-
// }
|
|
31583
|
-
}
|
|
31584
|
-
}).catch(err => {
|
|
31585
|
-
console.error("问答错误");
|
|
31586
|
-
console.error(err);
|
|
31587
|
-
});
|
|
31588
|
-
}
|
|
31589
|
-
}).catch(err => {
|
|
31590
|
-
console.error("语音识别错误");
|
|
31591
|
-
console.error(err);
|
|
31592
|
-
});
|
|
31593
|
-
|
|
31594
|
-
// recognition.start();
|
|
31595
|
-
}, 5 * 1000);
|
|
31596
|
-
});
|
|
31597
|
-
};
|
|
31598
|
-
const sendRecorder = () => {
|
|
31599
|
-
let wavBlob = state.recorder.getWAVBlob();
|
|
31600
|
-
let newbolb = new Blob([wavBlob], {
|
|
31601
|
-
type: "audio/wav"
|
|
34597
|
+
let {
|
|
34598
|
+
ttsMaleAddress
|
|
34599
|
+
} = data.detail[0];
|
|
34600
|
+
// 播放回答内容和进行小G动作
|
|
34601
|
+
if (ttsMaleAddress) {
|
|
34602
|
+
playAudio(ttsMaleAddress, "sys");
|
|
34603
|
+
}
|
|
34604
|
+
}
|
|
34605
|
+
}).catch(err => {
|
|
34606
|
+
console.error("问答错误");
|
|
34607
|
+
console.error(err);
|
|
31602
34608
|
});
|
|
31603
|
-
//获取当时时间戳作为文件名
|
|
31604
|
-
let fileOfBlob = new File([newbolb], new Date().getTime() + ".wav");
|
|
31605
|
-
|
|
31606
|
-
// 本地播放录音文件流
|
|
31607
|
-
// let sound = new Audio();
|
|
31608
|
-
// let src = URL.createObjectURL(fileOfBlob);
|
|
31609
|
-
// sound.src = src;
|
|
31610
|
-
// sound.play();
|
|
31611
|
-
// wenetWs.send(fileOfBlob);
|
|
31612
|
-
|
|
31613
|
-
if (wenetWs.readyState == 1) {
|
|
31614
|
-
wenetWs.send(fileOfBlob);
|
|
31615
|
-
}
|
|
31616
|
-
state.recorder.start();
|
|
31617
34609
|
};
|
|
31618
34610
|
const searchText = data => {
|
|
31619
34611
|
let url = props.qaServer;
|
|
31620
34612
|
return lib_axios.post(url, data);
|
|
31621
34613
|
};
|
|
31622
|
-
const uploadWavFile = data => {
|
|
31623
|
-
let url = props.audioServer;
|
|
31624
|
-
return lib_axios.post(url, data);
|
|
31625
|
-
};
|
|
31626
34614
|
const iAmHere = () => {
|
|
31627
34615
|
var url = audioConfig.here;
|
|
31628
34616
|
window.setTimeout(() => {
|
|
31629
34617
|
playAudio(url);
|
|
31630
|
-
},
|
|
31631
|
-
};
|
|
31632
|
-
const componentDidMount = () => {
|
|
31633
|
-
pCanvas = document.getElementById("playChart");
|
|
31634
|
-
pCtx = pCanvas.getContext("2d");
|
|
31635
|
-
};
|
|
31636
|
-
const drawPlay = () => {
|
|
31637
|
-
// 用requestAnimationFrame稳定60fps绘制
|
|
31638
|
-
drawPlayId = requestAnimationFrame(drawPlay);
|
|
31639
|
-
|
|
31640
|
-
// 实时获取音频大小数据
|
|
31641
|
-
let dataArray = state.recorder2.getRecordAnalyseData(),
|
|
31642
|
-
bufferLength = dataArray.length;
|
|
31643
|
-
|
|
31644
|
-
// 填充背景色
|
|
31645
|
-
pCtx.fillStyle = "rgb(200, 200, 200)";
|
|
31646
|
-
pCtx.fillRect(0, 0, pCanvas.width, pCanvas.height);
|
|
31647
|
-
|
|
31648
|
-
// 设定波形绘制颜色
|
|
31649
|
-
pCtx.lineWidth = 2;
|
|
31650
|
-
pCtx.strokeStyle = "rgb(0, 0, 0)";
|
|
31651
|
-
pCtx.beginPath();
|
|
31652
|
-
var sliceWidth = pCanvas.width * 1.0 / bufferLength,
|
|
31653
|
-
// 一个点占多少位置,共有bufferLength个点要绘制
|
|
31654
|
-
x = 0; // 绘制点的x轴位置
|
|
31655
|
-
|
|
31656
|
-
for (var i = 0; i < bufferLength; i++) {
|
|
31657
|
-
var v = dataArray[i] / 128.0;
|
|
31658
|
-
var y = v * pCanvas.height / 2;
|
|
31659
|
-
if (i === 0) {
|
|
31660
|
-
// 第一个点
|
|
31661
|
-
pCtx.moveTo(x, y);
|
|
31662
|
-
} else {
|
|
31663
|
-
// 剩余的点
|
|
31664
|
-
pCtx.lineTo(x, y);
|
|
31665
|
-
}
|
|
31666
|
-
// 依次平移,绘制所有点
|
|
31667
|
-
x += sliceWidth;
|
|
31668
|
-
}
|
|
31669
|
-
pCtx.lineTo(pCanvas.width, pCanvas.height / 2);
|
|
31670
|
-
pCtx.stroke();
|
|
31671
|
-
};
|
|
31672
|
-
const moveElement = event => {
|
|
31673
|
-
event.preventDefault();
|
|
31674
|
-
let ElWrap = contentRef.value;
|
|
31675
|
-
let X = event.clientX - ElWrap.offsetLeft;
|
|
31676
|
-
let Y = event.clientY - ElWrap.offsetTop;
|
|
31677
|
-
// 添加鼠标移动事件
|
|
31678
|
-
document.addEventListener("mousemove", move);
|
|
31679
|
-
function move(event) {
|
|
31680
|
-
ElWrap.style.left = event.clientX - X + "px";
|
|
31681
|
-
ElWrap.style.top = event.clientY - Y + "px";
|
|
31682
|
-
}
|
|
31683
|
-
// 添加鼠标抬起事件,鼠标抬起,将事件移除
|
|
31684
|
-
document.addEventListener("mouseup", () => {
|
|
31685
|
-
document.removeEventListener("mousemove", move);
|
|
31686
|
-
});
|
|
34618
|
+
}, 500);
|
|
31687
34619
|
};
|
|
31688
34620
|
const closeQaDrawer = () => {
|
|
31689
34621
|
if (state.isRequireIng) {
|
|
@@ -31706,15 +34638,12 @@ const _hoisted_19 = ["src"];
|
|
|
31706
34638
|
val: text,
|
|
31707
34639
|
qaType: "local"
|
|
31708
34640
|
});
|
|
31709
|
-
window.setTimeout(() => {
|
|
31710
|
-
componentDidMount();
|
|
31711
|
-
}, 200);
|
|
31712
34641
|
} else {
|
|
31713
34642
|
closeQaDrawer();
|
|
31714
34643
|
}
|
|
31715
34644
|
};
|
|
31716
34645
|
const scrollToBottom = () => {
|
|
31717
|
-
scrollContainer.value.scrollTop = scrollContainer.value
|
|
34646
|
+
scrollContainer.value.scrollTop = scrollContainer.value?.scrollHeight;
|
|
31718
34647
|
};
|
|
31719
34648
|
const resetQa = () => {
|
|
31720
34649
|
let lastStep = state.list[state.list.length - 2];
|
|
@@ -31756,31 +34685,11 @@ const _hoisted_19 = ["src"];
|
|
|
31756
34685
|
}
|
|
31757
34686
|
}, 50);
|
|
31758
34687
|
};
|
|
31759
|
-
|
|
31760
|
-
// 关键字匹配
|
|
31761
|
-
const matching = (text, params) => {
|
|
31762
|
-
let findMatch = {};
|
|
31763
|
-
state.findMatch = {};
|
|
31764
|
-
if (props.eventFun && props.eventFun.length) {
|
|
31765
|
-
findMatch = props.eventFun.find(q => {
|
|
31766
|
-
return q.keywords.some(t => text.indexOf(t) != -1);
|
|
31767
|
-
});
|
|
31768
|
-
}
|
|
31769
|
-
if (findMatch) {
|
|
31770
|
-
state.findMatch = {
|
|
31771
|
-
...findMatch,
|
|
31772
|
-
params
|
|
31773
|
-
};
|
|
31774
|
-
}
|
|
31775
|
-
};
|
|
31776
34688
|
const sendAi = () => {
|
|
31777
34689
|
if (state.isRequireIng) {
|
|
31778
34690
|
return;
|
|
31779
34691
|
}
|
|
31780
34692
|
let text = state.input;
|
|
31781
|
-
|
|
31782
|
-
// 执行方法匹配
|
|
31783
|
-
matching(text);
|
|
31784
34693
|
if (text) {
|
|
31785
34694
|
let param = {
|
|
31786
34695
|
type: 2,
|
|
@@ -31799,7 +34708,7 @@ const _hoisted_19 = ["src"];
|
|
|
31799
34708
|
};
|
|
31800
34709
|
state.list.push({
|
|
31801
34710
|
type: 1,
|
|
31802
|
-
value: `${props.waitTxt} <span class=
|
|
34711
|
+
value: `${props.waitTxt} <span class="ellipsisText"></span>`
|
|
31803
34712
|
});
|
|
31804
34713
|
scrollToBottom();
|
|
31805
34714
|
state.isRequireIng = true;
|
|
@@ -31822,10 +34731,61 @@ const _hoisted_19 = ["src"];
|
|
|
31822
34731
|
state.list.splice(state.list.length - 1, 1);
|
|
31823
34732
|
state.list.push({
|
|
31824
34733
|
type: 1,
|
|
31825
|
-
value: `<span style=
|
|
34734
|
+
value: `<span style="color:red">问答出现错误,请联系管理员!</span> `
|
|
31826
34735
|
});
|
|
31827
34736
|
});
|
|
31828
34737
|
};
|
|
34738
|
+
const startRecording = () => {
|
|
34739
|
+
state.isAudio = "loading";
|
|
34740
|
+
state.recorderCode = 0;
|
|
34741
|
+
closeRecognition();
|
|
34742
|
+
const recognition = wsconnecter.wsStart("offline");
|
|
34743
|
+
if (recognition === 1) {
|
|
34744
|
+
state.isAudio = "start";
|
|
34745
|
+
state.recorder.resume();
|
|
34746
|
+
if (waveRef.value) {
|
|
34747
|
+
//创建音频可视化图形绘制对象
|
|
34748
|
+
wave.value = recorder_core_default().WaveView({
|
|
34749
|
+
elem: waveRef.value
|
|
34750
|
+
});
|
|
34751
|
+
}
|
|
34752
|
+
} else {
|
|
34753
|
+
startRecording();
|
|
34754
|
+
}
|
|
34755
|
+
};
|
|
34756
|
+
const stopRecording = () => {
|
|
34757
|
+
state.isAudio = "end";
|
|
34758
|
+
wave.value = null;
|
|
34759
|
+
closeRecognition();
|
|
34760
|
+
startRecognition();
|
|
34761
|
+
};
|
|
34762
|
+
|
|
34763
|
+
//****************************************公共方法************************************
|
|
34764
|
+
const copyTextToClipboard = text => {
|
|
34765
|
+
const inputElement = document.createElement("input");
|
|
34766
|
+
inputElement.value = text;
|
|
34767
|
+
document.body.appendChild(inputElement);
|
|
34768
|
+
inputElement.select();
|
|
34769
|
+
document.execCommand("copy");
|
|
34770
|
+
document.body.removeChild(inputElement);
|
|
34771
|
+
};
|
|
34772
|
+
const moveElement = event => {
|
|
34773
|
+
event.preventDefault();
|
|
34774
|
+
let ElWrap = contentRef.value;
|
|
34775
|
+
let X = event.clientX - ElWrap.offsetLeft;
|
|
34776
|
+
let Y = event.clientY - ElWrap.offsetTop;
|
|
34777
|
+
// 添加鼠标移动事件
|
|
34778
|
+
document.addEventListener("mousemove", move);
|
|
34779
|
+
function move(event) {
|
|
34780
|
+
ElWrap.style.left = event.clientX - X + "px";
|
|
34781
|
+
ElWrap.style.top = event.clientY - Y + "px";
|
|
34782
|
+
}
|
|
34783
|
+
|
|
34784
|
+
// 添加鼠标抬起事件,鼠标抬起,将事件移除
|
|
34785
|
+
document.addEventListener("mouseup", () => {
|
|
34786
|
+
document.removeEventListener("mousemove", move);
|
|
34787
|
+
});
|
|
34788
|
+
};
|
|
31829
34789
|
|
|
31830
34790
|
// 语音播放
|
|
31831
34791
|
const playAudio = (audioUrl, type) => {
|
|
@@ -31866,74 +34826,8 @@ const _hoisted_19 = ["src"];
|
|
|
31866
34826
|
});
|
|
31867
34827
|
}, 100);
|
|
31868
34828
|
};
|
|
31869
|
-
const startRecording = () => {
|
|
31870
|
-
state.isAudio = "loading";
|
|
31871
|
-
js_audio_recorder_default().getPermission().then(() => {
|
|
31872
|
-
state.recorder2.start().then(() => {
|
|
31873
|
-
state.isAudio = "start";
|
|
31874
|
-
console.log("开始录音");
|
|
31875
|
-
drawPlay();
|
|
31876
|
-
// 开始录音
|
|
31877
|
-
}, error => {
|
|
31878
|
-
state.isAudio = "end";
|
|
31879
|
-
// 出错了
|
|
31880
|
-
console.log(`${error} : 1`);
|
|
31881
|
-
});
|
|
31882
|
-
}, error => {
|
|
31883
|
-
state.isAudio = "end";
|
|
31884
|
-
// this.$message({
|
|
31885
|
-
// message: "请先允许该网页使用麦克风",
|
|
31886
|
-
// type: "info",
|
|
31887
|
-
// });
|
|
31888
|
-
console.log(`${error} : 2`);
|
|
31889
|
-
});
|
|
31890
|
-
};
|
|
31891
|
-
const stopRecording = () => {
|
|
31892
|
-
state.isAudio = "end";
|
|
31893
|
-
uploadWAVData();
|
|
31894
|
-
};
|
|
31895
|
-
const uploadWAVData = () => {
|
|
31896
|
-
var wavBlob = state.recorder2.getWAVBlob();
|
|
31897
|
-
var formData = new FormData();
|
|
31898
|
-
const newbolb = new Blob([wavBlob], {
|
|
31899
|
-
type: "audio/wav"
|
|
31900
|
-
});
|
|
31901
|
-
//获取当时时间戳作为文件名
|
|
31902
|
-
const fileOfBlob = new File([newbolb], new Date().getTime() + ".wav");
|
|
31903
|
-
|
|
31904
|
-
// 本地播放录音文件流
|
|
31905
|
-
// let sound = new Audio();
|
|
31906
|
-
// let src = URL.createObjectURL(fileOfBlob);
|
|
31907
|
-
// sound.src = src;
|
|
31908
|
-
// sound.play();
|
|
31909
|
-
// return;
|
|
31910
|
-
|
|
31911
|
-
formData.append("modelName", "medium");
|
|
31912
|
-
formData.append("audio", fileOfBlob);
|
|
31913
|
-
uploadWavFile(formData).then(result => {
|
|
31914
|
-
let res = result.data;
|
|
31915
|
-
if (res.code == 200) {
|
|
31916
|
-
let {
|
|
31917
|
-
answer: audioToText
|
|
31918
|
-
} = res.detail.content;
|
|
31919
|
-
state.input = audioToText;
|
|
31920
|
-
}
|
|
31921
|
-
}).catch(err => {
|
|
31922
|
-
let info = err.response.data.detail.error;
|
|
31923
|
-
state.input = info;
|
|
31924
|
-
});
|
|
31925
|
-
};
|
|
31926
|
-
const copyTextToClipboard = text => {
|
|
31927
|
-
const inputElement = document.createElement("input");
|
|
31928
|
-
inputElement.value = text;
|
|
31929
|
-
document.body.appendChild(inputElement);
|
|
31930
|
-
inputElement.select();
|
|
31931
|
-
document.execCommand("copy");
|
|
31932
|
-
document.body.removeChild(inputElement);
|
|
31933
|
-
};
|
|
31934
34829
|
__expose({
|
|
31935
|
-
searchText
|
|
31936
|
-
uploadWavFile
|
|
34830
|
+
searchText
|
|
31937
34831
|
});
|
|
31938
34832
|
return (_ctx, _cache) => {
|
|
31939
34833
|
return (0,external_commonjs_vue_commonjs2_vue_root_Vue_.openBlock)(), (0,external_commonjs_vue_commonjs2_vue_root_Vue_.createElementBlock)("div", {
|
|
@@ -32014,8 +34908,10 @@ const _hoisted_19 = ["src"];
|
|
|
32014
34908
|
maxRows: 4
|
|
32015
34909
|
},
|
|
32016
34910
|
onKeyup: (0,external_commonjs_vue_commonjs2_vue_root_Vue_.withKeys)(sendAi, ["enter"])
|
|
32017
|
-
}, "\r\n ", 544), [[external_commonjs_vue_commonjs2_vue_root_Vue_.vModelText, state.input]]), (0,external_commonjs_vue_commonjs2_vue_root_Vue_.createElementVNode)("div", _hoisted_13, [props.useAudio ? ((0,external_commonjs_vue_commonjs2_vue_root_Vue_.openBlock)(), (0,external_commonjs_vue_commonjs2_vue_root_Vue_.createElementBlock)("p", _hoisted_14, [(0,external_commonjs_vue_commonjs2_vue_root_Vue_.createElementVNode)("
|
|
34911
|
+
}, "\r\n ", 544), [[external_commonjs_vue_commonjs2_vue_root_Vue_.vModelText, state.input]]), (0,external_commonjs_vue_commonjs2_vue_root_Vue_.createElementVNode)("div", _hoisted_13, [props.useAudio ? ((0,external_commonjs_vue_commonjs2_vue_root_Vue_.openBlock)(), (0,external_commonjs_vue_commonjs2_vue_root_Vue_.createElementBlock)("p", _hoisted_14, [(0,external_commonjs_vue_commonjs2_vue_root_Vue_.createElementVNode)("span", {
|
|
32018
34912
|
id: "playChart",
|
|
34913
|
+
ref_key: "waveRef",
|
|
34914
|
+
ref: waveRef,
|
|
32019
34915
|
class: (0,external_commonjs_vue_commonjs2_vue_root_Vue_.normalizeClass)([state.isAudio == 'start' ? 'show' : 'hiddle'])
|
|
32020
34916
|
}, null, 2), state.isAudio == 'end' ? ((0,external_commonjs_vue_commonjs2_vue_root_Vue_.openBlock)(), (0,external_commonjs_vue_commonjs2_vue_root_Vue_.createElementBlock)("img", {
|
|
32021
34917
|
key: 0,
|
|
@@ -32048,15 +34944,15 @@ const _hoisted_19 = ["src"];
|
|
|
32048
34944
|
});
|
|
32049
34945
|
;// CONCATENATED MODULE: ./src/package/src/main.vue?vue&type=script&setup=true&lang=js
|
|
32050
34946
|
|
|
32051
|
-
;// CONCATENATED MODULE: ./node_modules/mini-css-extract-plugin/dist/loader.js??clonedRuleSet-54.use[0]!./node_modules/css-loader/dist/cjs.js??clonedRuleSet-54.use[1]!./node_modules/vue-loader/dist/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-54.use[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/package/src/main.vue?vue&type=style&index=0&id=
|
|
34947
|
+
;// CONCATENATED MODULE: ./node_modules/mini-css-extract-plugin/dist/loader.js??clonedRuleSet-54.use[0]!./node_modules/css-loader/dist/cjs.js??clonedRuleSet-54.use[1]!./node_modules/vue-loader/dist/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-54.use[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/package/src/main.vue?vue&type=style&index=0&id=16bd8825&lang=css
|
|
32052
34948
|
// extracted by mini-css-extract-plugin
|
|
32053
34949
|
|
|
32054
|
-
;// CONCATENATED MODULE: ./src/package/src/main.vue?vue&type=style&index=0&id=
|
|
34950
|
+
;// CONCATENATED MODULE: ./src/package/src/main.vue?vue&type=style&index=0&id=16bd8825&lang=css
|
|
32055
34951
|
|
|
32056
|
-
;// CONCATENATED MODULE: ./node_modules/mini-css-extract-plugin/dist/loader.js??clonedRuleSet-74.use[0]!./node_modules/css-loader/dist/cjs.js??clonedRuleSet-74.use[1]!./node_modules/vue-loader/dist/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-74.use[2]!./node_modules/less-loader/dist/cjs.js??clonedRuleSet-74.use[3]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/package/src/main.vue?vue&type=style&index=1&id=
|
|
34952
|
+
;// CONCATENATED MODULE: ./node_modules/mini-css-extract-plugin/dist/loader.js??clonedRuleSet-74.use[0]!./node_modules/css-loader/dist/cjs.js??clonedRuleSet-74.use[1]!./node_modules/vue-loader/dist/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-74.use[2]!./node_modules/less-loader/dist/cjs.js??clonedRuleSet-74.use[3]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/package/src/main.vue?vue&type=style&index=1&id=16bd8825&lang=less&scoped=true
|
|
32057
34953
|
// extracted by mini-css-extract-plugin
|
|
32058
34954
|
|
|
32059
|
-
;// CONCATENATED MODULE: ./src/package/src/main.vue?vue&type=style&index=1&id=
|
|
34955
|
+
;// CONCATENATED MODULE: ./src/package/src/main.vue?vue&type=style&index=1&id=16bd8825&lang=less&scoped=true
|
|
32060
34956
|
|
|
32061
34957
|
// EXTERNAL MODULE: ./node_modules/vue-loader/dist/exportHelper.js
|
|
32062
34958
|
var exportHelper = __webpack_require__(6262);
|
|
@@ -32068,7 +34964,7 @@ var exportHelper = __webpack_require__(6262);
|
|
|
32068
34964
|
|
|
32069
34965
|
|
|
32070
34966
|
|
|
32071
|
-
const __exports__ = /*#__PURE__*/(0,exportHelper/* default */.A)(mainvue_type_script_setup_true_lang_js, [['__scopeId',"data-v-
|
|
34967
|
+
const __exports__ = /*#__PURE__*/(0,exportHelper/* default */.A)(mainvue_type_script_setup_true_lang_js, [['__scopeId',"data-v-16bd8825"]])
|
|
32072
34968
|
|
|
32073
34969
|
/* harmony default export */ var main = (__exports__);
|
|
32074
34970
|
;// CONCATENATED MODULE: ./src/package/index.js
|