5.4 KiB
ContinueAudioPlayer
该控件是一个容器控件,继承自 bricks.VBox,用于在浏览器中连续播放通过 WebSocket 或 Base64 编码传输的音频数据。它基于 Web Audio API 实现高精度、低延迟的音频播放控制,支持暂停、恢复、重新开始、音量调节和静音功能。适用于语音播报、实时通信、在线教育等需要无缝播放多个音频片段的场景。
主要方法
-
initAudioContext()
初始化 Web Audio API 的上下文(AudioContext)和增益节点(GainNode),为后续音频播放做准备。 -
base64ToArrayBuffer(base64)
将 Base64 编码的音频字符串转换为 ArrayBuffer,供decodeAudioData使用。 -
handleAudioTrack(arrayBuffer)
解码并播放传入的音频数据(ArrayBuffer),自动管理播放时间线,确保多个音频连续播放不重叠。 -
pauseAudio()
暂停当前播放的音频(实际是挂起 AudioContext)。 -
resumeAudio()
恢复被暂停的音频播放。 -
restart()
关闭当前 AudioContext 并重新初始化,从头开始播放。 -
setVolume(value)
设置音量(0.0 ~ 1.0),自动更新增益节点,并触发onVolumeChange事件。 -
toggleMute()
切换静音状态,同时更新增益值并发出音量变化事件。 -
emit(eventName, ...args)
触发配置中的回调函数,如onStart、onEnd等。
主要事件
这些事件可通过 options 配置传入回调函数,在特定时刻执行逻辑:
onStart:当一个音频轨道开始播放时触发。onEnd:当一个音频轨道播放结束后触发。onPause:调用pauseAudio成功后触发。onResume:调用resumeAudio成功后触发。onVolumeChange:音量或静音状态改变时触发,参数为当前有效音量(静音时为 0)。
源码例子
{
"id": "audioPlayerContainer",
"widgettype": "ContinueAudioPlayer",
"options": {
"ws_url": "wss://example.com/audio-stream", // 可选:WebSocket 地址(若使用流式接收)
"onStart": "function() { console.log('音频开始播放'); }",
"onEnd": "function() { console.log('音频播放结束'); }",
"onPause": "function() { bricks.getWidget('playBtn').setValue('▶️ 播放'); }",
"onResume": "function() { bricks.getWidget('playBtn').setValue('⏸️ 暂停'); }",
"onVolumeChange": "function(vol) { bricks.getWidget('volumeSlider').setValue(vol); }"
},
"subwidgets": [
{
"id": "controlBar",
"widgettype": "HBox",
"subwidgets": [
{
"id": "playBtn",
"widgettype": "Button",
"options": {
"value": "▶️ 播放",
"onClick": "function() { var player = bricks.getWidget('audioPlayerContainer'); if (player.audioContext.state === 'running') { player.pauseAudio(); } else { player.resumeAudio(); } }"
}
},
{
"id": "restartBtn",
"widgettype": "Button",
"options": {
"value": "🔁 重新开始",
"onClick": "function() { bricks.getWidget('audioPlayerContainer').restart(); }"
}
},
{
"id": "muteBtn",
"widgettype": "Button",
"options": {
"value": "🔊 静音",
"onClick": "function() { var player = bricks.getWidget('audioPlayerContainer'); player.toggleMute(); this.setValue(player.muted ? '🔇 取消静音' : '🔊 静音'); }"
}
},
{
"id": "volumeSlider",
"widgettype": "Slider",
"options": {
"min": 0,
"max": 1,
"step": 0.01,
"value": 1,
"onChange": "function(val) { bricks.getWidget('audioPlayerContainer').setVolume(val); }"
}
}
]
}
],
"binds": [
{
"actiontype": "method",
"wid": "externalStartTrigger",
"event": "click",
"target": "audioPlayerContainer",
"method": "resumeAudio",
"conform": {
"title": "确认播放",
"message": "确定要开始播放音频吗?",
"confirmButtonText": "确定",
"cancelButtonText": "取消"
}
},
{
"actiontype": "script",
"wid": "dataReceiver",
"event": "audioDataReady",
"target": "audioPlayerContainer",
"datascript": "return base64EncodedAudioChunk;", // 假设外部脚本提供了此变量
"script": "const buf = widget.base64ToArrayBuffer(rtdata); widget.handleAudioTrack(buf);"
}
]
}
✅ 注释说明:
ContinueAudioPlayer本身作为容器,包含一组控制按钮(播放/暂停、重启、静音、音量滑块)。binds中定义了两个行为:
- 点击外部元素
externalStartTrigger时,调用播放器的resumeAudio方法,带确认弹窗。- 当
dataReceiver组件触发audioDataReady事件时,执行脚本将 Base64 数据转为 ArrayBuffer 并交给播放器处理。- 所有 UI 控件通过 ID 获取实例并与
ContinueAudioPlayer实例交互。- 回调函数使用字符串形式的
function(){}写法,符合 Bricks.js 对 options 中函数的序列化要求。
💡 提示:
要实现真正的“持续”播放,需保证不断向 handleAudioTrack 方法传入新的音频数据块(ArrayBuffer)。可结合 WebSocket 接收流式音频并解码推送至此控件。