UNPKG

@cloudraker/use-whisper

Version:

React Hook for OpenAI Whisper API with speech recorder and silence removal built-in.

9 lines (6 loc) 5.21 kB
import { d, b, c } from './chunk-HEIBFR64.js'; import { a } from './chunk-OXF5VRB2.js'; import { a as a$1 } from './chunk-E6DUBRF6.js'; import { useRef, useState, useEffect } from 'react'; var ae={apiKey:"",autoStart:!1,autoTranscribe:!0,mode:"transcriptions",nonStop:!1,removeSilence:!1,stopTimeout:5e3,streaming:!1,timeSlice:1e3,onDataAvailable:void 0,onTranscribe:void 0,whisperApiEndpoints:{transcriptions:`${d}/transcriptions`,translations:`${d}/translations`}},ie={stop:void 0},se={blob:void 0,text:void 0},de=K=>{let{apiKey:h,autoStart:U,autoTranscribe:W,mode:T,nonStop:B,removeSilence:j,stopTimeout:q,streaming:k,timeSlice:z,whisperConfig:c$1,onDataAvailable:L,onTranscribe:R,whisperApiEndpoints:p}={...ae,...K};if(!p)throw new Error("whisperApiEndpoints is required and should not have been nullified");p.transcriptions=p?.transcriptions||`${d}/transcriptions`,p.translations=p?.translations||`${d}/translations`;let G=p?.transcriptions||p?.translations;if(!h&&!R&&!G)throw new Error("Either apiKey, whisperApiEndpoints, or onTranscribeCallback is required");let d$1=useRef([]),i=useRef(),s=useRef(),t=useRef(),a$2=useRef(),l=useRef(ie),[J,A]=useState(!1),[N,C]=useState(!1),[Q,b$1]=useState(!1),[V,m]=useState(se);useEffect(()=>()=>{d$1.current&&(d$1.current=[]),i.current&&(i.current.flush(),i.current=void 0),t.current&&(t.current.destroy(),t.current=void 0),y("stop"),s.current&&(s.current.off("speaking",E),s.current.off("stopped_speaking",v)),a$2.current&&(a$2.current.getTracks().forEach(e=>e.stop()),a$2.current=void 0);},[]),a(async()=>{U&&await F();},[U]);let X=async()=>{await F();},Y=async()=>{await re();},Z=async()=>{await D();},F=async()=>{try{if(a$2.current||await ee(),a$2.current){if(!t.current){let{default:{RecordRTCPromisesHandler:r,StereoAudioRecorder:o}}=await import('recordrtc'),n={mimeType:"audio/wav",numberOfAudioChannels:1,recorderType:o,sampleRate:44100,timeSlice:k?z:void 0,type:"audio",ondataavailable:W&&k?ne:void 0};t.current=new r(a$2.current,n);}if(!i.current){let{Mp3Encoder:r}=await import('lamejs');i.current=new r(1,44100,96);}let e=await t.current.getState();(e==="inactive"||e==="stopped")&&await t.current.startRecording(),e==="paused"&&await t.current.resumeRecording(),B&&H("stop"),A(!0);}}catch{}},ee=async()=>{try{if(a$2.current&&a$2.current.getTracks().forEach(e=>e.stop()),a$2.current=await navigator.mediaDevices.getUserMedia({audio:!0}),!s.current){let{default:e}=await import('hark');s.current=e(a$2.current,{interval:100,play:!1}),s.current.on("speaking",E),s.current.on("stopped_speaking",v);}}catch{}},H=e=>{l.current[e]||(l.current[e]=setTimeout(D,q));},E=()=>{C(!0),y("stop");},v=()=>{C(!1),B&&H("stop");},re=async()=>{try{t.current&&(await t.current.getState()==="recording"&&await t.current.pauseRecording(),y("stop"),A(!1));}catch{}},D=async()=>{try{if(t.current){let e=await t.current.getState();if((e==="recording"||e==="paused")&&await t.current.stopRecording(),te(),y("stop"),A(!1),W)await _();else {let r=await t.current.getBlob();m({blob:r});}await t.current.destroy(),d$1.current=[],i.current&&(i.current.flush(),i.current=void 0),t.current=void 0;}}catch{}},te=()=>{s.current&&(s.current.off("speaking",E),s.current.off("stopped_speaking",v),s.current=void 0),a$2.current&&(a$2.current.getTracks().forEach(e=>e.stop()),a$2.current=void 0);},y=e=>{l.current[e]&&(clearTimeout(l.current[e]),l.current[e]=void 0);},_=async()=>{try{if(i.current&&t.current&&await t.current.getState()==="stopped"){b$1(!0);let r=await t.current.getBlob();if(j){let{FFmpeg:o}=await import('@ffmpeg/ffmpeg'),n=new o;await n.load({coreURL:b});let u=await r.arrayBuffer();await n.writeFile("in.wav",new Uint8Array(u)),await n.exec(["-i","in.wav","-acodec","libmp3lame","-b:a","96k","-ar","44100","-af",c,"out.mp3"]);let g=await n.readFile("out.mp3","binary");if(g.length<=225){n.terminate(),m({blob:r}),b$1(!1);return}r=new Blob([g],{type:"audio/mpeg"}),n.terminate();}else {let o=await r.arrayBuffer(),n=i.current.encodeBuffer(new Int16Array(o));r=new Blob([n],{type:"audio/mpeg"});}if(typeof R=="function"){let o=await R(r);m(o);}else {let o=new File([r],"speech.mp3",{type:"audio/mpeg"}),n=await x(o);m({blob:r,text:n});}b$1(!1);}}catch{b$1(!1);}},ne=async e=>{try{if(k&&t.current){if(L?.(e),i.current){let o=await e.arrayBuffer(),n=i.current.encodeBuffer(new Int16Array(o)),u=new Blob([n],{type:"audio/mpeg"});d$1.current.push(u);}if(await t.current.getState()==="recording"){let o=new Blob(d$1.current,{type:"audio/mpeg"}),n=new File([o],"speech.mp3",{type:"audio/mpeg"}),u=await x(n);u&&m(g=>({...g,text:u}));}}}catch{}},x=a$1(async e=>{let r=new FormData;r.append("file",e),r.append("model","whisper-1"),T==="transcriptions"&&r.append("language",c$1?.language??"en"),c$1?.prompt&&r.append("prompt",c$1.prompt),c$1?.response_format&&r.append("response_format",c$1.response_format),c$1?.temperature&&r.append("temperature",`${c$1.temperature}`);let o={};h&&(o.Authorization=`Bearer ${h}`);let n=p[T??"transcriptions"];return (await(await fetch(n,{method:"POST",body:r,headers:o})).json()).text},[h,T,c$1]);return {recording:J,speaking:N,transcribing:Q,transcript:V,pauseRecording:Y,startRecording:X,stopRecording:Z,onTranscribing:_}}; export { de as a };