From 55908f7b8f7936bb8b4cd9e1b584a94abe1c3989 Mon Sep 17 00:00:00 2001 From: yumoqing Date: Sun, 5 Oct 2025 06:39:58 +0800 Subject: [PATCH] bugfix --- aidocs/accordion.md | 205 +++++++++ aidocs/aggrid.md | 226 ++++++++++ aidocs/asr.md | 220 +++++++++ aidocs/audio.md | 404 +++++++++++++++++ aidocs/bar.md | 211 +++++++++ aidocs/binstreaming.md | 276 ++++++++++++ aidocs/bricks.md | 498 +++++++++++++++++++++ aidocs/button.md | 254 +++++++++++ aidocs/camera.md | 355 +++++++++++++++ aidocs/cols.md | 323 ++++++++++++++ aidocs/conform.md | 249 +++++++++++ aidocs/continueaudio.md | 314 +++++++++++++ aidocs/countdown.md | 284 ++++++++++++ aidocs/css.md | 88 ++++ aidocs/datagrid.md | 434 ++++++++++++++++++ aidocs/datarow.md | 311 +++++++++++++ aidocs/dataviewer.md | 502 +++++++++++++++++++++ aidocs/docxviewer.md | 262 +++++++++++ aidocs/dynamicaccordion.md | 399 +++++++++++++++++ aidocs/dynamiccolumn.md | 173 ++++++++ aidocs/echartsext.md | 301 +++++++++++++ aidocs/factory.md | 162 +++++++ aidocs/floaticonbar.md | 321 ++++++++++++++ aidocs/form.md | 353 +++++++++++++++ aidocs/gobang.md | 283 ++++++++++++ aidocs/html.md | 123 ++++++ aidocs/i18n.md | 283 ++++++++++++ aidocs/iconbarpage.md | 218 +++++++++ aidocs/iframe.md | 184 ++++++++ aidocs/image.md | 350 +++++++++++++++ aidocs/input.md | 621 ++++++++++++++++++++++++++ aidocs/jsoncall.md | 391 ++++++++++++++++ aidocs/keypress.md | 126 ++++++ aidocs/layout.md | 359 +++++++++++++++ aidocs/line.md | 203 +++++++++ aidocs/llm.md | 414 +++++++++++++++++ aidocs/llm_dialog.md | 366 +++++++++++++++ aidocs/llmout.md | 297 +++++++++++++ aidocs/markdown_viewer.md | 250 +++++++++++ aidocs/menu.md | 367 +++++++++++++++ aidocs/message.md | 218 +++++++++ aidocs/miniform.md | 314 +++++++++++++ aidocs/modal.md | 295 ++++++++++++ aidocs/multiple_state_image.md | 170 +++++++ aidocs/myoperator.md | 117 +++++ aidocs/myvad.md | 164 +++++++ aidocs/page_data_loader.md | 317 +++++++++++++ aidocs/paging.md | 272 ++++++++++++ aidocs/period.md | 322 ++++++++++++++ aidocs/pie.md | 257 +++++++++++ aidocs/popup.md | 502 +++++++++++++++++++++ aidocs/progressbar.md | 150 +++++++ aidocs/qaframe.md | 343 ++++++++++++++ aidocs/recorder.md | 410 +++++++++++++++++ aidocs/registerfunction.md | 183 ++++++++ aidocs/rtc.md | 435 ++++++++++++++++++ aidocs/running.md | 198 +++++++++ aidocs/scroll.md | 293 ++++++++++++ aidocs/splitter.md | 139 ++++++ aidocs/streaming_audio.md | 240 ++++++++++ aidocs/svg.md | 350 +++++++++++++++ aidocs/tab.md | 334 ++++++++++++++ aidocs/tabular.md | 304 +++++++++++++ aidocs/toolbar.md | 368 +++++++++++++++ aidocs/tree.md | 356 +++++++++++++++ aidocs/tree_choose.md | 106 +++++ aidocs/uitype.md | 274 ++++++++++++ aidocs/uitypesdef.md | 428 ++++++++++++++++++ aidocs/utils.md | 787 +++++++++++++++++++++++++++++++++ aidocs/vadtext.md | 268 +++++++++++ aidocs/video.md | 292 ++++++++++++ aidocs/videoplayer.md | 398 +++++++++++++++++ aidocs/views.md | 176 ++++++++ aidocs/vision.md | 90 ++++ aidocs/websocket.md | 254 +++++++++++ aidocs/webspeech.md | 240 ++++++++++ aidocs/widget.md | 499 +++++++++++++++++++++ aidocs/wsllm.md | 427 ++++++++++++++++++ aidocs/wterm.md | 347 +++++++++++++++ 79 files changed, 23597 insertions(+) create mode 100644 aidocs/accordion.md create mode 100644 aidocs/aggrid.md create mode 100644 aidocs/asr.md create mode 100644 aidocs/audio.md create mode 100644 aidocs/bar.md create mode 100644 aidocs/binstreaming.md create mode 100644 aidocs/bricks.md create mode 100644 aidocs/button.md create mode 100644 aidocs/camera.md create mode 100644 aidocs/cols.md create mode 100644 aidocs/conform.md create mode 100644 aidocs/continueaudio.md create mode 100644 aidocs/countdown.md create mode 100644 aidocs/css.md create mode 100644 aidocs/datagrid.md create mode 100644 aidocs/datarow.md create mode 100644 aidocs/dataviewer.md create mode 100644 aidocs/docxviewer.md create mode 100644 aidocs/dynamicaccordion.md create mode 100644 aidocs/dynamiccolumn.md create mode 100644 aidocs/echartsext.md create mode 100644 aidocs/factory.md create mode 100644 aidocs/floaticonbar.md create mode 100644 aidocs/form.md create mode 100644 aidocs/gobang.md create mode 100644 aidocs/html.md create mode 100644 aidocs/i18n.md create mode 100644 aidocs/iconbarpage.md create mode 100644 aidocs/iframe.md create mode 100644 aidocs/image.md create mode 100644 aidocs/input.md create mode 100644 aidocs/jsoncall.md create mode 100644 aidocs/keypress.md create mode 100644 aidocs/layout.md create mode 100644 aidocs/line.md create mode 100644 aidocs/llm.md create mode 100644 aidocs/llm_dialog.md create mode 100644 aidocs/llmout.md create mode 100644 aidocs/markdown_viewer.md create mode 100644 aidocs/menu.md create mode 100644 aidocs/message.md create mode 100644 aidocs/miniform.md create mode 100644 aidocs/modal.md create mode 100644 aidocs/multiple_state_image.md create mode 100644 aidocs/myoperator.md create mode 100644 aidocs/myvad.md create mode 100644 aidocs/page_data_loader.md create mode 100644 aidocs/paging.md create mode 100644 aidocs/period.md create mode 100644 aidocs/pie.md create mode 100644 aidocs/popup.md create mode 100644 aidocs/progressbar.md create mode 100644 aidocs/qaframe.md create mode 100644 aidocs/recorder.md create mode 100644 aidocs/registerfunction.md create mode 100644 aidocs/rtc.md create mode 100644 aidocs/running.md create mode 100644 aidocs/scroll.md create mode 100644 aidocs/splitter.md create mode 100644 aidocs/streaming_audio.md create mode 100644 aidocs/svg.md create mode 100644 aidocs/tab.md create mode 100644 aidocs/tabular.md create mode 100644 aidocs/toolbar.md create mode 100644 aidocs/tree.md create mode 100644 aidocs/tree_choose.md create mode 100644 aidocs/uitype.md create mode 100644 aidocs/uitypesdef.md create mode 100644 aidocs/utils.md create mode 100644 aidocs/vadtext.md create mode 100644 aidocs/video.md create mode 100644 aidocs/videoplayer.md create mode 100644 aidocs/views.md create mode 100644 aidocs/vision.md create mode 100644 aidocs/websocket.md create mode 100644 aidocs/webspeech.md create mode 100644 aidocs/widget.md create mode 100644 aidocs/wsllm.md create mode 100644 aidocs/wterm.md diff --git a/aidocs/accordion.md b/aidocs/accordion.md new file mode 100644 index 0000000..689b064 --- /dev/null +++ b/aidocs/accordion.md @@ -0,0 +1,205 @@ +# `bricks.Accordion` 技术文档 + +```markdown +# bricks.Accordion + +`bricks.Accordion` 是一个基于 `bricks.VBox` 的可折叠面板组件,允许用户通过点击标题按钮切换显示不同的内容区域。常用于需要节省垂直空间、分组展示信息的界面设计中。 + +--- + +## 继承关系 + +- **继承自**: `bricks.VBox` +- **注册名称**: `'Accordion'`(通过 `bricks.Factory.register` 注册) + +--- + +## 构造函数 + +### `new bricks.Accordion(opts)` + +#### 参数 + +| 参数 | 类型 | 说明 | +|------|------|------| +| `opts` | Object | 配置选项对象 | + +#### `opts` 配置项 + +| 属性名 | 类型 | 默认值 | 说明 | +|--------|------|--------|------| +| `item_size` | String | `'25px'` | 每个标题项的高度(CSS 尺寸字符串) | +| `item_css` | String | `'accordion-button'` | 标题按钮使用的 CSS 类名 | +| `content_css` | String | `'accordion-content'` | 内容区域使用的 CSS 类名 | +| `items` | Array\ | 必填 | 要显示的面板项列表 | + +##### `items` 数组元素结构 + +每个 `item` 是一个对象,包含以下字段: + +| 字段 | 类型 | 是否必需 | 说明 | +|------|------|----------|------| +| `name` | String | 是 | 唯一标识符,用于定位和缓存内容 | +| `icon` | String | 否 | 显示在按钮前的图标类名(如 Font Awesome 类) | +| `label` | String | 是 | 按钮上显示的文本标签 | +| `content` | Object | 是 | 描述子组件的配置对象(符合 `widgetBuild` 结构) | +| `refresh` | Boolean | 否 | 若为 `true`,每次点击都会重新构建内容(不使用缓存) | + +--- + +## 成员属性 + +| 属性 | 类型 | 说明 | +|------|------|------| +| `w_items` | Array\ | 存储所有标题按钮实例的数组 | +| `subcontents` | Object | 缓存已创建的内容组件,键为 `name`,值为对应的 widget 实例 | +| `content` | bricks.Filler | 包裹内容区域的容器 | +| `sub_container` | bricks.VScrollPanel | 实际承载内容的可滚动面板 | +| `key_select_items` | Array | 支持键盘导航的选择项集合(用于上下键选择) | +| `keyselectable` | Boolean | `true`,表示该组件支持键盘选择操作 | + +--- + +## 方法 + +### `constructor(opts)` + +初始化 Accordion 组件: + +1. 调用父类构造函数。 +2. 设置整体高度为 `100%`。 +3. 创建多个 `bricks.Button` 实例作为标题栏,并绑定 `click` 事件到 `change_content`。 +4. 初始化内容显示区域(`VScrollPanel`)并插入第一个项目的内容。 + +> ⚠️ 注意:第一个按钮会自动触发一次 `click` 事件以加载默认内容。 + +--- + +### `async change_content(event)` + +处理标题按钮点击事件,动态切换显示内容。 + +#### 参数 + +- `event`: DOM 事件对象,`event.target.bricks_widget` 应指向被点击的 `bricks.Button` 实例。 + +#### 行为逻辑 + +1. 获取被点击按钮的 `name`。 +2. 在 `this.opts.items` 中查找对应项的位置与配置。 +3. 判断是否需要刷新: + - 如果设置了 `refresh: true` + - 或者该内容尚未被缓存 +4. 若需刷新或未缓存,则调用 `bricks.widgetBuild()` 异步生成新内容并缓存。 +5. 清空当前内容区,并将新内容添加进 `sub_container`。 +6. 更新布局:移除旧的 `content` widget 并重新插入(确保位于正确位置)。 + +#### 错误处理 + +- 若找不到匹配的 `name`,会在控制台输出警告日志。 +- 若 `item.content` 不存在,则打印错误信息并返回。 + +--- + +## 事件绑定 + +- 所有标题按钮均监听 `click` 事件,触发 `change_content` 回调。 +- 使用 `.bind(this)` 确保回调中的 `this` 指向正确的 Accordion 实例。 + +--- + +## 示例配置 + +```javascript +var accordion = new bricks.Accordion({ + item_size: '30px', + item_css: 'my-accordion-button', + content_css: 'my-accordion-content', + items: [ + { + name: 'general', + icon: 'fa fa-home', + label: '通用设置', + content: { + widgettype: 'TextBlock', + text: '这里是通用设置内容...' + } + }, + { + name: 'advanced', + icon: 'fa fa-cog', + label: '高级选项', + refresh: true, + content: { + widgettype: 'FormPanel', + fields: [ ... ] + } + } + ] +}); +``` + +--- + +## 样式建议(CSS) + +```css +.accordion-button { + padding: 8px 12px; + background-color: #f0f0f0; + border-bottom: 1px solid #ddd; + cursor: pointer; + font-weight: bold; +} + +.accordion-button:hover { + background-color: #e0e0e0; +} + +.accordion-content { + padding: 10px; + background-color: #fff; + border: 1px solid #ddd; + min-height: 100px; +} +``` + +> 可根据实际需求覆盖默认类名或通过 `item_css` / `content_css` 自定义。 + +--- + +## 工厂注册 + +```javascript +bricks.Factory.register('Accordion', bricks.Accordion); +``` + +允许通过工厂方法创建实例: + +```javascript +bricks.widgetBuild({ widgettype: 'Accordion', ... }); +``` + +--- + +## 注意事项 + +- 内容组件是**懒加载**的,仅在首次点击时创建。 +- 支持**缓存机制**,避免重复渲染提升性能;可通过 `refresh: true` 强制重载。 +- 支持键盘导航(上下箭头选择按钮),前提是容器环境支持焦点管理。 +- `widgetBuild` 返回的是 `Promise`,因此 `change_content` 定义为 `async` 函数。 + +--- + +## 调试信息 + +启用调试模式后,点击按钮时会输出类似日志: + +```text +accordion: button= [Button Instance] name= general +``` + +可通过 `bricks.debug()` 控制开关。 + +--- +``` \ No newline at end of file diff --git a/aidocs/aggrid.md b/aidocs/aggrid.md new file mode 100644 index 0000000..1647ae8 --- /dev/null +++ b/aidocs/aggrid.md @@ -0,0 +1,226 @@ +# `bricks.AG_Grid` 技术文档 + +> 基于 [ag-Grid](https://www.ag-grid.com/) 封装的可复用 JavaScript 网格组件,继承自 `bricks.JsWidget`。 + +--- + +## 概述 + +`bricks.AG_Grid` 是一个基于 `ag-Grid` 的封装类,用于在网页中快速创建功能丰富的数据表格。它支持从远程 URL 动态加载数据,并提供列定义、排序、过滤、多选、单元格点击事件等基础功能。 + +该类继承自 `bricks.JsWidget`,遵循统一的组件初始化和生命周期管理机制。 + +--- + +## 依赖 + +- `ag-Grid`(必须全局可用,即 `agGrid` 对象已加载) +- `bricks.js` 核心库(包含 `bricks.JsWidget` 基类) + +--- + +## 构造函数 + +```js +new bricks.AG_Grid(options) +``` + +### 参数 + +| 参数 | 类型 | 必填 | 描述 | +|------|------|------|------| +| `options` | `Object` | ✅ | 配置选项对象 | + +#### `options` 属性 + +| 属性名 | 类型 | 必填 | 默认值 | 说明 | +|--------|------|------|--------|------| +| `dataurl` | `String` | ✅ | - | 数据接口 URL,返回 JSON 格式数组数据 | +| `fields` | `Array` | ✅ | - | 列字段配置列表,每个字段包含显示信息 | + +##### `fields` 字段配置项 + +| 属性名 | 类型 | 必填 | 默认值 | 说明 | +|--------|------|------|--------|------| +| `name` | `String` | ✅ | - | 字段名(对应数据中的 key) | +| `label` | `String` | ❌ | `name` | 表头显示名称 | +| `width` | `Number` | ❌ | `100` | 列宽度(像素) | + +--- + +## 类定义 + +```js +var bricks = window.bricks || {}; +bricks.AG_Grid = class extends bricks.JsWidget { + /* + opts 示例: + { + dataurl: "/api/data", + fields: [ + { name: "id", label: "ID", width: 80 }, + { name: "name", label: "姓名" }, + { name: "age", width: 60 } + ] + } + */ + + constructor(opts) { + super(opts); + this.ag_opts = {}; // ag-Grid 配置对象 + } + + init() { + // 初始化数据源 + this.datasource = { + getRows: this.getRows.bind(this), + startRow: 0 + }; + + // 设置 ag-Grid 配置项 + this.ag_opts.columnDefs = []; + this.ag_opts.rowModelType = 'infinite'; + this.ag_opts.maxConcurrentDatasourceRequests = 1; + this.ag_opts.datasource = this.datasource; + + // 生成列定义 + for (let i = 0; i < this.opts.fields.length; i++) { + const field = this.opts.fields[i]; + const colDef = { + field: field.name, + headerName: field.label || field.name, + width: field.width || 100 + }; + this.ag_opts.columnDefs.push(colDef); + } + + // 默认列行为:可排序、可过滤 + this.ag_opts.defaultColDef = { sortable: true, filter: true }; + + // 启用多行选择 + this.ag_opts.rowSelection = 'multiple'; + + // 启用行动画效果 + this.ag_opts.animateRows = true; + + // 绑定单元格点击事件 + this.ag_opts.onCellClicked = this.cell_clicked.bind(this); + + // 初始化 ag-Grid 实例 + this.aggrid = new agGrid.Grid(this.dom_element, this.ag_opts); + + // 加载初始数据(一次性加载全部) + fetch(this.opts.dataurl) + .then(response => response.json()) + .then(data => { + this.ag_opts.api.setRowData(data); // 注意:此处与 infinite model 不符,见下方说明 + }) + .catch(err => console.error('Failed to load data:', err)); + } + + cell_clicked(params) { + bricks.debug('Cell clicked:', params); + } +} +``` + +--- + +## 方法说明 + +### `constructor(opts)` + +调用父类构造函数并初始化 `this.ag_opts` 为空对象,用于后续存储 ag-Grid 配置。 + +### `init()` + +组件初始化主逻辑: + +1. 定义 `datasource` 对象(为无限滚动做准备,但当前实现未完全使用)。 +2. 遍历 `opts.fields` 构建 `columnDefs`。 +3. 设置通用表格行为(排序、过滤、多选、动画)。 +4. 创建 `ag-Grid` 实例并与 DOM 元素绑定。 +5. 使用 `fetch` 请求 `dataurl` 获取初始数据,并通过 `setRowData` 填充表格。 + +> ⚠️ **注意**:虽然设置了 `rowModelType: 'infinite'`,但实际并未正确实现 `getRows` 方法,因此当前行为更像是“客户端模型”,而非真正的无限滚动。建议根据需求调整数据加载方式。 + +### `cell_clicked(params)` + +单元格点击回调函数,输出调试信息到控制台(需 `bricks.debug` 存在)。 + +参数 `params` 包含: +- `value`: 当前单元格值 +- `column`: 列对象 +- `rowIndex`: 行索引 +- `data`: 整行数据对象 +- 更多详见 [ag-Grid 官方文档](https://www.ag-grid.com/javascript-data-grid/cell-events/) + +--- + +## 使用示例 + +```html +
+ + +``` + +--- + +## 已知问题与改进建议 + +| 问题 | 说明 | 建议 | +|------|------|------| +| `getRows` 未实现 | `datasource.getRows` 未定义,却赋值给了 `this.datasource.getRows` | 若使用 `infinite` 模式,应实现分页加载逻辑 | +| `startRow` 未绑定上下文 | `startRow` 在 `datasource` 中未正确定义为属性 | 应作为闭包变量或实例属性维护 | +| `setRowData` 不适用于 Infinite Model | `setRowData` 仅适用于客户端模型 | 改为调用 `api.setDatasource()` 并完整实现 `getRows` | +| 错误语法 | `maxConcurrentDatasourceRequests: 1,` 使用了冒号而非赋值 | 应为 `=` | +| `width` 和 `label` 的默认值写法错误 | 使用了位运算符 `|` 而非逻辑默认值 | 应使用 `||` 或 `??` | + +### 修正建议代码片段 + +```js +// 正确的字段处理 +width: field.width ?? 100, +headerName: field.label ?? field.name, + +// 正确的属性赋值 +this.ag_opts.maxConcurrentDatasourceRequests = 1; + +// 实现 getRows(若启用 infinite 模式) +getRows(params) { + fetch(`${this.opts.dataurl}?start=${params.startRow}&end=${params.endRow}`) + .then(res => res.json()) + .then(data => { + params.successCallback(data, data.length === 100 ? 10000 : data.length); + }); +} +``` + +--- + +## 总结 + +`bricks.AG_Grid` 提供了一个简洁的 ag-Grid 封装,适合快速集成静态或小规模动态数据表格。但在大数据场景下需完善 `infinite` 模式的数据源实现以提升性能。 + +建议后续优化方向: +- 完整支持分页/无限滚动 +- 支持列类型、渲染器扩展 +- 添加加载状态提示 +- 支持外部刷新方法 + +--- + +📌 **版本**: 1.0 +📅 **最后更新**: 2025-04 \ No newline at end of file diff --git a/aidocs/asr.md b/aidocs/asr.md new file mode 100644 index 0000000..962743f --- /dev/null +++ b/aidocs/asr.md @@ -0,0 +1,220 @@ +# `bricks.ASRClient` 技术文档 + +> 基于 WebSocket 的语音识别客户端组件,用于实时音频流传输与文本识别结果接收。 + +--- + +## 概述 + +`bricks.ASRClient` 是一个基于 `bricks.VBox` 的类,封装了浏览器端的语音识别功能。它通过调用 Web Audio API 获取用户麦克风输入,并使用 WebSocket 将音频数据以 Base64 编码形式发送至后端 ASR(自动语音识别)服务。同时监听服务器返回的识别结果,并触发相应事件。 + +该组件提供了一个可点击的图标按钮来控制录音的开始与停止,支持自定义图标、WebSocket 地址和附加参数。 + +--- + +## 继承关系 + +- **继承自**:`bricks.VBox` +- **注册名称**:`ASRClient`(可通过 `bricks.Factory.create('ASRClient', options)` 创建) + +```js +bricks.Factory.register('ASRClient', bricks.ASRClient); +``` + +--- + +## 构造函数 + +### `constructor(opts)` + +#### 参数 + +| 参数名 | 类型 | 说明 | +|----------------|----------|------| +| `opts` | Object | 配置选项对象,见下表 | + +##### `opts` 配置项 + +| 属性名 | 类型 | 默认值 | 说明 | +|----------------|----------|--------|------| +| `start_icon` | String | `'imgs/start_recording.svg'` | 开始录音时显示的图标路径(SVG/PNG) | +| `stop_icon` | String | `'imgs/stop_recording.svg'` | 停止录音时显示的图标路径(SVG/PNG) | +| `ws_url` | String | 必填 | WebSocket 服务器地址,例如:`wss://asr.example.com/ws` | +| `icon_options` | Object | `{}` | 传递给内部 `bricks.Svg` 图标组件的额外配置 | +| `ws_params` | Object | `{}` | 发送至 WebSocket 服务的附加参数,在每次发送音频时合并使用 | + +--- + +## 事件 + +`ASRClient` 支持以下自定义事件,可通过 `.bind()` 方法监听: + +| 事件名 | 触发时机 | 参数格式(`event.params`) | +|--------------|------------------------------|----------------------------| +| `start` | 用户点击开始录音 | 无参数 | +| `stop` | 用户点击停止录音 | 无参数 | +| `transtext` | 接收到服务器返回的识别文本 | `{ content, speaker, start, end }` | + +示例: +```js +asr.bind('transtext', function(e) { + console.log('识别结果:', e.params.content); +}); +``` + +--- + +## 属性 + +| 属性名 | 类型 | 说明 | +|---------------|---------------|------| +| `status` | String | 当前状态:`'start'` 或 `'stop'` | +| `icon` | `bricks.Svg` | 控制按钮图标实例 | +| `socket` | `WebSocket` | 连接到 ASR 服务的 WebSocket 实例 | +| `stream` | `MediaStream` | 来自 `getUserMedia` 的音频流 | +| `mediaRecorder` | `MediaRecorder` | 浏览器原生媒体录制对象,每秒收集并发送音频块 | + +--- + +## 方法 + +### `toggle_button()` + +切换录音状态(开始 ↔ 停止),并更新按钮图标。 + +- 若当前为 `'stop'`,则切换为 `'start'` 并调用 `start_recording()` +- 若当前为 `'start'`,则切换为 `'stop'` 并调用 `stop_recording()` + +绑定在图标的 `click` 事件上。 + +--- + +### `async start_recording()` + +启动麦克风录音并开始向服务器发送音频数据。 + +#### 行为流程: + +1. 调用 `navigator.mediaDevices.getUserMedia({ audio: true })` 请求麦克风权限。 +2. 创建 `MediaRecorder` 实例处理音频流。 +3. 设置 `ondataavailable` 回调:每 1 秒生成一段音频 Blob。 +4. 使用 `blobToBase64()` 工具将 Blob 转为 Base64 字符串。 +5. 构造消息体并发送至 WebSocket 服务器: + ```json + { + "type": "audiobuffer", + "data": "base64string...", + ...ws_params + } + ``` + +> ⚠️ 注意:需确保页面运行在 HTTPS 环境或本地开发环境(localhost),否则无法获取麦克风权限。 + +--- + +### `stop_recording()` + +停止 `MediaRecorder` 录音,关闭音频流轨道。 + +```js +this.mediaRecorder.stop(); +// 同时会释放麦克风资源 +``` + +--- + +### `response_data(event)` + +处理来自 WebSocket 的服务器响应。 + +#### 参数 + +- `event.data`: 服务器返回的 JSON 字符串 + +#### 动作 + +1. 解析 JSON 数据 +2. 触发 `transtext` 事件并将解析后的数据作为参数分发 + +```js +this.dispatch('transtext', parsedData); +``` + +--- + +### `response_log(event)` + +调试方法:将接收到的识别结果输出到控制台。 + +```js +console.log('response data=', event.params); +``` + +可通过重写此方法实现日志收集或 UI 更新。 + +--- + +## 内部依赖 + +| 工具/函数 | 说明 | +|----------------------|------| +| `bricks_resource(path)` | 解析资源路径的工具函数,通常用于构建静态资源 URL | +| `blobToBase64(blob)` | 异步将 Blob 转换为 Base64 编码字符串 | +| `objcopy(obj)` | 深拷贝对象(防止修改原始 `ws_params`) | + +> 示例 `blobToBase64` 实现: +> ```js +> function blobToBase64(blob) { +> return new Promise((resolve, reject) => { +> const reader = new FileReader(); +> reader.onload = () => resolve(reader.result.split(',')[1]); +> reader.onerror = reject; +> reader.readAsDataURL(blob); +> }); +> } +> ``` + +--- + +## 使用示例 + +```js +var asr = new bricks.ASRClient({ + ws_url: 'wss://your-asr-server.com/asr', + start_icon: 'imgs/mic-on.svg', + stop_icon: 'imgs/mic-off.svg', + ws_params: { + lang: 'zh-CN', + model: 'conversational' + } +}); + +// 监听识别结果 +asr.bind('transtext', function(e) { + document.getElementById('output').innerHTML += '

' + e.params.content + '

'; +}); + +// 插入到 DOM 容器 +document.body.appendChild(asr.render()); +``` + +--- + +## 注意事项 + +1. **安全性要求**:必须在安全上下文(HTTPS 或 localhost)中运行才能访问麦克风。 +2. **浏览器兼容性**:需要支持 `MediaRecorder` API 和 `WebSocket`。 +3. **性能建议**:每秒发送一次音频块,避免频繁请求;建议使用 Opus 编码压缩音频。 +4. **错误处理**:未对 `getUserMedia` 失败做降级处理,建议外层捕获异常。 + +--- + +## 版本信息 + +- **作者**:Bricks Framework Team +- **版本**:1.0 +- **最后更新**:2025年4月5日 + +--- + +📌 *文档结束* \ No newline at end of file diff --git a/aidocs/audio.md b/aidocs/audio.md new file mode 100644 index 0000000..7f850ac --- /dev/null +++ b/aidocs/audio.md @@ -0,0 +1,404 @@ +# `bricks` 音频模块技术文档 + +本文档为 `bricks` 框架中的音频相关功能模块提供详细说明,包含以下核心类: + +- `bricks.formatMs()` —— 时间格式化工具函数 +- `bricks.AudioPlayer` —— 音频播放器组件 +- `bricks.AudioRecorder` —— 音频录制与上传组件 +- `bricks.TextedAudioPlayer` —— 带文本同步的流式音频播放器 +- 工厂注册机制(通过 `bricks.Factory`) + +--- + +## 1. 工具函数:`bricks.formatMs(ms, all)` + +将毫秒数转换为可读的时间字符串,支持自定义显示粒度。 + +### 参数 + +| 参数 | 类型 | 描述 | +|------|------|------| +| `ms` | `number` | 时间(单位:毫秒) | +| `all` | `boolean?` | 是否强制显示所有时间单位(即使高位为0) | + +### 返回值 + +返回格式化的字符串,形式如:`"h:mm:ss″sss"` 或 `"mm:ss″sss"` + +- 小时部分仅在非零时显示 +- 分钟和秒根据上下文决定是否显示前导零 +- 毫秒固定三位数字补全 + +### 示例 + +```js +bricks.formatMs(3661234); // 输出: "1:01:01″234" +bricks.formatMs(61234, true); // 输出: "01:01″0234" +``` + +--- + +## 2. 音频播放器:`bricks.AudioPlayer` + +基于 HTML5 `