12345678910 |
- /**
- * @copyright © 未来飞马 © 未来全栈 www.fmode.cn
- * 版权所有 © 未来飞马 © 江西脑控科技有限公司 Copyright © Fmode Technology Co., Ltd.
- * 保留所有权利 All Rights Reserved.
- * /home/ryan/workspace/nova/nova-admin/dist/fmode-ng/esm2022/lib/aigc/voice/fmode-voice.service.mjs
- */
- import{Injectable}from"@angular/core";import Recorder from"recorder-core";import"recorder-core/src/engine/pcm";import"recorder-core/src/engine/wav";import"recorder-core/src/extensions/waveview";import CryptoJS from"crypto-js";import{pcmtoWav}from"./lib/pcm2wav";import{convertFrameBufferToBase64,resampleBuffer}from"./lib/resample";import{WebSpeech}from"./class-asr";import{Platform}from"@ionic/angular";import{Diagnostic}from"@awesome-cordova-plugins/diagnostic/ngx";import*as i0 from"@angular/core";import*as i1 from"@ionic/angular";import*as i2 from"@awesome-cordova-plugins/diagnostic/ngx";export class FmodeVoiceService{constructor(t,e){this.platform=t,this.diagnostic=e,this.webSpeech=WebSpeech,this.isUserFinish=!1,this.recordWavBlob=null,this.recordPcmBlob=null,this.recordDuration=0,this.recordType="pcm",this.encodingType="raw",this.connStatus="",this.btnStatus="UNDEFINED",this.resultText="",this.resultTextTemp="",this.APPID="50f4a46c",this.API_SECRET="NzFlNmFhZDJjMDNkZGM3NzI0Mzg2OGNm",this.API_KEY="106ddc40dfd4b9ca6d7b47c70fada749",this.durationStr="00:00",this.duration=0,this.requestPermission()}toggleRecord(){console.log(this.btnStatus),"UNDEFINED"===this.btnStatus||"CLOSED"===this.btnStatus?this.startTalk():"CONNECTING"!==this.btnStatus&&"OPEN"!==this.btnStatus||this.finishTalk()}finishTalk(){this.isUserFinish=!0,this.onBeforeFinishTalk&&this.onBeforeFinishTalk(),this.recordStop()}async startTalk(t){this.resultText="",this.resultTextTemp="",this.onBeforeStartTalk&&this.onBeforeStartTalk(),event?.preventDefault(),await this.openWithPriviledge(),setTimeout((()=>{this.connectWebSocket()}),100),this.startCountdown(),this.onAfterStartTalk&&this.onAfterStartTalk()}cancelTalk(){this.onBeforeCancelTalk&&this.onBeforeCancelTalk(),this.recordStop(),this.iatWS?.close(),this.resultText=null,this.onAfterCancelTalk&&this.onAfterCancelTalk()}async recordStart(){this.createRecorder(),await this.openWithPriviledge(),this.recorder.start(),this.changeBtnStatus("OPEN"),this.onAfterRecordStart&&this.onAfterRecordStart()}recordStop(){return new Promise((t=>{clearInterval(this.countdownInterval),this.changeBtnStatus("CLOSED"),this.recorder?.stop((async(e,i)=>{try{this.iatWS.send(JSON.stringify({data:{status:2,format:"audio/L16;rate=16000",encoding:this.encodingType,audio:""}}))}catch(t){}let s=(window.URL||webkitURL).createObjectURL(e);console.log(e,s,"时长:"+i+"ms"),this.recordPcmBlob=e,this.recordWavBlob=await this.pcmBlobToWavBlob(e,44100),console.log("this.recordWavBlob",this.recordWavBlob),setTimeout((()=>{this.isUserFinish&&(this.onAfterFinishTalk&&this.onAfterFinishTalk(),this.isUserFinish=!1)}),2e3),this.recorder?.close(),this.recorder=null,console.log("localUrl",s),t(!0)}),(e=>{console.log("录音失败:"+e),this.recorder.close(),this.recorder=null,t(null)}))}))}playRecord(){this.playPCM(this.recordPcmBlob,44100)}async pcmBlobToWavBlob(t,e){return new Promise((i=>{let s=new FileReader;s.onload=function(t){let s=t.target.result,o=pcmtoWav(s,e,1,16);i(o)},s.readAsArrayBuffer(t)}))}async playPCM(t,e){let i=await this.pcmBlobToWavBlob(t,e),s=window.URL.createObjectURL(i),o=new Audio;o.src=s,o.play()}async playBuffers(){let t=await this.BuffersToBlob(this.buffers);this.playPCM(t,44100)}BuffersToBlob(t){let e=[];return t.forEach((t=>{t.forEach((t=>{e.push(t)}))})),new Blob([e],{type:"audio/pcm"})}splitAudioData(t){const e=1280,i=Math.ceil(t.length/e),s=[];for(let o=0;o<i;o++){const i=o*e,r=i+e,a=t.slice(i,r);s.push(a)}return s}BufferToBlob(t){return new Blob([t],{type:"audio/pcm"})}createRecorder(){this.recorder||(this.recorder=Recorder({type:this.recordType,sampleRate:44100,bitRate:16,onProcess:(t,e,i,s,o,r)=>{let a=t.length&&t[t.length-1];if(this.buffers=t,a=resampleBuffer(a,44100,16e3),this.iatWS.readyState===this.iatWS.OPEN){if(this.disableASR)return;this.iatWS.send(JSON.stringify({data:{status:1,format:"audio/L16;rate=16000",encoding:this.encodingType,audio:convertFrameBufferToBase64(a)}}))}this.waveClient?.input(t[t.length-1],e,s)}}))}async openWithPriviledge(){return console.log(this.btnStatus),await this.requestPermission(),this.createRecorder(),!!Recorder.IsOpen()||new Promise((t=>{this.recorder.open((()=>{let e=document.querySelector(".record-wave");e&&(console.log(e),Recorder.WaveView&&(this.waveClient=Recorder.WaveView({elem:".record-wave"}))),t(!0)}),((t,e)=>{console.log((e?"UserNotAllow,":"")+"无法录音:"+t)}))}))}getWebSocketUrl(){let t="wss://iat-api.xfyun.cn/v2/iat",e="iat-api.xfyun.cn",i=this.API_KEY,s=this.API_SECRET,o=(new Date).toUTCString(),r=`host: ${e}\ndate: ${o}\nGET /v2/iat HTTP/1.1`,a=CryptoJS.HmacSHA256(r,s),n=CryptoJS.enc.Base64.stringify(a);return t=`${t}?authorization=${btoa(`api_key="${i}", algorithm="hmac-sha256", headers="host date request-line", signature="${n}"`)}&date=${o}&host=${e}`,t}toBase64(t){for(var e="",i=new Uint8Array(t),s=i.byteLength,o=0;o<s;o++)e+=String.fromCharCode(i[o]);return window.btoa(e)}countTimer(){this.duration++;let t=String(parseInt(String(this.duration/60))).padStart(2,"0"),e=String((this.duration%60).toFixed(0)).padStart(2,"0"),i=t+":"+e;this.durationStr=i,this.connStatus=`录音中(${this.durationStr})`,console.log(this.duration,t,e),console.log(this.duration),console.log(i),this.onDurationStrChange&&this.onDurationStrChange(i)}startCountdown(){this.recordDuration=0,this.durationInterval&&clearInterval(this.durationInterval),this.countdownInterval=setInterval((()=>{this.recordDuration+=100}),100),this.now=new Date,this.duration=0,this.countdownInterval&&clearInterval(this.countdownInterval),this.countdownInterval=setInterval((()=>{this.countTimer()}),1e3)}changeBtnStatus(t){this.btnStatus=t,"CONNECTING"===t?this.connStatus="建立连接中":"OPEN"===t||("CLOSING"===t?this.connStatus="关闭连接中":"CLOSED"===t&&(this.connStatus="开始录音"))}renderResult(t){let e=JSON.parse(t);if(e.data&&e.data.result){let t=e.data.result,i="",s=t.ws;for(let t=0;t<s.length;t++)i+=s[t].cw[0].w,console.log(i);t.pgs?("apd"===t.pgs&&(this.resultText=this.resultTextTemp),this.resultTextTemp=this.resultText+i):this.resultText=this.resultText+i,this.resultTextTemp||this.resultText,console.log("diff temp",this.resultTextTemp),console.log("diff result",this.resultText),this.onInputChange&&this.onInputChange(this.getUserInput())}0===e.code&&2===e.data.status&&this.iatWS.close(),0!==e.code&&(this.iatWS.close(),console.error(e))}getUserInput(){return""+(this.resultTextTemp||this.resultText)}connectWebSocket(){console.log("connectWebSocket");const t=this.getWebSocketUrl();if("WebSocket"in window)this.iatWS=new WebSocket(t);else if(!("MozWebSocket"in window))return void alert("浏览器不支持WebSocket");console.log("connectWebSocket",this.btnStatus),this.changeBtnStatus("CONNECTING"),this.iatWS.onopen=t=>{this.recordStart();var e={common:{app_id:this.APPID},business:{language:"zh_cn",domain:"iat",accent:"mandarin",vad_eos:5e3,dwa:"wpgs"},data:{status:0,format:"audio/L16;rate=16000",encoding:this.encodingType}};this.iatWS.send(JSON.stringify(e))},this.iatWS.onmessage=t=>{console.log("onmessage"+this.resultText),this.renderResult(t.data)},this.iatWS.onerror=t=>{console.error("error",t),this.recordStop(),this.changeBtnStatus("CLOSED")},this.iatWS.onclose=async t=>{console.log("onclose"+this.resultText),this.reconnectWebsocket()}}async reconnectWebsocket(){this.isUserFinish||this.connectWebSocket()}isCapacitor(){return this.platform.is("capacitor")||this.platform.is("cordova")}async requestPermission(){if(this.isCapacitor())try{await this.requestStoagePermission(),await this.requestCameraPermission(),await this.requestMicPermission(),await this.requestRecordAudioPermission()}catch(t){console.error(t)}}async requestRecordAudioPermission(){let t=await this.diagnostic.requestRuntimePermissions([this.diagnostic.permission.RECORD_AUDIO]);console.log("record permission request:",t)}async requestMicPermission(){let t=await this.diagnostic.isMicrophoneAuthorized();if(console.log("permisson_MIC:",t),!t){await this.diagnostic.requestMicrophoneAuthorization()}}async requestStoagePermission(){let t=await this.diagnostic.isExternalStorageAuthorized();if(console.log("permisson_STORAGE:",t),!t){await this.diagnostic.requestExternalStorageAuthorization()}}async requestCameraPermission(){let t=await this.diagnostic.isCameraAuthorized();if(console.log("permisson_Camera:",t),!t){await this.diagnostic.requestCameraAuthorization()}}static{this.ɵfac=i0.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"17.3.12",ngImport:i0,type:FmodeVoiceService,deps:[{token:i1.Platform},{token:i2.Diagnostic}],target:i0.ɵɵFactoryTarget.Injectable})}static{this.ɵprov=i0.ɵɵngDeclareInjectable({minVersion:"12.0.0",version:"17.3.12",ngImport:i0,type:FmodeVoiceService,providedIn:"root"})}}i0.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"17.3.12",ngImport:i0,type:FmodeVoiceService,decorators:[{type:Injectable,args:[{providedIn:"root"}]}],ctorParameters:()=>[{type:i1.Platform},{type:i2.Diagnostic}]});
- var MODULE_PATH_NEED = `6K+l5paH5Lu25piv5pys6aG555uu55qE5LiA6YOo5YiGIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBDb21wb25lbnRzIGluIEZtb2RlIEluYy4KICAgIOeJiOadg+aJgOaciSDCqSDmnKrmnaXpo57pqawgwqkg5rGf6KW/6ISR5o6n56eR5oqA5pyJ6ZmQ5YWs5Y+4IENvcHlyaWdodCDCqSBGbW9kZSBUZWNobm9sb2d5IENvLiwgTHRkLgogICAg5L+d55WZ5omA5pyJ5p2D5YipIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAgICDkuKXnpoHlnKjmnKrnu4/mjojmnYPnmoTmg4XlhrXkuIvvvIzpgJrov4fku7vkvZXlqpLku4vlpI3liLbmraTmlofku7YgVW5hdXRob3JpemVkIGNvcHlpbmcgb2YgdGhpcyBmaWxlLCB2aWEgYW55IG1lZGl1bSBpcyBzdHJpY3RseSBwcm9oaWJpdGVkCiAgICDor6Xmlofku7bmmK/kuJPmnInnmoTmnLrlr4bmlofku7YgUHJvcHJpZXRhcnkgYW5kIGNvbmZpZGVudGlhbAogICAKICAgIENvcHlyaWdodCAyMDIxLW5vdyBGbW9kZSBJbmMuIHN1cHBvcnRAZm1vZGUuY24uIDE4NjA3MDA3MDczLgogICAg5L+d55WZ5omA5pyJ5p2D5YipIEFsbCByaWdodHMgcmVzZXJ2ZWQuCgogICAgUEFUSDovaG9tZS9yeWFuL3dvcmtzcGFjZS9ub3ZhL25vdmEtYWRtaW4vZGlzdC9mbW9kZS1uZy9lc20yMDIyL2xpYi9haWdjL3ZvaWNlL2Ztb2RlLXZvaWNlLnNlcnZpY2UubWpz`
-
|