bricks/bricks/asr.js
2025-04-11 10:45:26 +08:00

77 lines
2.1 KiB
JavaScript

var bricks = window.bricks || {};
bricks.ASRClient = class extends bricks.VBox {
/*
options:
{
start_icon:record.png,
stop_icon:stop.png
ws_url:
icon_options
ws_params:
}
event:
start: start recording, no params
stop: stop recording, no params
transtext: recognised text, params={
"content":
"speaker":
"start":
"end":
}
*/
constructor(opts){
super(opts);
var icon_options = this.icon_options || {};
icon_options.url = this.start_icon || bricks_resource('imgs/start_recording.png');
this.icon = new bricks.Icon(icon_options);
this.status = 'stop';
this.icon.bind('click', this.toggle_button.bind(this));
this.add_widget(this.icon);
var sessdata = bricks.app.get_session();
this.socket = new WebSocket(this.ws_url, sessdata);
this.socket.onmessage = this.response_data.bind(this);
this.bind('transtext', this.response_log.bind(this));
}
response_log(event){
console.log('response data=', event.params);
}
toggle_button(){
if (this.status == 'stop'){
this.icon.set_url(this.start_icon||bricks_resource('imgs/stop_recording.png'));
this.status = 'start';
this.start_recording();
} else {
this.icon.set_url(this.stop_icon||bricks_resource('imgs/start_recording.png'));
this.status = 'stop';
this.stop_recording();
}
}
async start_recording() {
this.stream = await navigator.mediaDevices.getUserMedia({ audio: true });
this.mediaRecorder = new MediaRecorder(this.stream);
this.mediaRecorder.ondataavailable = (event) => {
if (event.data.size > 0) {
// 将音频数据通过 WebSocket 发送到服务器
blobToBase64(event.data).then((b64str) => {
var d = objcopy(this.ws_params);
d.type = 'audiobuffer';
d.data = b64str;
this.socket.send(JSON.stringify(d));
}).catch((error) => {
console.log('Error', error);
});
}
}
this.mediaRecorder.start(1000); // 每 1 秒发送一次数据
}
stop_recording(){
this.mediaRecorder.stop();
}
response_data(event){
var d = JSON.parse(event.data);
this.dispatch('transtext', d);
}
}
bricks.Factory.register('ASRClient', bricks.ASRClient);