@soniox/speech-to-text-web
Version:
Javascript client library for Soniox Speech-to-Text websocket API
2 lines (1 loc) • 7.55 kB
JavaScript
(function(s,o){typeof exports=="object"&&typeof module<"u"?o(exports):typeof define=="function"&&define.amd?define(["exports"],o):(s=typeof globalThis<"u"?globalThis:s||self,o(s["speech-to-text-web"]={}))})(this,function(s){"use strict";var W=Object.defineProperty;var y=(s,o,c)=>o in s?W(s,o,{enumerable:!0,configurable:!0,writable:!0,value:c}):s[o]=c;var i=(s,o,c)=>y(s,typeof o!="symbol"?o+"":o,c);const o=["Init","Finished","Error","Canceled"],c=["RequestingMedia","OpeningWebSocket","Running","FinishingProcessing"],v=["OpeningWebSocket","Running","FinishingProcessing"];function b(d){return o.includes(d)}function f(d){return c.includes(d)}function g(d){return v.includes(d)}const m="wss://stt-rt.soniox.com/transcribe-websocket",p=1e3,R=120,k='{ "type": "finalize" }',w='{ "type": "keepalive" }',E=()=>({apiKey:"",bufferQueueSize:p}),M={echoCancellation:!1,noiseSuppression:!1,autoGainControl:!1,channelCount:1,sampleRate:44100},l=class l{constructor(e){i(this,"_state","Init");i(this,"_options");i(this,"_audioOptions");i(this,"_websocket");i(this,"_mediaRecorder");i(this,"_queuedMessages",[]);i(this,"_keepAliveInterval",null);i(this,"_hasCallback",e=>{var t;return this._options[e]!=null||((t=this._audioOptions)==null?void 0:t[e])!=null});i(this,"_callback",(e,...t)=>{var n,u,r,_;(u=(n=this._options)[e])==null||u.call(n,...t),(_=(r=this._audioOptions)==null?void 0:r[e])==null||_.call(r,...t)});i(this,"start",async e=>{if(f(this._state))throw new Error("SonioxClient is already active");this._audioOptions={...e};let t;if(e.stream!=null)t=e.stream.clone();else{this._setState("RequestingMedia");try{t=await navigator.mediaDevices.getUserMedia({audio:this._audioOptions.audioConstraints?this._audioOptions.audioConstraints:M})}catch(n){this._onError("get_user_media_failed",n==null?void 0:n.toString())}}if(t==null)throw new Error("Failed to create stream");this._mediaRecorder=new MediaRecorder(t,e.mediaRecorderOptions?e.mediaRecorderOptions:{}),this._queuedMessages=[],this._mediaRecorder.addEventListener("dataavailable",this._onMediaRecorderData),this._mediaRecorder.addEventListener("error",this._onMediaRecorderError),this._mediaRecorder.addEventListener("pause",this._onMediaRecorderPause),this._mediaRecorder.addEventListener("stop",this._onMediaRecorderStop),this._mediaRecorder.start(R),this._setState("OpeningWebSocket"),this._websocket=new WebSocket(this._options.webSocketUri??m),this._websocket.addEventListener("open",this._onWebSocketOpen),this._websocket.addEventListener("error",this._onWebSocketError),this._websocket.addEventListener("message",this._onWebSocketMessage)});i(this,"stop",()=>{var e;this._state=="RequestingMedia"||this._state=="OpeningWebSocket"?(this._closeResources(),this._handleFinished()):this._state=="Running"&&(this._setState("FinishingProcessing"),this._closeSource(),(e=this._websocket)==null||e.send(""))});i(this,"cancel",()=>{b(this._state)||(this._closeResources(),this._setState("Canceled"))});i(this,"finalize",()=>{var e;this._state=="RequestingMedia"||this._state=="OpeningWebSocket"?this._queuedMessages.length<(this._options.bufferQueueSize??p)?this._queuedMessages.push(k):this._onError("queue_limit_exceeded","Queue size exceeded before websocket connection was established."):(this._state=="Running"||this._state=="FinishingProcessing")&&((e=this._websocket)==null||e.send(k))});i(this,"_onMediaRecorderData",async e=>{var t;if(this._state==="OpeningWebSocket")this._queuedMessages.length<(this._options.bufferQueueSize??p)?this._queuedMessages.push(e.data):this._onError("queue_limit_exceeded","Queue size exceeded before websocket connection was established.");else if(this._state==="Running"){const n=await e.data.arrayBuffer();(t=this._websocket)==null||t.send(n)}});i(this,"_onMediaRecorderError",e=>{this._onError("media_recorder_error",e.error??"Unknown error")});i(this,"_onMediaRecorderPause",e=>{this.stop()});i(this,"_onMediaRecorderStop",e=>{this.stop()});i(this,"_onWebSocketOpen",e=>{this._onWebSocketOpenAsync(e)});i(this,"_onWebSocketOpenAsync",async e=>{var r,_;if(this._state!=="OpeningWebSocket"||this._audioOptions==null)return;const t=this._audioOptions;let n;if(typeof this._options.apiKey=="function")try{n=await this._options.apiKey()}catch(a){this._onError("api_key_fetch_failed",a==null?void 0:a.toString());return}else n=this._options.apiKey;if(this._state!=="OpeningWebSocket")return;const u={api_key:n,model:t.model,audio_format:t.audioFormat?t.audioFormat:"auto",sample_rate:t.sampleRate,num_channels:t.numChannels,language_hints:t.languageHints,context:t.context,enable_speaker_diarization:t.enableSpeakerDiarization,enable_language_identification:t.enableLanguageIdentification,enable_endpoint_detection:t.enableEndpointDetection,translation:t.translation,client_reference_id:t.clientReferenceId};(r=this._websocket)==null||r.send(JSON.stringify(u));for(const a of this._queuedMessages)(_=this._websocket)==null||_.send(a);if(this._queuedMessages=[],this._setState("Running"),this._callback("onStarted"),this._options.keepAlive){const a=this._options.keepAliveInterval??5e3;this._keepAliveInterval=setInterval(()=>{var S;(this._state==="Running"||this._state==="FinishingProcessing")&&((S=this._websocket)==null||S.send(w))},a)}});i(this,"_onWebSocketError",e=>{g(this._state)&&this._onError("websocket_error","WebSocket error occurred.")});i(this,"_onWebSocketMessage",e=>{if(this._state!="Running"&&this._state!="FinishingProcessing"||this._audioOptions==null)return;const t=JSON.parse(e.data);if(t.error_code!=null||t.error_message!=null){this._onError("api_error",t.error_message,t.error_code);return}this._callback("onPartialResult",t),t.finished&&this._handleFinished()});i(this,"_onError",(e,t,n=void 0)=>{if(this._setState("Error"),this._closeResources(),this._hasCallback("onError"))this._callback("onError",e,t??"Unknown error",n);else throw new Error(`SonioxClient error: ${e}: ${t??"Unknown error"}`)});i(this,"_closeSource",()=>{this._mediaRecorder!=null&&(this._mediaRecorder.removeEventListener("dataavailable",this._onMediaRecorderData),this._mediaRecorder.removeEventListener("error",this._onMediaRecorderError),this._mediaRecorder.removeEventListener("pause",this._onMediaRecorderPause),this._mediaRecorder.removeEventListener("stop",this._onMediaRecorderStop),this._mediaRecorder.stop(),this._mediaRecorder.stream.getTracks().forEach(e=>e.stop()),this._mediaRecorder=null)});i(this,"_closeResources",()=>{this._queuedMessages=[],this._keepAliveInterval!=null&&(clearInterval(this._keepAliveInterval),this._keepAliveInterval=null),this._websocket!=null&&(this._websocket.removeEventListener("open",this._onWebSocketOpen),this._websocket.removeEventListener("error",this._onWebSocketError),this._websocket.removeEventListener("message",this._onWebSocketMessage),this._websocket.close(),this._websocket=null),this._closeSource()});if(!l.isSupported)throw"Soniox Speech-to-Text is not supported on this browser.";this._options={...E(),...e},this._audioOptions=null,this._websocket=null,this._mediaRecorder=null}_setState(e){const t=this._state;this._state=e,this._callback("onStateChange",{oldState:t,newState:e})}get state(){return this._state}_handleFinished(){this._closeResources(),this._setState("Finished"),this._callback("onFinished")}};i(l,"isSupported",!!("WebSocket"in window&&navigator.mediaDevices&&navigator.mediaDevices.getUserMedia));let h=l;const O=h;s.RecordTranscribe=O,s.SonioxClient=h,s.isActiveState=f,s.isInactiveState=b,s.isWebSocketState=g,Object.defineProperty(s,Symbol.toStringTag,{value:"Module"})});