bricks/docs/ai.old/audio.md
2025-11-18 14:59:26 +08:00

282 lines
8.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# AudioPlayer
用于播放音频文件的普通控件,继承自 `JsWidget`。支持本地或远程音频资源播放、自动播放、播放控制(暂停/继续)、播放队列管理以及通过流式响应动态加载多个音频片段。
**类型:** 普通控件(非容器控件)
---
## 主要方法
- `play()`
异步方法,开始播放当前音频。如果音频已暂停,则恢复播放。
- `toggle_play()`
异步方法,切换播放/暂停状态。若当前为暂停状态则播放,否则暂停。
- `set_url(url)`
设置音频源并立即开始播放。参数 `url` 为音频文件的 URL 地址。
- `set_source(url)`
设置音频源(仅更新 `<source>` 标签和 `audio.src`),不自动播放。
- `add_url(url)`
将指定 URL 添加到播放列表末尾。如果当前音频处于“错误”或“结束”状态,则立即切换播放该音频;否则加入队列等待自动播放下一首。
- `get_status()`
获取当前播放器的状态,返回值为以下之一:
- `"playing"`:正在播放
- `"paused"`:已暂停
- `"loading"`:加载中(数据不足)
- `"ended"`:播放结束
- `"error"`:发生错误
- `set_stream_urls(response)`
接收一个 `Response` 对象(如从 `fetch` 流式接口获取),解析其流中的每一段音频 URL并逐个播放。适用于服务器推送多个音频片段的场景。
- `play_srclist(event)`
内部异步方法,用于从 `srcList` 中按顺序播放未播放过的音频片段。
---
## 主要事件
- `ended`
当所有音频播放完毕(包括播放列表中的最后一个)时触发。可用于通知上层组件播放完成。
---
## 源码例子
```json
{
"id": "player1",
"widgettype": "AudioPlayer",
"options": {
"url": "/audio/intro.mp3", // 初始音频URL
"autoplay": true // 是否自动播放
},
"binds": [
{
"actiontype": "method",
"wid": "btn_toggle",
"event": "click",
"target": "player1",
"method": "toggle_play",
"params": {}
},
{
"actiontype": "method",
"wid": "btn_next",
"event": "click",
"target": "player1",
"method": "add_url",
"params": {
"url": "/audio/chapter2.mp3"
}
},
{
"actiontype": "script",
"wid": "player1",
"event": "ended",
"target": "Popup",
"script": "bricks.alert('播放完成!');"
}
]
}
```
> **注释说明:**
> - 此控件 ID 为 `player1`,初始加载并自动播放 `/audio/intro.mp3`。
> - 点击 ID 为 `btn_toggle` 的按钮会调用 `toggle_play()` 方法实现播放/暂停切换。
> - 点击 `btn_next` 按钮将添加新的音频到播放队列。
> - 当音频播放结束后,弹出提示框告知用户“播放完成”。
---
# AudioRecorder
音频录制控件,继承自 `HBox`(水平布局容器控件)。提供麦克风录音功能,支持 WAV 格式录音、实时录音时长显示、录音开始/结束事件派发,并可配置上传 URL 实现录音文件自动上传。
**类型:** 容器控件(继承自 HBox包含子控件
---
## 主要方法
- `start_recording()`
开始录音。若尚未打开麦克风权限,则先请求授权并初始化录音器。
- `stop_recording()`
停止录音,生成 Blob 对象并派发 `record_ended` 事件,携带录音数据与播放 URL。
- `pause_recording()`
暂停录音(如有支持)。
- `resume_recording()`
恢复暂停的录音。
- `upload()`
异步方法,将最近一次录音的数据通过 FormData 上传至 `upload_url` 配置的地址,使用 POST 请求发送文件 `recorder.wav`
- `download()`
下载当前录音文件,生成临时链接并触发浏览器下载行为。
- `recOpen()` / `recClose()`
内部方法,用于打开/关闭麦克风访问权限及初始化 Recorder 实例。
---
## 主要事件
- `record_started`
当录音开始前触发,可用于 UI 更新(如切换图标、启用播放预览等)。
- `record_ended`
录音停止后触发,携带数据对象 `{ data: Blob, url: string, duration: number }`,可用于预览或上传。
- `uploaded`
成功上传录音后触发,携带服务器返回结果 `ret`
---
## 源码例子
```json
{
"id": "recorder1",
"widgettype": "AudioRecorder",
"options": {
"upload_url": "/api/upload_audio", // 录音上传地址
"start_icon": "imgs/start_recording.svg", // 开始录音图标
"stop_icon": "imgs/stop_recording.svg", // 停止录音图标
"icon_rate": 2 // SVG 图标缩放比例
},
"binds": [
{
"actiontype": "event",
"wid": "recorder1",
"event": "record_started",
"target": "status_text",
"dispatch_event": "set_text",
"params": {
"text": "正在录音..."
}
},
{
"actiontype": "event",
"wid": "recorder1",
"event": "record_ended",
"target": "status_text",
"dispatch_event": "set_text",
"params": {
"text": "录音结束,正在上传..."
}
},
{
"actiontype": "registerfunction",
"wid": "recorder1",
"event": "uploaded",
"rfname": "onAudioUploaded",
"params": {
"recorderId": "recorder1"
}
},
{
"actiontype": "method",
"wid": "btn_download",
"event": "click",
"target": "recorder1",
"method": "download",
"params": {}
}
]
}
```
> **注释说明:**
> - 控件 ID 为 `recorder1`,使用自定义图标进行视觉反馈。
> - 录音开始时,向 `status_text` 文本控件派发 `set_text` 事件更新状态。
> - 录音结束后提示“正在上传”,并在上传成功后调用全局注册函数 `onAudioUploaded` 处理后续逻辑。
> - 提供一个下载按钮 `btn_download`,允许用户手动下载录音文件。
---
# TextedAudioPlayer
带文本同步显示的音频播放器,继承自 `VBox`(垂直容器控件)。常用于语音朗读+字幕同步场景。能够接收流式 JSON 数据,其中包含音频 Base64 编码片段和对应文本内容,实现边接收边播放边展示文本的效果。
**类型:** 容器控件(可包含子控件)
---
## 主要方法
- `set_stream_urls(response)`
接收一个 `Response` 流对象,从中读取 JSON 数据流(每个 JSON 包含 `audio``text` 字段),解码后缓存至内部队列。
- `load_stream_data(json)`
内部异步方法,处理每一个流式到达的 JSON 数据块,将其推入播放缓冲区,并尝试触发播放。
- `playnext()`
从缓冲区取出下一条音频+文本数据,设置音频播放,并更新文本区域内容。当播放完当前音频后自动触发下一首。
---
## 主要事件
无自定义事件对外暴露,但内部监听 `AudioPlayer``ended` 事件以驱动连续播放。
---
## 源码例子
```json
{
"id": "texted_player",
"widgettype": "TextedAudioPlayer",
"options": {
"height": "300px",
"width": "100%"
},
"subwidgets": [],
"binds": [
{
"actiontype": "urlwidget",
"wid": "btn_start_read",
"event": "click",
"target": "texted_player",
"options": {
"url": "/api/stream-audio-text",
"method": "POST",
"params": {
"text": "{{input_text}}"
}
},
"mode": "replace"
},
{
"actiontype": "method",
"wid": "texted_player",
"event": "ended",
"target": "bricks",
"method": "notify",
"params": {
"message": "全部朗读完成"
}
}
]
}
```
> **注释说明:**
> - 控件 ID 为 `texted_player`,是一个垂直布局容器,内部包含一个 `AudioPlayer` 和一个带滚动的文本区域。
> - 点击 `btn_start_read` 按钮时,向 `/api/stream-audio-text` 发起 POST 请求,传入动态文本内容(例如来自输入框的 `input_text`)。
> - 服务器以流式 JSON 响应返回多个 `{ audio: base64str, text: '...' }` 数据块,客户端逐步播放音频并同步显示文本。
> - 所有内容播放完成后,调用 `bricks.notify` 显示完成通知。
---
> ✅ **备注:**
> 上述三个控件均已通过 `bricks.Factory.register` 注册,可在 `.ui` 文件中直接使用 `widgettype` 调用。
> 使用时需确保引入依赖库:[Recorder.js](https://gitee.com/xiangyuecn/Recorder) 用于录音功能。