UNPKG

mstf-kit

Version:

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

2 lines (1 loc) 4.02 kB
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./logger.js");function o(e,o){if(!e||!o)return null;const t=o.split(".");let r=e;for(const n of t){if(!r||"object"!=typeof r||!(n in r))return null;r=r[n]}return r}async function t(t,r={}){const{audioField:n,dataType:a,mimeType:l="audio/mpeg",autoPlay:i=!1,debug:c=!1,onAudioData:s,onError:u,onComplete:f}=r,d=e.createLogger({enabled:c,prefix:"[NonStreamAudio]",level:c?e.LogLevel.DEBUG:e.LogLevel.NONE});d.log("开始处理非流式音频响应",{hasResponse:!!t,audioField:n,dataType:a,mimeType:l,autoPlay:i});try{let e=null;if(n){if(d.log(`按字段路径提取音频数据: ${n}`),t&&"object"==typeof t&&"data"in t?(e=o(t.data,n),d.log("从response.data中提取数据")):(e=o(t,n),d.log("直接从response中提取数据")),!e)throw new Error(`无法从路径 "${n}" 提取音频数据`)}else if(d.log("未指定字段路径,尝试自动检测音频数据"),t&&"object"==typeof t&&"data"in t?(e=t.data,d.log("使用response.data作为音频数据")):(e=t,d.log("直接使用response作为音频数据")),e&&"object"==typeof e&&!(e instanceof Blob)&&!(e instanceof ArrayBuffer)&&!(e instanceof File)){const o=["audio","data","content","file","sound","voice"];let t=!1;for(const r of o)if(r in e){d.log(`自动检测到音频字段: ${r}`),e=e[r],t=!0;break}t||d.warn("未找到常见的音频字段,尝试使用整个对象")}d.log("提取的音频数据类型:",typeof e,e instanceof Blob?"(Blob)":"");let r,c=a;if(!c){const o=function(e){if(e){if(e instanceof Blob)return"blob";if(e instanceof ArrayBuffer)return"arraybuffer";if(e instanceof File)return"file";if("string"==typeof e){const o=e.replace(/^data:[^;]+;base64,/,"");if(/^[A-Za-z0-9+/]+=*$/.test(o))return"base64"}}}(e);o&&(c=o,d.log("自动检测的数据类型:",c))}if(!c)throw new Error("无法检测音频数据类型,请指定 dataType 参数");switch(c){case"base64":d.log("将Base64数据转换为Blob"),r=function(e,o="audio/mpeg"){const t=e.replace(/^data:[^;]+;base64,/,""),r=atob(t),n=new Uint8Array(r.length);for(let a=0;a<r.length;a++)n[a]=r.charCodeAt(a);return new Blob([n],{type:o})}(e,l);break;case"blob":d.log("直接使用Blob数据"),r=e;break;case"arraybuffer":d.log("将ArrayBuffer转换为Blob"),r=function(e,o="audio/mpeg"){return new Blob([e],{type:o})}(e,l);break;case"file":d.log("将File转换为Blob"),r=function(e,o){return o?new Blob([e],{type:o}):e}(e,l);break;default:throw new Error(`不支持的数据类型: ${c}`)}d.log("成功创建Blob:",{size:r.size,type:r.type});const u=URL.createObjectURL(r);let g;d.log("创建音频URL:",u),s&&(d.log("触发onAudioData回调"),s(r)),i&&(d.log("启动自动播放"),g=new Audio(u),g.play().catch((e=>{d.error("自动播放失败:",e)})));const b={blob:r,url:u,size:r.size,mimeType:r.type||l,audio:g};return f&&(d.log("触发onComplete回调"),f(r)),d.log("处理完成"),b}catch(g){throw d.error("处理音频数据时发生错误:",g),u&&u(g instanceof Error?g:new Error(String(g))),f&&f(),g}}exports.createAudioUrl=async function(e,o={}){return(await t(e,o)).url},exports.downloadAudio=async function(e,o,r={}){const n=await t(e,r),a=document.createElement("a");a.href=n.url,a.download=o,document.body.appendChild(a),a.click(),document.body.removeChild(a),setTimeout((()=>{URL.revokeObjectURL(n.url)}),1e3)},exports.getAudioBlob=async function(e,o,r){return(await t(e,{audioField:o,dataType:r,debug:!1})).blob},exports.processBatchNonStreamAudio=async function(o,r={}){const n=e.createLogger({enabled:r.debug,prefix:"[NonStreamAudio:Batch]",level:r.debug?e.LogLevel.DEBUG:e.LogLevel.NONE});n.log(`开始批量处理 ${o.length} 个音频响应`);const a=[];for(let e=0;e<o.length;e++)try{n.log(`处理第 ${e+1}/${o.length} 个音频`);const l=await t(o[e],{...r,autoPlay:!1});a.push(l)}catch(l){n.error(`处理第 ${e+1} 个音频时失败:`,l)}return n.log(`批量处理完成,成功处理 ${a.length}/${o.length} 个音频`),a},exports.processNonStreamAudio=t;