UNPKG

mstf-kit

Version:

一个现代化的 JavaScript/TypeScript 工具库,提供了丰富的常用工具函数

2 lines (1 loc) 6.42 kB
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./logger.js");function t(){return{audioCtx:new(window.AudioContext||window.webkitAudioContext),currentSource:null,isPlaying:!1,audioQueue:[],wavHeader:null,previousChunk:"",isFirstChunk:!0,audioChunks:[],hasStartedPlaying:!1,detectedFormat:null}}function n(e){return!(e.length<4)&&"RIFF"===String.fromCharCode(...e.slice(0,4))}function o(e){return e.length<44?null:n(e)?e.slice(0,44):null}function a(e){if(e.currentSource){try{e.currentSource.stop()}catch(t){}e.currentSource=null}e.isPlaying=!1,e.audioQueue=[],e.wavHeader=null,e.previousChunk="",e.isFirstChunk=!0,e.audioChunks=[],e.detectedFormat=null}async function r(e,t,n,o){return new Promise((a=>{if(t.isPlaying)return t.audioQueue.push(e),void a();const r=t.audioCtx.createBufferSource();r.buffer=e,r.connect(t.audioCtx.destination),r.onended=()=>{t.isPlaying=!1,t.currentSource=null,0===t.audioQueue.length&&o&&o(),a(),i(t,n,o)},t.currentSource=r,t.isPlaying=!0,r.start(0),n&&!t.hasStartedPlaying&&(t.hasStartedPlaying=!0,n())}))}async function i(e,t,n){if(e.audioQueue.length>0&&!e.isPlaying){const o=e.audioQueue.shift();await r(o,e,t,n)}}function u(e,t,n="audio/wav"){const o=new Uint8Array(t.length+e.length);return o.set(t),o.set(e,t.length),new Blob([o],{type:n})}function s(e,t,n="audio/wav"){let o=t.length;e.forEach((e=>{o+=e.length}));const a=new Uint8Array(o);let r=0;return a.set(t),r+=t.length,e.forEach((e=>{a.set(e,r),r+=e.length})),new Blob([a],{type:n})}async function l(e,t,n,o){try{if(!t.wavHeader)return;const a=new Uint8Array(t.wavHeader.length+e.length);a.set(t.wavHeader),a.set(e,t.wavHeader.length);const i=await t.audioCtx.decodeAudioData(a.buffer.slice(0));t.isPlaying?t.audioQueue.push(i):await r(i,t,n,o)}catch(a){}}async function d(e,t,a,r){if(e.startsWith("data: "))try{const i=e.substring(6);if(!i.trim())return;const s=function(e,t){if(!e)return null;if(!t)return"string"==typeof e?e:e.audio&&"string"==typeof e.audio?e.audio:e.data&&e.data.audio&&"string"==typeof e.data.audio?e.data.audio:null;const n=t.split(".");let o=e;for(const a of n){if(!o||"object"!=typeof o||!(a in o))return null;o=o[a]}return"string"==typeof o?o:null}(JSON.parse(i),a.audioField);s&&await async function(e,t,a,r){try{const i=function(e){try{return function(e){const t=new Uint8Array(e.length);for(let n=0;n<e.length;n++)t[n]=e.charCodeAt(n);return t}(atob(e))}catch(t){return console.error("Base64解码错误:",t),new Uint8Array(0)}}(e),s="auto"===a.dataFormat?function(e,t){return t.detectedFormat?t.detectedFormat:n(e)||t.isFirstChunk?"auto":(t.detectedFormat="without-header","without-header")}(i,t):a.dataFormat||"auto";r.debug("处理音频块:",{size:i.length,isFirstChunk:t.isFirstChunk,format:s,hasHeader:n(i)}),"with-header"===s||"auto"===s&&n(i)?await async function(e,t,n,a){a.debug("处理带头部的音频块");const r=o(e);if(!r)return void a.warn("无法提取WAV头部");const i=e.slice(44);t.wavHeader||(t.wavHeader=r),t.audioChunks.push(i);const s=u(i,r,n.mimeType);n.onAudioData&&n.onAudioData(s),n.autoPlay&&await l(i,t,n.onStart,n.onEnded)}(i,t,a,r):("without-header"===s||"auto"===s&&!n(i))&&await async function(e,t,n,a){if(a.debug("处理无头部的音频块"),t.isFirstChunk){const a=o(e);if(a){t.wavHeader=a;const o=e.slice(44);if(o.length>0){t.audioChunks.push(o);const e=u(o,a,n.mimeType);n.onAudioData&&n.onAudioData(e),n.autoPlay&&await l(o,t,n.onStart,n.onEnded)}}}else{if(!t.wavHeader)return void a.warn("未找到WAV头部,无法处理音频数据");t.audioChunks.push(e);const o=u(e,t.wavHeader,n.mimeType);n.onAudioData&&n.onAudioData(o),n.autoPlay&&await l(e,t,n.onStart,n.onEnded)}}(i,t,a,r),t.isFirstChunk=!1}catch(i){r.error("处理音频块错误:",i),a.onError&&a.onError(i instanceof Error?i:new Error(String(i)))}}(s,t,a,r)}catch(i){r.debug("跳过不完整的数据:",e.substring(0,50))}}exports.createAxiosAudioOptionsV2=function(n={}){const o=e.createLogger({enabled:n.debug,prefix:"[AxiosAudioV2]",level:n.debug?e.LogLevel.DEBUG:e.LogLevel.NONE}),r=t();let u=0,l=!1,c=null;return{axiosConfig:{responseType:"text",onDownloadProgress:async e=>{var t,a,i,g,h;if(!l)try{const l=null==(a=null==(t=e.event)?void 0:t.target)?void 0:a.response;if(l&&"string"==typeof l){const e=l.substring(u);if(u=l.length,e){n.onRawChunk&&n.onRawChunk(e);const t=e.split("\n");for(const e of t)e.trim()&&e.startsWith("data: ")&&await d(e.trim(),r,n,o)}}if(e.loaded===e.total)if(n.returnBlob&&r.wavHeader&&r.audioChunks.length>0){const e=s(r.audioChunks,r.wavHeader,n.mimeType||"audio/wav");null==c||c(e),null==(i=n.onComplete)||i.call(n,e)}else null==(g=n.onComplete)||g.call(n)}catch(f){o.error("Axios进度处理错误:",f),f instanceof Error&&(null==(h=n.onError)||h.call(n,f))}}},pause:()=>{r.currentSource&&(r.currentSource.stop(),r.currentSource=null),r.isPlaying=!1},resume:()=>{!r.isPlaying&&r.audioQueue.length>0&&i(r,n.onStart,n.onEnded)},abort:()=>{l=!0,a(r)},isPlaying:()=>r.isPlaying,finalBlob:n.returnBlob?new Promise((e=>{c=e})):void 0}},exports.processStreamAudioV2=async function(n,o={}){const{autoPlay:r=!1,returnBlob:u=!1,mimeType:l="audio/wav",audioField:c,dataFormat:g="auto",debug:h=!1,onAudioData:f,onError:y,onComplete:w,onStart:p,onEnded:m,onRawChunk:v}=o,C=e.createLogger({enabled:h,prefix:"[StreamAudioV2]",level:h?e.LogLevel.DEBUG:e.LogLevel.NONE});C.log("初始化流式音频处理器 V2",{autoPlay:r,returnBlob:u,mimeType:l,audioField:c,dataFormat:g});const b=t(),P=new TextDecoder;let S="",k=null,A=!1;const F=u?new Promise((e=>{k=e})):void 0;return(async()=>{try{for(;!A;){const{value:e,done:t}=await n.read();if(t)break;S+=P.decode(e,{stream:!0}),v&&v(S);const a=S.split("\n");S=a.pop()||"";for(const n of a)n.trim()&&await d(n.trim(),b,o,C)}if(!A&&S.trim()&&await d(S.trim(),b,o,C),C.log("流处理完成",{chunksCount:b.audioChunks.length,detectedFormat:b.detectedFormat}),u&&b.wavHeader&&b.audioChunks.length>0){const e=s(b.audioChunks,b.wavHeader,l);null==k||k(e),null==w||w(e)}else null==w||w()}catch(e){C.error("流处理错误:",e),e instanceof Error&&(null==y||y(e))}})(),{pause:()=>{b.currentSource&&(b.currentSource.stop(),b.currentSource=null),b.isPlaying=!1,C.log("暂停播放")},resume:()=>{!b.isPlaying&&b.audioQueue.length>0&&(i(b,p,m),C.log("恢复播放"))},abort:()=>{A=!0,n.cancel().catch((()=>{})),a(b),C.log("中止处理")},isPlaying:()=>b.isPlaying,finalBlob:F}};