@easyv/biz-components 0.0.8 → 0.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -48,10 +48,20 @@ ${o}`);
48
48
  ] })
49
49
  ] });
50
50
  };
51
- return /* @__PURE__ */ e.jsxs("div", { className: C("px-4 py-3 flex flex-col gap-3 rounded-lg", "bg-[#FFFFFF14] select-text", m), children: [
52
- h.map((r, t) => typeof r == "string" ? /* @__PURE__ */ e.jsx("div", { className: "contents", children: j(r) }, t) : /* @__PURE__ */ e.jsx("div", { className: "contents", children: w(r) }, t)),
53
- f && /* @__PURE__ */ e.jsx("div", { className: "flex gap-1", children: /* @__PURE__ */ e.jsx("div", { className: "copy-btn w-6 h-6 rounded-md flex justify-center items-center hover:bg-bg-white cursor-pointer", children: /* @__PURE__ */ e.jsx(F, { className: "w-3.5 h-3.5 text-text-2", onClick: () => s == null ? void 0 : s() }) }) })
54
- ] });
51
+ return /* @__PURE__ */ e.jsxs(
52
+ "div",
53
+ {
54
+ className: C(
55
+ "px-4 py-3 flex flex-col gap-3 rounded-lg",
56
+ "bg-[#FFFFFF14] select-text",
57
+ m
58
+ ),
59
+ children: [
60
+ h.map((r, t) => typeof r == "string" ? /* @__PURE__ */ e.jsx("div", { className: "contents", children: j(r) }, t) : /* @__PURE__ */ e.jsx("div", { className: "contents", children: w(r) }, t)),
61
+ f && /* @__PURE__ */ e.jsx("div", { className: "flex gap-1", children: /* @__PURE__ */ e.jsx("div", { className: "copy-btn w-6 h-6 rounded-md flex justify-center items-center hover:bg-bg-white cursor-pointer", children: /* @__PURE__ */ e.jsx(F, { className: "w-3.5 h-3.5 text-text-2", onClick: () => s == null ? void 0 : s() }) }) })
62
+ ]
63
+ }
64
+ );
55
65
  };
56
66
  export {
57
67
  B as AiMessageRender
@@ -1 +1 @@
1
- {"version":3,"file":"AiMessageRender.es.js","sources":["../../../src/components/AiMessageRender/AiMessageRender.tsx"],"sourcesContent":["import { CopyCircleOutlined } from '@easyv/react-icons';\nimport classNames from 'classnames';\nimport Markdown from 'react-markdown';\nimport remarkGfm from 'remark-gfm';\nimport { ShadowDom } from '../ShadowDom';\n// @ts-expect-error\nimport messageRenderCss from './index.less?raw';\nimport { DashboardContext } from './types';\n\nexport interface AiMessageRenderProps {\n className?: string;\n contents: (string | DashboardContext)[];\n renderDashboardContent?: (msg: DashboardContext) => React.ReactNode;\n showFooterButtons?: boolean;\n onCopy?: () => void;\n onRedo?: () => void;\n markdownClassName?: string;\n rootFontSize?: number;\n /**隐藏默认样式 */\n hideDefaultStyle?: boolean;\n markdownStyle?: string;\n}\n\nexport const AiMessageRender = (props: AiMessageRenderProps) => {\n const {\n className = '',\n onCopy,\n renderDashboardContent: propsRenderDashboardContent,\n showFooterButtons = false,\n contents,\n markdownClassName = '',\n rootFontSize,\n hideDefaultStyle,\n markdownStyle,\n } = props;\n\n let finalMarkdownStyle = hideDefaultStyle ? '' : messageRenderCss;\n if (markdownStyle) {\n finalMarkdownStyle += `\\n${markdownStyle}`;\n }\n const renderStringContent = (msg: string) => {\n return (\n <ShadowDom\n style={finalMarkdownStyle}\n shadowRootDivClassName={markdownClassName + ' markdown-container'}\n rootFontSize={rootFontSize}\n >\n <Markdown remarkPlugins={[remarkGfm]}>{msg}</Markdown>\n </ShadowDom>\n );\n };\n const renderDashboardContent = (msg: DashboardContext) => {\n const { data, filterCode, plotModuleName, plotVersion } = msg;\n if (propsRenderDashboardContent) {\n return propsRenderDashboardContent(msg);\n }\n let finalData = data;\n if (filterCode) {\n const filterFunc = new Function('data', filterCode);\n finalData = filterFunc(data) as unknown[];\n }\n return (\n <div>\n <div>组件名称:{plotModuleName}</div>\n <div>组件版本:{plotVersion}</div>\n <div>组件数据:{finalData.slice(0, 5).map((i: unknown) => JSON.stringify(i))}</div>\n </div>\n );\n };\n\n return (\n <div className={classNames('px-4 py-3 flex flex-col gap-3 rounded-lg', 'bg-[#FFFFFF14] select-text', className)}>\n {contents.map((msg, index) => {\n if (typeof msg === 'string') {\n return (\n <div key={index} className='contents'>\n {renderStringContent(msg)}\n </div>\n );\n } else {\n return (\n <div key={index} className='contents'>\n {renderDashboardContent(msg)}\n </div>\n );\n }\n })}\n {showFooterButtons && (\n <div className='flex gap-1'>\n <div className='copy-btn w-6 h-6 rounded-md flex justify-center items-center hover:bg-bg-white cursor-pointer'>\n <CopyCircleOutlined className='w-3.5 h-3.5 text-text-2' onClick={() => onCopy?.()} />\n </div>\n {/* <div className='redo-btn w-6 h-6 rounded-md flex justify-center items-center hover:bg-bg-white cursor-pointer'>\n <RedoOutlined className='w-3.5 h-3.5 text-text-2' />\n </div> */}\n </div>\n )}\n </div>\n );\n};\n"],"names":["AiMessageRender","props","className","onCopy","propsRenderDashboardContent","showFooterButtons","contents","markdownClassName","rootFontSize","hideDefaultStyle","markdownStyle","finalMarkdownStyle","messageRenderCss","renderStringContent","msg","jsx","ShadowDom","Markdown","remarkGfm","renderDashboardContent","data","filterCode","plotModuleName","plotVersion","finalData","jsxs","i","classNames","index","CopyCircleOutlined"],"mappings":";;;;;;;AAuBa,MAAAA,IAAkB,CAACC,MAAgC;AACxD,QAAA;AAAA,IACJ,WAAAC,IAAY;AAAA,IACZ,QAAAC;AAAA,IACA,wBAAwBC;AAAA,IACxB,mBAAAC,IAAoB;AAAA,IACpB,UAAAC;AAAA,IACA,mBAAAC,IAAoB;AAAA,IACpB,cAAAC;AAAA,IACA,kBAAAC;AAAA,IACA,eAAAC;AAAA,EAAA,IACET;AAEA,MAAAU,IAAqBF,IAAmB,KAAKG;AACjD,EAAIF,MACoBC,KAAA;AAAA,EAAKD,CAAa;AAEpC,QAAAG,IAAsB,CAACC,MAEzBC,gBAAAA,EAAA;AAAA,IAACC;AAAA,IAAA;AAAA,MACC,OAAOL;AAAA,MACP,wBAAwBJ,IAAoB;AAAA,MAC5C,cAAAC;AAAA,MAEA,gCAACS,GAAS,EAAA,eAAe,CAACC,CAAS,GAAI,UAAIJ,EAAA,CAAA;AAAA,IAAA;AAAA,EAC7C,GAGEK,IAAyB,CAACL,MAA0B;AACxD,UAAM,EAAE,MAAAM,GAAM,YAAAC,GAAY,gBAAAC,GAAgB,aAAAC,EAAgB,IAAAT;AAC1D,QAAIV;AACF,aAAOA,EAA4BU,CAAG;AAExC,QAAIU,IAAYJ;AAChB,WAAIC,MAEFG,IADmB,IAAI,SAAS,QAAQH,CAAU,EAC3BD,CAAI,2BAG1B,OACC,EAAA,UAAA;AAAA,MAAAK,gBAAAA,OAAC,OAAI,EAAA,UAAA;AAAA,QAAA;AAAA,QAAMH;AAAA,MAAA,GAAe;AAAA,6BACzB,OAAI,EAAA,UAAA;AAAA,QAAA;AAAA,QAAMC;AAAA,MAAA,GAAY;AAAA,6BACtB,OAAI,EAAA,UAAA;AAAA,QAAA;AAAA,QAAMC,EAAU,MAAM,GAAG,CAAC,EAAE,IAAI,CAACE,MAAe,KAAK,UAAUA,CAAC,CAAC;AAAA,MAAA,EAAE,CAAA;AAAA,IAAA,GAC1E;AAAA,EAEJ;AAEA,gCACG,OAAI,EAAA,WAAWC,EAAW,4CAA4C,8BAA8BzB,CAAS,GAC3G,UAAA;AAAA,IAASI,EAAA,IAAI,CAACQ,GAAKc,MACd,OAAOd,KAAQ,iCAEd,OAAgB,EAAA,WAAU,YACxB,UAAoBD,EAAAC,CAAG,KADhBc,CAEV,0BAIC,OAAgB,EAAA,WAAU,YACxB,UAAuBT,EAAAL,CAAG,KADnBc,CAEV,CAGL;AAAA,IACAvB,KACEU,gBAAAA,EAAAA,IAAA,OAAA,EAAI,WAAU,cACb,UAAAA,gBAAAA,EAAA,IAAC,SAAI,WAAU,iGACb,UAACA,gBAAAA,EAAA,IAAAc,GAAA,EAAmB,WAAU,2BAA0B,SAAS,MAAM1B,KAAA,gBAAAA,KAAY,GACrF,EAIF,CAAA;AAAA,EAAA,GAEJ;AAEJ;"}
1
+ {"version":3,"file":"AiMessageRender.es.js","sources":["../../../src/components/AiMessageRender/AiMessageRender.tsx"],"sourcesContent":["import { CopyCircleOutlined } from '@easyv/react-icons';\nimport classNames from 'classnames';\nimport Markdown from 'react-markdown';\nimport remarkGfm from 'remark-gfm';\nimport { ShadowDom } from '../ShadowDom';\n// @ts-expect-error\nimport messageRenderCss from './index.less?raw';\nimport { DashboardContext } from './types';\n\nexport interface AiMessageRenderProps {\n className?: string;\n contents: (string | DashboardContext)[];\n renderDashboardContent?: (msg: DashboardContext) => React.ReactNode;\n showFooterButtons?: boolean;\n onCopy?: () => void;\n onRedo?: () => void;\n markdownClassName?: string;\n rootFontSize?: number;\n /**隐藏默认样式 */\n hideDefaultStyle?: boolean;\n markdownStyle?: string;\n}\n\nexport const AiMessageRender = (props: AiMessageRenderProps) => {\n const {\n className = '',\n onCopy,\n renderDashboardContent: propsRenderDashboardContent,\n showFooterButtons = false,\n contents,\n markdownClassName = '',\n rootFontSize,\n hideDefaultStyle,\n markdownStyle,\n } = props;\n\n let finalMarkdownStyle = hideDefaultStyle ? '' : messageRenderCss;\n if (markdownStyle) {\n finalMarkdownStyle += `\\n${markdownStyle}`;\n }\n const renderStringContent = (msg: string) => {\n return (\n <ShadowDom\n style={finalMarkdownStyle}\n shadowRootDivClassName={markdownClassName + ' markdown-container'}\n rootFontSize={rootFontSize}\n >\n <Markdown remarkPlugins={[remarkGfm]}>{msg}</Markdown>\n </ShadowDom>\n );\n };\n const renderDashboardContent = (msg: DashboardContext) => {\n const { data, filterCode, plotModuleName, plotVersion } = msg;\n if (propsRenderDashboardContent) {\n return propsRenderDashboardContent(msg);\n }\n let finalData = data;\n if (filterCode) {\n const filterFunc = new Function('data', filterCode);\n finalData = filterFunc(data) as unknown[];\n }\n return (\n <div>\n <div>组件名称:{plotModuleName}</div>\n <div>组件版本:{plotVersion}</div>\n <div>组件数据:{finalData.slice(0, 5).map((i: unknown) => JSON.stringify(i))}</div>\n </div>\n );\n };\n\n return (\n <div\n className={classNames(\n 'px-4 py-3 flex flex-col gap-3 rounded-lg',\n 'bg-[#FFFFFF14] select-text',\n className\n )}\n >\n {contents.map((msg, index) => {\n if (typeof msg === 'string') {\n return (\n <div key={index} className='contents'>\n {renderStringContent(msg)}\n </div>\n );\n } else {\n return (\n <div key={index} className='contents'>\n {renderDashboardContent(msg)}\n </div>\n );\n }\n })}\n {showFooterButtons && (\n <div className='flex gap-1'>\n <div className='copy-btn w-6 h-6 rounded-md flex justify-center items-center hover:bg-bg-white cursor-pointer'>\n <CopyCircleOutlined className='w-3.5 h-3.5 text-text-2' onClick={() => onCopy?.()} />\n </div>\n {/* <div className='redo-btn w-6 h-6 rounded-md flex justify-center items-center hover:bg-bg-white cursor-pointer'>\n <RedoOutlined className='w-3.5 h-3.5 text-text-2' />\n </div> */}\n </div>\n )}\n </div>\n );\n};\n"],"names":["AiMessageRender","props","className","onCopy","propsRenderDashboardContent","showFooterButtons","contents","markdownClassName","rootFontSize","hideDefaultStyle","markdownStyle","finalMarkdownStyle","messageRenderCss","renderStringContent","msg","jsx","ShadowDom","Markdown","remarkGfm","renderDashboardContent","data","filterCode","plotModuleName","plotVersion","finalData","jsxs","i","classNames","index","CopyCircleOutlined"],"mappings":";;;;;;;AAuBa,MAAAA,IAAkB,CAACC,MAAgC;AACxD,QAAA;AAAA,IACJ,WAAAC,IAAY;AAAA,IACZ,QAAAC;AAAA,IACA,wBAAwBC;AAAA,IACxB,mBAAAC,IAAoB;AAAA,IACpB,UAAAC;AAAA,IACA,mBAAAC,IAAoB;AAAA,IACpB,cAAAC;AAAA,IACA,kBAAAC;AAAA,IACA,eAAAC;AAAA,EAAA,IACET;AAEA,MAAAU,IAAqBF,IAAmB,KAAKG;AACjD,EAAIF,MACoBC,KAAA;AAAA,EAAKD,CAAa;AAEpC,QAAAG,IAAsB,CAACC,MAEzBC,gBAAAA,EAAA;AAAA,IAACC;AAAA,IAAA;AAAA,MACC,OAAOL;AAAA,MACP,wBAAwBJ,IAAoB;AAAA,MAC5C,cAAAC;AAAA,MAEA,gCAACS,GAAS,EAAA,eAAe,CAACC,CAAS,GAAI,UAAIJ,EAAA,CAAA;AAAA,IAAA;AAAA,EAC7C,GAGEK,IAAyB,CAACL,MAA0B;AACxD,UAAM,EAAE,MAAAM,GAAM,YAAAC,GAAY,gBAAAC,GAAgB,aAAAC,EAAgB,IAAAT;AAC1D,QAAIV;AACF,aAAOA,EAA4BU,CAAG;AAExC,QAAIU,IAAYJ;AAChB,WAAIC,MAEFG,IADmB,IAAI,SAAS,QAAQH,CAAU,EAC3BD,CAAI,2BAG1B,OACC,EAAA,UAAA;AAAA,MAAAK,gBAAAA,OAAC,OAAI,EAAA,UAAA;AAAA,QAAA;AAAA,QAAMH;AAAA,MAAA,GAAe;AAAA,6BACzB,OAAI,EAAA,UAAA;AAAA,QAAA;AAAA,QAAMC;AAAA,MAAA,GAAY;AAAA,6BACtB,OAAI,EAAA,UAAA;AAAA,QAAA;AAAA,QAAMC,EAAU,MAAM,GAAG,CAAC,EAAE,IAAI,CAACE,MAAe,KAAK,UAAUA,CAAC,CAAC;AAAA,MAAA,EAAE,CAAA;AAAA,IAAA,GAC1E;AAAA,EAEJ;AAGE,SAAAD,gBAAAA,EAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAWE;AAAA,QACT;AAAA,QACA;AAAA,QACAzB;AAAA,MACF;AAAA,MAEC,UAAA;AAAA,QAASI,EAAA,IAAI,CAACQ,GAAKc,MACd,OAAOd,KAAQ,iCAEd,OAAgB,EAAA,WAAU,YACxB,UAAoBD,EAAAC,CAAG,KADhBc,CAEV,0BAIC,OAAgB,EAAA,WAAU,YACxB,UAAuBT,EAAAL,CAAG,KADnBc,CAEV,CAGL;AAAA,QACAvB,KACEU,gBAAAA,EAAAA,IAAA,OAAA,EAAI,WAAU,cACb,UAAAA,gBAAAA,EAAA,IAAC,SAAI,WAAU,iGACb,UAACA,gBAAAA,EAAA,IAAAc,GAAA,EAAmB,WAAU,2BAA0B,SAAS,MAAM1B,KAAA,gBAAAA,KAAY,GACrF,EAIF,CAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAEJ;AAEJ;"}
@@ -0,0 +1,7 @@
1
+
2
+ export interface VoiceAnimationProps {
3
+ className?: string;
4
+ barNumber?: number;
5
+ barClassName?: string;
6
+ }
7
+ export declare const VoiceAnimation: (props: VoiceAnimationProps) => JSX.Element;
@@ -0,0 +1,20 @@
1
+ import { j as t } from "../../node_modules/.pnpm/react@18.2.0/node_modules/react/jsx-runtime.es.js";
2
+ import o from "../../node_modules/.pnpm/classnames@2.5.1/node_modules/classnames/index.es.js";
3
+ /* empty css */
4
+ const n = [0.4, 1.2, 0.8, 1.4, 0.8, 0.4, 1.4, 0.4, 1.4, 0.8, 0.4, 1.6], m = n.length, l = (a) => `-${n[a % m]}s`, y = (a) => {
5
+ const { className: s = "", barNumber: r = 22, barClassName: i = "" } = a;
6
+ return /* @__PURE__ */ t.jsx("div", { className: o("voice-animation flex justify-between", s), children: new Array(r).fill(0).map((c, e) => /* @__PURE__ */ t.jsx(
7
+ "div",
8
+ {
9
+ className: `wave-bar h-full rounded-full w-[0.4rem] ${i}`,
10
+ style: {
11
+ animationDelay: l(e)
12
+ }
13
+ },
14
+ e
15
+ )) });
16
+ };
17
+ export {
18
+ y as VoiceAnimation
19
+ };
20
+ //# sourceMappingURL=VoiceAnimation.es.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VoiceAnimation.es.js","sources":["../../../src/components/VoiceAnimation/VoiceAnimation.tsx"],"sourcesContent":["import classNames from 'classnames';\nimport './index.css';\n\nexport interface VoiceAnimationProps {\n className?: string;\n barNumber?: number;\n barClassName?: string;\n}\nconst animationDelayList = [0.4, 1.2, 0.8, 1.4, 0.8, 0.4, 1.4, 0.4, 1.4, 0.8, 0.4, 1.6];\nconst durationLength = animationDelayList.length;\nconst getAnimationDelay = (index: number) => {\n return `-${animationDelayList[index % durationLength]}s`;\n};\n\nexport const VoiceAnimation = (props: VoiceAnimationProps) => {\n const { className = '', barNumber = 22, barClassName = '' } = props;\n\n return (\n <div className={classNames('voice-animation flex justify-between', className)}>\n {new Array(barNumber).fill(0).map((_, index) => {\n return (\n <div\n key={index}\n className={`wave-bar h-full rounded-full w-[0.4rem] ${barClassName}`}\n style={{\n animationDelay: getAnimationDelay(index),\n }}\n ></div>\n );\n })}\n </div>\n );\n};\n"],"names":["animationDelayList","durationLength","getAnimationDelay","index","VoiceAnimation","props","className","barNumber","barClassName","classNames","_","jsx"],"mappings":";;;AAQA,MAAMA,IAAqB,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,GAAG,GAChFC,IAAiBD,EAAmB,QACpCE,IAAoB,CAACC,MAClB,IAAIH,EAAmBG,IAAQF,CAAc,CAAC,KAG1CG,IAAiB,CAACC,MAA+B;AAC5D,QAAM,EAAE,WAAAC,IAAY,IAAI,WAAAC,IAAY,IAAI,cAAAC,IAAe,OAAOH;AAE9D,+BACG,OAAI,EAAA,WAAWI,EAAW,wCAAwCH,CAAS,GACzE,UAAA,IAAI,MAAMC,CAAS,EAAE,KAAK,CAAC,EAAE,IAAI,CAACG,GAAGP,MAElCQ,gBAAAA,EAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MAEC,WAAW,2CAA2CH,CAAY;AAAA,MAClE,OAAO;AAAA,QACL,gBAAgBN,EAAkBC,CAAK;AAAA,MAAA;AAAA,IACzC;AAAA,IAJKA;AAAA,EAKN,CAEJ,GACH;AAEJ;"}
@@ -0,0 +1 @@
1
+ export { VoiceAnimation } from './VoiceAnimation';
@@ -1,3 +1,4 @@
1
1
  export * from './AiMessageRender';
2
2
  export * from './ShadowDom';
3
3
  export * from './ScrollController';
4
+ export * from './VoiceAnimation';
package/dist/index.d.ts CHANGED
@@ -1,2 +1,4 @@
1
+
1
2
  export * from './components';
2
3
  export * from './hooks';
4
+ export * from './utils';
package/dist/index.es.js CHANGED
@@ -1,11 +1,17 @@
1
- import { AiMessageRender as e } from "./components/AiMessageRender/AiMessageRender.es.js";
2
- import { ShadowDom as t } from "./components/ShadowDom/ShadowDom.es.js";
1
+ /* empty css */
2
+ import { AiMessageRender as t } from "./components/AiMessageRender/AiMessageRender.es.js";
3
+ import { ShadowDom as n } from "./components/ShadowDom/ShadowDom.es.js";
3
4
  import { ScrollController as f } from "./components/ScrollController/ScrollController.es.js";
4
- import { useDivAutoScroll as x } from "./hooks/useDivAutoScroll.es.js";
5
+ import { VoiceAnimation as l } from "./components/VoiceAnimation/VoiceAnimation.es.js";
6
+ import { useDivAutoScroll as S } from "./hooks/useDivAutoScroll.es.js";
7
+ import { FunASRManager as c, getWebSocketConnectForFunASR as A } from "./utils/funASR/funASRManager.es.js";
5
8
  export {
6
- e as AiMessageRender,
9
+ t as AiMessageRender,
10
+ c as FunASRManager,
7
11
  f as ScrollController,
8
- t as ShadowDom,
9
- x as useDivAutoScroll
12
+ n as ShadowDom,
13
+ l as VoiceAnimation,
14
+ A as getWebSocketConnectForFunASR,
15
+ S as useDivAutoScroll
10
16
  };
11
17
  //# sourceMappingURL=index.es.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.es.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
1
+ {"version":3,"file":"index.es.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;"}
package/dist/style.css ADDED
@@ -0,0 +1 @@
1
+ export default "data:text/css;base64,QHRhaWx3aW5kIGJhc2U7CkB0YWlsd2luZCBjb21wb25lbnRzOwpAdGFpbHdpbmQgdXRpbGl0aWVzOwo="export default "data:text/css;base64,LnZvaWNlLWFuaW1hdGlvbiAud2F2ZS1iYXIgewogIGJhY2tncm91bmQ6ICNmZmY7CiAgYW5pbWF0aW9uOiB3YXZlIDEuNnMgZWFzZS1pbi1vdXQgaW5maW5pdGU7Cn0KCkBrZXlmcmFtZXMgd2F2ZSB7CiAgMCUsCiAgMTAwJSB7CiAgICB0cmFuc2Zvcm06IHNjYWxlWSgxKTsKICB9CiAgNTAlIHsKICAgIHRyYW5zZm9ybTogc2NhbGVZKDAuMik7CiAgfQp9Cg=="{}
@@ -0,0 +1,103 @@
1
+ export interface WebSocketConnectMethodInstance {
2
+ wsSend: (msg: string | Int16Array<ArrayBuffer>) => void;
3
+ wsStop: () => void;
4
+ /** 1 is ok, 0 is error */
5
+ wsStart: () => 0 | 1;
6
+ getSocket: () => WebSocket | undefined;
7
+ }
8
+ export interface JsonMsg {
9
+ data: string;
10
+ }
11
+ export interface WebSocketConnectMethodConfig {
12
+ msgHandle: (jsonMsg: JsonMsg) => void;
13
+ /**
14
+ * 0: 成功
15
+ * 1: 关闭
16
+ * 2: 连接失败
17
+ */
18
+ stateHandle: (state: number) => void;
19
+ uri: string;
20
+ /**
21
+ * 逆文本标准化, 默认 true
22
+ * 标准化文本恢复成符合自然语言表达习惯的形式。
23
+ * 如: “一百二十三元五角” 这样的表述,经过 ITN 处理后,会变成 “123.5 元”
24
+ */
25
+ itn?: boolean;
26
+ /**
27
+ * 默认 2pass
28
+ * 2pass 模式:该模式也叫两步解码模式,通常包含两个步骤。第一步进行快速的初步解码,利用较为简单的语言模型和声学模型快速生成一个大致的识别结果;第二步基于第一步的结果,使用更复杂、更精确的语言模型进行重新解码和优化,从而得到最终更准确的识别结果。
29
+ * online 模式:采用流式处理方式,在语音数据输入的过程中,系统会逐块对语音进行实时识别。只要有新的语音数据块到达,就立即对其进行处理并输出部分识别结果,而无需等待整个语音输入结束。
30
+ * offline 模式:需要等待完整的语音数据全部输入后,才开始进行识别处理。在处理过程中,系统会对整个语音数据进行全面的分析和处理,以得出最终的识别结果。
31
+ */
32
+ mode?: '2pass' | 'online' | 'offline';
33
+ /** 是否是文件上传模式,当前模式暂不支持 */
34
+ isFileMode?: boolean;
35
+ /** 一行一个关键字,空格隔开权重,如 "阿里巴巴 20" */
36
+ hotWords?: string;
37
+ }
38
+ export interface RecorderConfig {
39
+ /**
40
+ * 输出类型:mp3,wav,wav输出文件尺寸超大不推荐使用,但mp3编码支持会导致js文件超大,如果不需支持mp3可以使js文件大幅减小
41
+ * pcm 文件无法直接播放,转成wav文件来播放,已提供转换函数 Recorder.pcm2wav
42
+ */
43
+ type?: 'mp3' | 'wav' | 'pcm';
44
+ /**
45
+ * 比特率 wav:16或8位,MP3:8kbps 1k/s,8kbps 2k/s 录音文件很小
46
+ */
47
+ bitRate?: number;
48
+ /**
49
+ * 采样率,wav格式大小=sampleRate*时间;mp3此项对低比特率有影响,高比特率几乎无影响。
50
+ * wav任意值,mp3取值范围:48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000
51
+ * 采样率参考https://www.cnblogs.com/devin87/p/mp3-recorder.html
52
+ */
53
+ sampleRate?: number;
54
+ /**
55
+ * 有默认值,可以不传 \n
56
+ * fn(buffers,powerLevel,bufferDuration,bufferSampleRate,newBufferIdx,asyncEnd)
57
+ * buffers=[[Int16,...],...]:缓冲的PCM数据,为从开始录音到现在的所有pcm片段;
58
+ * powerLevel:当前缓冲的音量级别0-100,
59
+ * bufferDuration:已缓冲时长,
60
+ * bufferSampleRate:缓冲使用的采样率(当type支持边录边转码(Worker)时,此采样率和设置的采样率相同,否则不一定相同);
61
+ * newBufferIdx:本次回调新增的buffer起始索引;
62
+ * asyncEnd:fn() 如果onProcess是异步的(返回值为true时),处理完成时需要调用此回调,如果不是异步的请忽略此参数,此方法回调时必须是真异步(不能真异步时需用setTimeout包裹)。
63
+ * onProcess返回值:如果返回true代表开启异步模式,在某些大量运算的场合异步是必须的,必须在异步处理完成时调用asyncEnd(不能真异步时需用setTimeout包裹),
64
+ * 在onProcess执行后新增的buffer会全部替换成空数组,因此本回调开头应立即将newBufferIdx到本次回调结尾位置的buffer全部保存到另外一个数组内,
65
+ * 处理完成后写回buffers中本次回调的结尾位置。
66
+ */
67
+ onProcess?: (...arg: any[]) => void;
68
+ }
69
+ export interface RecorderResult {
70
+ open: (fn: () => void) => void;
71
+ close: (fn?: () => void) => void;
72
+ stop: (fn?: (blob: Blob, duration?: number) => void, errFn?: (errMsg: string) => void) => void;
73
+ start: () => void;
74
+ pcm2wav: (...params: any) => void;
75
+ /** 0未录音 1录音中 2暂停 3等待ctx激活 */
76
+ state: 0 | 1 | 2;
77
+ SampleData: (array: Array<any>, sampleRate: number, targetSampleRate: number) => {
78
+ data: Int16Array<ArrayBuffer>;
79
+ };
80
+ }
81
+ export declare const getWebSocketConnectForFunASR: (config: WebSocketConnectMethodConfig) => WebSocketConnectMethodInstance;
82
+ interface RecorderFn {
83
+ (config: RecorderConfig): RecorderResult;
84
+ Destroy: () => void;
85
+ }
86
+ export declare class FunASRManager {
87
+ socketConfig: WebSocketConnectMethodConfig;
88
+ recorderConfig: RecorderConfig;
89
+ wsInstance: WebSocketConnectMethodInstance | null;
90
+ recorderInstance: RecorderResult | null;
91
+ sampleBuf: Int16Array<ArrayBuffer>;
92
+ isRec: boolean;
93
+ Recorder: RecorderFn;
94
+ status: 'live' | 'stop';
95
+ timer: NodeJS.Timeout | number;
96
+ constructor(socketConfig: WebSocketConnectMethodConfig, recorderConfig?: RecorderConfig);
97
+ init(): void;
98
+ destroy(): void;
99
+ startRecord(): void;
100
+ stopRecord(): void;
101
+ private recordProcess;
102
+ }
103
+ export {};
@@ -0,0 +1,78 @@
1
+ var d = Object.defineProperty;
2
+ var w = (n, t, e) => t in n ? d(n, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : n[t] = e;
3
+ var r = (n, t, e) => w(n, typeof t != "symbol" ? t + "" : t, e);
4
+ import { pcmEnhanceRecorder as I } from "./pcm.es.js";
5
+ import { Recorder as R } from "./recorder.es.js";
6
+ import { wavEnhanceRecorder as B } from "./wav.es.js";
7
+ import { WebSocketConnectMethod as S } from "./wsConnecter.es.js";
8
+ const k = (n) => new S(n);
9
+ class v {
10
+ constructor(t, e = { type: "pcm" }) {
11
+ r(this, "wsInstance", null);
12
+ r(this, "recorderInstance", null);
13
+ r(this, "sampleBuf", new Int16Array());
14
+ r(this, "isRec", !1);
15
+ r(this, "Recorder", R);
16
+ r(this, "status", "stop");
17
+ r(this, "timer", 0);
18
+ this.socketConfig = t, this.recorderConfig = e, console.log("%c 🐱 cat ==== fun asr manager ", "color: orange; font-size: 16px;", this), this.init(), this.wsInstance = k(t), this.recorderInstance = this.Recorder({
19
+ ...e,
20
+ onProcess: (...s) => e.onProcess ? e.onProcess(...s) : this.recordProcess(s[0], s[1], s[2], s[3], s[4], s[5])
21
+ });
22
+ }
23
+ init() {
24
+ I(this.Recorder), B(this.Recorder), this.status = "live";
25
+ }
26
+ destroy() {
27
+ var t;
28
+ (t = this.wsInstance) == null || t.wsStop(), this.Recorder.Destroy(), this.status = "stop";
29
+ }
30
+ startRecord() {
31
+ var t, e, s, o;
32
+ this.status !== "stop" && (((e = (t = this.wsInstance) == null ? void 0 : t.getSocket()) == null ? void 0 : e.readyState) !== WebSocket.OPEN && ((s = this.wsInstance) == null || s.wsStart()), (o = this.recorderInstance) == null || o.open(() => {
33
+ var a;
34
+ (a = this.recorderInstance) == null || a.start(), this.isRec = !0;
35
+ }));
36
+ }
37
+ stopRecord() {
38
+ var s;
39
+ if (this.status === "stop" || ((s = this.recorderInstance) == null ? void 0 : s.state) === 0)
40
+ return;
41
+ const t = this;
42
+ this.timer && clearTimeout(this.timer);
43
+ const e = () => {
44
+ var o;
45
+ (o = this.recorderInstance) == null || o.stop(() => {
46
+ var i, c;
47
+ const u = {
48
+ chunk_size: [5, 10, 5],
49
+ wav_name: "h5",
50
+ is_speaking: !1,
51
+ chunk_interval: 10,
52
+ mode: t.socketConfig.mode
53
+ };
54
+ t.sampleBuf.length > 0 && ((i = t.wsInstance) == null || i.wsSend(t.sampleBuf), console.log("sampleBuf.length" + t.sampleBuf.length), t.sampleBuf = new Int16Array()), (c = t.wsInstance) == null || c.wsSend(JSON.stringify(u)), this.isRec = !1;
55
+ });
56
+ };
57
+ this.timer = setTimeout(() => {
58
+ e();
59
+ }, 1e3);
60
+ }
61
+ recordProcess(t, e, s, o, a, u) {
62
+ var i, c;
63
+ if (this.status !== "stop" && this.isRec === !0) {
64
+ const l = t[t.length - 1], m = new Array(l), p = ((i = this.Recorder) == null ? void 0 : i.SampleData(m, o, 16e3).data) || [];
65
+ this.sampleBuf = Int16Array.from([...this.sampleBuf, ...p]);
66
+ const h = 960;
67
+ for (; this.sampleBuf.length >= h; ) {
68
+ const f = this.sampleBuf.slice(0, h);
69
+ this.sampleBuf = this.sampleBuf.slice(h, this.sampleBuf.length), (c = this.wsInstance) == null || c.wsSend(f);
70
+ }
71
+ }
72
+ }
73
+ }
74
+ export {
75
+ v as FunASRManager,
76
+ k as getWebSocketConnectForFunASR
77
+ };
78
+ //# sourceMappingURL=funASRManager.es.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"funASRManager.es.js","sources":["../../../src/utils/funASR/funASRManager.ts"],"sourcesContent":["import { pcmEnhanceRecorder } from './pcm';\nimport { Recorder as OriginRecorder } from './recorder';\nimport { wavEnhanceRecorder } from './wav';\nimport { WebSocketConnectMethod } from './wsConnecter';\n\nexport interface WebSocketConnectMethodInstance {\n wsSend: (msg: string | Int16Array<ArrayBuffer>) => void;\n wsStop: () => void;\n /** 1 is ok, 0 is error */\n wsStart: () => 0 | 1;\n getSocket: () => WebSocket | undefined;\n}\n\nexport interface JsonMsg {\n data: string;\n}\nexport interface WebSocketConnectMethodConfig {\n msgHandle: (jsonMsg: JsonMsg) => void;\n /**\n * 0: 成功\n * 1: 关闭\n * 2: 连接失败\n */\n stateHandle: (state: number) => void;\n uri: string;\n /**\n * 逆文本标准化, 默认 true\n * 标准化文本恢复成符合自然语言表达习惯的形式。\n * 如: “一百二十三元五角” 这样的表述,经过 ITN 处理后,会变成 “123.5 元”\n */\n itn?: boolean;\n /**\n * 默认 2pass\n * 2pass 模式:该模式也叫两步解码模式,通常包含两个步骤。第一步进行快速的初步解码,利用较为简单的语言模型和声学模型快速生成一个大致的识别结果;第二步基于第一步的结果,使用更复杂、更精确的语言模型进行重新解码和优化,从而得到最终更准确的识别结果。\n * online 模式:采用流式处理方式,在语音数据输入的过程中,系统会逐块对语音进行实时识别。只要有新的语音数据块到达,就立即对其进行处理并输出部分识别结果,而无需等待整个语音输入结束。\n * offline 模式:需要等待完整的语音数据全部输入后,才开始进行识别处理。在处理过程中,系统会对整个语音数据进行全面的分析和处理,以得出最终的识别结果。\n */\n mode?: '2pass' | 'online' | 'offline';\n /** 是否是文件上传模式,当前模式暂不支持 */\n isFileMode?: boolean;\n /** 一行一个关键字,空格隔开权重,如 \"阿里巴巴 20\" */\n hotWords?: string;\n}\nexport interface RecorderConfig {\n /**\n * 输出类型:mp3,wav,wav输出文件尺寸超大不推荐使用,但mp3编码支持会导致js文件超大,如果不需支持mp3可以使js文件大幅减小\n * pcm 文件无法直接播放,转成wav文件来播放,已提供转换函数 Recorder.pcm2wav\n */\n type?: 'mp3' | 'wav' | 'pcm';\n /**\n * 比特率 wav:16或8位,MP3:8kbps 1k/s,8kbps 2k/s 录音文件很小\n */\n bitRate?: number;\n /**\n * 采样率,wav格式大小=sampleRate*时间;mp3此项对低比特率有影响,高比特率几乎无影响。\n * wav任意值,mp3取值范围:48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000\n * 采样率参考https://www.cnblogs.com/devin87/p/mp3-recorder.html\n */\n sampleRate?: number;\n /**\n * 有默认值,可以不传 \\n\n * fn(buffers,powerLevel,bufferDuration,bufferSampleRate,newBufferIdx,asyncEnd)\n * buffers=[[Int16,...],...]:缓冲的PCM数据,为从开始录音到现在的所有pcm片段;\n * powerLevel:当前缓冲的音量级别0-100,\n * bufferDuration:已缓冲时长,\n * bufferSampleRate:缓冲使用的采样率(当type支持边录边转码(Worker)时,此采样率和设置的采样率相同,否则不一定相同);\n * newBufferIdx:本次回调新增的buffer起始索引;\n * asyncEnd:fn() 如果onProcess是异步的(返回值为true时),处理完成时需要调用此回调,如果不是异步的请忽略此参数,此方法回调时必须是真异步(不能真异步时需用setTimeout包裹)。\n * onProcess返回值:如果返回true代表开启异步模式,在某些大量运算的场合异步是必须的,必须在异步处理完成时调用asyncEnd(不能真异步时需用setTimeout包裹),\n * 在onProcess执行后新增的buffer会全部替换成空数组,因此本回调开头应立即将newBufferIdx到本次回调结尾位置的buffer全部保存到另外一个数组内,\n * 处理完成后写回buffers中本次回调的结尾位置。\n */\n onProcess?: (...arg: any[]) => void;\n}\nexport interface RecorderResult {\n open: (fn: () => void) => void;\n close: (fn?: () => void) => void;\n stop: (fn?: (blob: Blob, duration?: number) => void, errFn?: (errMsg: string) => void) => void;\n start: () => void;\n pcm2wav: (...params: any) => void;\n /** 0未录音 1录音中 2暂停 3等待ctx激活 */\n state: 0 | 1 | 2;\n SampleData: (\n array: Array<any>,\n sampleRate: number,\n targetSampleRate: number,\n ) => { data: Int16Array<ArrayBuffer> };\n}\n\nexport const getWebSocketConnectForFunASR = (config: WebSocketConnectMethodConfig) => {\n return new WebSocketConnectMethod(config) as unknown as WebSocketConnectMethodInstance;\n};\n\ninterface RecorderFn {\n (config: RecorderConfig): RecorderResult;\n Destroy: () => void;\n}\n\nexport class FunASRManager {\n wsInstance: WebSocketConnectMethodInstance | null = null;\n recorderInstance: RecorderResult | null = null;\n sampleBuf = new Int16Array();\n isRec = false;\n Recorder = OriginRecorder as RecorderFn;\n status: 'live' | 'stop' = 'stop';\n timer: NodeJS.Timeout | number = 0;\n\n constructor(\n public socketConfig: WebSocketConnectMethodConfig,\n public recorderConfig: RecorderConfig = { type: 'pcm' },\n ) {\n console.log('%c 🐱 cat ==== fun asr manager ', 'color: orange; font-size: 16px;', this);\n this.init();\n this.wsInstance = getWebSocketConnectForFunASR(socketConfig);\n this.recorderInstance = this.Recorder({\n ...recorderConfig,\n onProcess: (...args) => {\n if (recorderConfig.onProcess) {\n return recorderConfig.onProcess(...args);\n }\n return this.recordProcess(args[0], args[1], args[2], args[3], args[4], args[5]);\n },\n }) as unknown as RecorderResult;\n }\n\n init() {\n pcmEnhanceRecorder(this.Recorder);\n wavEnhanceRecorder(this.Recorder);\n this.status = 'live';\n }\n\n destroy() {\n this.wsInstance?.wsStop();\n this.Recorder.Destroy();\n this.status = 'stop';\n }\n\n public startRecord() {\n if (this.status === 'stop') {\n return;\n }\n if (this.wsInstance?.getSocket()?.readyState !== WebSocket.OPEN) {\n this.wsInstance?.wsStart();\n }\n this.recorderInstance?.open(() => {\n this.recorderInstance?.start();\n this.isRec = true;\n });\n }\n public stopRecord() {\n if (this.status === 'stop' || this.recorderInstance?.state === 0) {\n return;\n }\n const that = this;\n if (this.timer) {\n clearTimeout(this.timer);\n }\n const stopFn = () => {\n this.recorderInstance?.stop(() => {\n const chunk_size = [5, 10, 5];\n const request = {\n chunk_size: chunk_size,\n wav_name: 'h5',\n is_speaking: false,\n chunk_interval: 10,\n mode: that.socketConfig.mode,\n };\n if (that.sampleBuf.length > 0) {\n that.wsInstance?.wsSend(that.sampleBuf);\n console.log('sampleBuf.length' + that.sampleBuf.length);\n that.sampleBuf = new Int16Array();\n }\n that.wsInstance?.wsSend(JSON.stringify(request));\n this.isRec = false;\n });\n };\n // 延迟 1s 等待录音结束\n this.timer = setTimeout(() => {\n stopFn();\n }, 1000);\n }\n\n private recordProcess(\n buffer: string | any[],\n _powerLevel: any,\n _bufferDuration: any,\n bufferSampleRate: number,\n _newBufferIdx: any,\n _asyncEnd: any,\n ) {\n if (this.status === 'stop') {\n return;\n }\n if (this.isRec === true) {\n const data_48k = buffer[buffer.length - 1];\n\n const array_48k = new Array(data_48k);\n const data_16k =\n (this.Recorder as any)?.SampleData(array_48k, bufferSampleRate, 16000).data || [];\n\n this.sampleBuf = Int16Array.from([...this.sampleBuf, ...data_16k]);\n const chunk_size = 960; // for asr chunk_size [5, 10, 5]\n while (this.sampleBuf.length >= chunk_size) {\n const sendBuf = this.sampleBuf.slice(0, chunk_size);\n this.sampleBuf = this.sampleBuf.slice(chunk_size, this.sampleBuf.length);\n this.wsInstance?.wsSend(sendBuf);\n }\n }\n }\n}\n"],"names":["getWebSocketConnectForFunASR","config","WebSocketConnectMethod","FunASRManager","socketConfig","recorderConfig","__publicField","OriginRecorder","args","pcmEnhanceRecorder","wavEnhanceRecorder","_a","_b","_c","_d","that","stopFn","request","buffer","_powerLevel","_bufferDuration","bufferSampleRate","_newBufferIdx","_asyncEnd","data_48k","array_48k","data_16k","chunk_size","sendBuf"],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export * from './funASRManager';
@@ -0,0 +1 @@
1
+ export function pcmEnhanceRecorder(Recorder: any): void;
@@ -0,0 +1,46 @@
1
+ function m(i) {
2
+ i.prototype.enc_pcm = {
3
+ stable: !0,
4
+ testmsg: "pcm为未封装的原始音频数据,pcm数据文件无法直接播放;支持位数8位、16位(填在比特率里面),采样率取值无限制"
5
+ }, i.prototype.pcm = function(e, l, v) {
6
+ var o = this, s = o.set, a = e.length, r = s.bitRate == 8 ? 8 : 16, f = new ArrayBuffer(a * (r / 8)), n = new DataView(f), p = 0;
7
+ if (r == 8)
8
+ for (var t = 0; t < a; t++, p++) {
9
+ var c = (e[t] >> 8) + 128;
10
+ n.setInt8(p, c, !0);
11
+ }
12
+ else
13
+ for (var t = 0; t < a; t++, p += 2)
14
+ n.setInt16(p, e[t], !0);
15
+ l(new Blob([n.buffer], { type: "audio/pcm" }));
16
+ }, i.pcm2wav = function(e, l, v) {
17
+ e.slice && e.type != null && (e = { blob: e });
18
+ var o = e.sampleRate || 16e3, s = e.bitRate || 16;
19
+ if ((!e.sampleRate || !e.bitRate) && console.warn("pcm2wav必须提供sampleRate和bitRate"), !i.prototype.wav) {
20
+ v("pcm2wav必须先加载wav编码器wav.js");
21
+ return;
22
+ }
23
+ var a = new FileReader();
24
+ a.onloadend = function() {
25
+ var r;
26
+ if (s == 8) {
27
+ var f = new Uint8Array(a.result);
28
+ r = new Int16Array(f.length);
29
+ for (var n = 0; n < f.length; n++)
30
+ r[n] = f[n] - 128 << 8;
31
+ } else
32
+ r = new Int16Array(a.result);
33
+ i({
34
+ type: "wav",
35
+ sampleRate: o,
36
+ bitRate: s
37
+ }).mock(r, o).stop(function(p, t) {
38
+ l(p, t);
39
+ }, v);
40
+ }, a.readAsArrayBuffer(e.blob);
41
+ };
42
+ }
43
+ export {
44
+ m as pcmEnhanceRecorder
45
+ };
46
+ //# sourceMappingURL=pcm.es.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pcm.es.js","sources":["../../../src/utils/funASR/pcm.js"],"sourcesContent":["/*\npcm编码器+编码引擎\nhttps://github.com/xiangyuecn/Recorder\n\n编码原理:本编码器输出的pcm格式数据其实就是Recorder中的buffers原始数据(经过了重新采样),16位时为LE小端模式(Little Endian),并未经过任何编码处理\n\n编码的代码和wav.js区别不大,pcm加上一个44字节wav头即成wav文件;所以要播放pcm就很简单了,直接转成wav文件来播放,已提供转换函数 Recorder.pcm2wav\n*/\nexport function pcmEnhanceRecorder(Recorder) {\n 'use strict';\n\n Recorder.prototype.enc_pcm = {\n stable: true,\n testmsg:\n 'pcm为未封装的原始音频数据,pcm数据文件无法直接播放;支持位数8位、16位(填在比特率里面),采样率取值无限制',\n };\n Recorder.prototype.pcm = function (res, True, False) {\n var This = this,\n set = This.set,\n size = res.length,\n bitRate = set.bitRate == 8 ? 8 : 16;\n\n var buffer = new ArrayBuffer(size * (bitRate / 8));\n var data = new DataView(buffer);\n var offset = 0;\n\n // 写入采样数据\n if (bitRate == 8) {\n for (var i = 0; i < size; i++, offset++) {\n //16转8据说是雷霄骅的 https://blog.csdn.net/sevennight1989/article/details/85376149 细节比blqw的按比例的算法清晰点,虽然都有明显杂音\n var val = (res[i] >> 8) + 128;\n data.setInt8(offset, val, true);\n }\n } else {\n for (var i = 0; i < size; i++, offset += 2) {\n data.setInt16(offset, res[i], true);\n }\n }\n\n True(new Blob([data.buffer], { type: 'audio/pcm' }));\n };\n\n /**pcm直接转码成wav,可以直接用来播放;需同时引入wav.js\n\tdata: {\n\t\t\tsampleRate:16000 pcm的采样率\n\t\t\tbitRate:16 pcm的位数 取值:8 或 16\n\t\t\tblob:blob对象\n\t\t}\n\t\tdata如果直接提供的blob将默认使用16位16khz的配置,仅用于测试\n\tTrue(wavBlob,duration)\n\tFalse(msg)\n\t**/\n Recorder.pcm2wav = function (data, True, False) {\n if (data.slice && data.type != null) {\n //Blob 测试用\n data = { blob: data };\n }\n var sampleRate = data.sampleRate || 16000,\n bitRate = data.bitRate || 16;\n if (!data.sampleRate || !data.bitRate) {\n console.warn('pcm2wav必须提供sampleRate和bitRate');\n }\n if (!Recorder.prototype.wav) {\n False('pcm2wav必须先加载wav编码器wav.js');\n return;\n }\n\n var reader = new FileReader();\n reader.onloadend = function () {\n var pcm;\n if (bitRate == 8) {\n //8位转成16位\n var u8arr = new Uint8Array(reader.result);\n pcm = new Int16Array(u8arr.length);\n for (var j = 0; j < u8arr.length; j++) {\n pcm[j] = (u8arr[j] - 128) << 8;\n }\n } else {\n pcm = new Int16Array(reader.result);\n }\n\n Recorder({\n type: 'wav',\n sampleRate: sampleRate,\n bitRate: bitRate,\n })\n .mock(pcm, sampleRate)\n .stop(function (wavBlob, duration) {\n True(wavBlob, duration);\n }, False);\n };\n reader.readAsArrayBuffer(data.blob);\n };\n}\n"],"names":["pcmEnhanceRecorder","Recorder","res","True","False","This","set","size","bitRate","buffer","data","offset","i","val","sampleRate","reader","pcm","u8arr","j","wavBlob","duration"],"mappings":"AAQO,SAASA,EAAmBC,GAAU;AAG3C,EAAAA,EAAS,UAAU,UAAU;AAAA,IAC3B,QAAQ;AAAA,IACR,SACE;AAAA,EACH,GACDA,EAAS,UAAU,MAAM,SAAUC,GAAKC,GAAMC,GAAO;AACnD,QAAIC,IAAO,MACTC,IAAMD,EAAK,KACXE,IAAOL,EAAI,QACXM,IAAUF,EAAI,WAAW,IAAI,IAAI,IAE/BG,IAAS,IAAI,YAAYF,KAAQC,IAAU,EAAE,GAC7CE,IAAO,IAAI,SAASD,CAAM,GAC1BE,IAAS;AAGb,QAAIH,KAAW;AACb,eAASI,IAAI,GAAGA,IAAIL,GAAMK,KAAKD,KAAU;AAEvC,YAAIE,KAAOX,EAAIU,CAAC,KAAK,KAAK;AAC1B,QAAAF,EAAK,QAAQC,GAAQE,GAAK,EAAI;AAAA,MACtC;AAAA;AAEM,eAASD,IAAI,GAAGA,IAAIL,GAAMK,KAAKD,KAAU;AACvC,QAAAD,EAAK,SAASC,GAAQT,EAAIU,CAAC,GAAG,EAAI;AAItC,IAAAT,EAAK,IAAI,KAAK,CAACO,EAAK,MAAM,GAAG,EAAE,MAAM,YAAW,CAAE,CAAC;AAAA,EACpD,GAYDT,EAAS,UAAU,SAAUS,GAAMP,GAAMC,GAAO;AAC9C,IAAIM,EAAK,SAASA,EAAK,QAAQ,SAE7BA,IAAO,EAAE,MAAMA,EAAM;AAEvB,QAAII,IAAaJ,EAAK,cAAc,MAClCF,IAAUE,EAAK,WAAW;AAI5B,SAHI,CAACA,EAAK,cAAc,CAACA,EAAK,YAC5B,QAAQ,KAAK,+BAA+B,GAE1C,CAACT,EAAS,UAAU,KAAK;AAC3B,MAAAG,EAAM,0BAA0B;AAChC;AAAA,IACN;AAEI,QAAIW,IAAS,IAAI,WAAY;AAC7B,IAAAA,EAAO,YAAY,WAAY;AAC7B,UAAIC;AACJ,UAAIR,KAAW,GAAG;AAEhB,YAAIS,IAAQ,IAAI,WAAWF,EAAO,MAAM;AACxC,QAAAC,IAAM,IAAI,WAAWC,EAAM,MAAM;AACjC,iBAASC,IAAI,GAAGA,IAAID,EAAM,QAAQC;AAChC,UAAAF,EAAIE,CAAC,IAAKD,EAAMC,CAAC,IAAI,OAAQ;AAAA,MAEvC;AACQ,QAAAF,IAAM,IAAI,WAAWD,EAAO,MAAM;AAGpC,MAAAd,EAAS;AAAA,QACP,MAAM;AAAA,QACN,YAAYa;AAAA,QACZ,SAASN;AAAA,MACV,CAAA,EACE,KAAKQ,GAAKF,CAAU,EACpB,KAAK,SAAUK,GAASC,GAAU;AACjC,QAAAjB,EAAKgB,GAASC,CAAQ;AAAA,MACvB,GAAEhB,CAAK;AAAA,IACX,GACDW,EAAO,kBAAkBL,EAAK,IAAI;AAAA,EACnC;AACH;"}
@@ -0,0 +1,3 @@
1
+ export class Recorder {
2
+ private constructor();
3
+ }