bugfix
This commit is contained in:
parent
f66e68921e
commit
cadff9d654
@ -267,6 +267,56 @@ bricks.SttClient = class extends bricks.VBox {
|
|||||||
this.result_text.set_text(txt);
|
this.result_text.set_text(txt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bricks.ContinueAudioPlayer = class extends bricks.AudioPlayer {
|
||||||
|
constructor(opts){
|
||||||
|
this.options = opts
|
||||||
|
this.audioContext = null;
|
||||||
|
this.nextStartTime = 0;
|
||||||
|
this.started = false;
|
||||||
|
this.initAudioContext(); // 初始化音频上下文
|
||||||
|
}
|
||||||
|
initAudioContext() {
|
||||||
|
this.audioContext = new (window.AudioContext || window.webkitAudioContext)();
|
||||||
|
this.nextStartTime = this.audioContext.currentTime;
|
||||||
|
this.started = true;
|
||||||
|
}
|
||||||
|
handleAudioTrack(arrayBuffer) {
|
||||||
|
this.audioContext.decodeAudioData(arrayBuffer).then(decodedBuffer => {
|
||||||
|
const source = this.audioContext.createBufferSource();
|
||||||
|
source.buffer = decodedBuffer;
|
||||||
|
source.connect(this.audioContext.destination);
|
||||||
|
|
||||||
|
// 连续播放安排
|
||||||
|
const startTime = Math.max(this.audioContext.currentTime, this.nextStartTime);
|
||||||
|
source.start(startTime);
|
||||||
|
|
||||||
|
this.nextStartTime = startTime + decodedBuffer.duration;
|
||||||
|
}).catch(err => {
|
||||||
|
console.error("Error decoding audio data:", err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
pauseAudio() {
|
||||||
|
if (this.audioContext && this.audioContext.state === 'running') {
|
||||||
|
this.audioContext.suspend().then(() => {
|
||||||
|
console.log("Audio playback paused.");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ▶️ 恢复音频播放(继续 AudioContext)
|
||||||
|
*/
|
||||||
|
resumeAudio() {
|
||||||
|
if (this.audioContext && this.audioContext.state === 'suspended') {
|
||||||
|
this.audioContext.resume().then(() => {
|
||||||
|
console.log("Audio playback resumed.");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
bricks.Factory.register('AudioPlayer', bricks.AudioPlayer);
|
bricks.Factory.register('AudioPlayer', bricks.AudioPlayer);
|
||||||
bricks.Factory.register('AudioRecorder', bricks.AudioRecorder);
|
bricks.Factory.register('AudioRecorder', bricks.AudioRecorder);
|
||||||
bricks.Factory.register('SttClient', bricks.SttClient);
|
bricks.Factory.register('SttClient', bricks.SttClient);
|
||||||
|
|
||||||
|
|
||||||
|
134
bricks/continueaudio.js
Normal file
134
bricks/continueaudio.js
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
var bricks = window.bricks || {};
|
||||||
|
|
||||||
|
bricks.ContinueAudioPlayer = class extends class bricks.VBox {
|
||||||
|
constructor(options) {
|
||||||
|
super(options);
|
||||||
|
this.ws_url = options.ws_url;
|
||||||
|
this.options = options || {};
|
||||||
|
this.audioContext = null;
|
||||||
|
this.gainNode = null;
|
||||||
|
this.nextStartTime = 0;
|
||||||
|
this.started = false;
|
||||||
|
this.muted = false;
|
||||||
|
this.volume = 1.0;
|
||||||
|
|
||||||
|
this.initAudioContext();
|
||||||
|
this.initWebSocket();
|
||||||
|
}
|
||||||
|
|
||||||
|
initAudioContext() {
|
||||||
|
this.audioContext = new (window.AudioContext || window.webkitAudioContext)();
|
||||||
|
this.gainNode = this.audioContext.createGain();
|
||||||
|
this.gainNode.gain.value = this.volume;
|
||||||
|
this.gainNode.connect(this.audioContext.destination);
|
||||||
|
|
||||||
|
this.nextStartTime = this.audioContext.currentTime;
|
||||||
|
this.started = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
base64ToArrayBuffer(base64) {
|
||||||
|
const binaryStr = atob(base64);
|
||||||
|
const len = binaryStr.length;
|
||||||
|
const bytes = new Uint8Array(len);
|
||||||
|
for (let i = 0; i < len; i++) {
|
||||||
|
bytes[i] = binaryStr.charCodeAt(i);
|
||||||
|
}
|
||||||
|
return bytes.buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
handleAudioTrack(arrayBuffer) {
|
||||||
|
this.audioContext.decodeAudioData(arrayBuffer).then(decodedBuffer => {
|
||||||
|
const source = this.audioContext.createBufferSource();
|
||||||
|
source.buffer = decodedBuffer;
|
||||||
|
source.connect(this.gainNode);
|
||||||
|
|
||||||
|
const startTime = Math.max(this.audioContext.currentTime, this.nextStartTime);
|
||||||
|
source.start(startTime);
|
||||||
|
|
||||||
|
this.nextStartTime = startTime + decodedBuffer.duration;
|
||||||
|
|
||||||
|
if (typeof this.options.onStart === 'function') {
|
||||||
|
this.options.onStart();
|
||||||
|
}
|
||||||
|
|
||||||
|
source.onended = () => {
|
||||||
|
if (typeof this.options.onEnd === 'function') {
|
||||||
|
this.options.onEnd();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}).catch(err => {
|
||||||
|
console.error("Error decoding audio data:", err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ⏸ 暂停播放
|
||||||
|
*/
|
||||||
|
pauseAudio() {
|
||||||
|
if (this.audioContext && this.audioContext.state === 'running') {
|
||||||
|
this.audioContext.suspend().then(() => {
|
||||||
|
if (typeof this.options.onPause === 'function') {
|
||||||
|
this.options.onPause();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ▶️ 恢复播放
|
||||||
|
*/
|
||||||
|
resumeAudio() {
|
||||||
|
if (this.audioContext && this.audioContext.state === 'suspended') {
|
||||||
|
this.audioContext.resume().then(() => {
|
||||||
|
if (typeof this.options.onResume === 'function') {
|
||||||
|
this.options.onResume();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 🔁 重新开始播放
|
||||||
|
*/
|
||||||
|
restart() {
|
||||||
|
console.log("Restarting audio playback...");
|
||||||
|
if (this.audioContext && this.audioContext.state !== 'closed') {
|
||||||
|
this.audioContext.close().then(() => {
|
||||||
|
this.initAudioContext();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.initAudioContext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 🔊 设置音量(0.0 - 1.0)
|
||||||
|
*/
|
||||||
|
setVolume(value) {
|
||||||
|
this.volume = Math.max(0, Math.min(1, value));
|
||||||
|
if (this.gainNode) {
|
||||||
|
this.gainNode.gain.value = this.muted ? 0 : this.volume;
|
||||||
|
}
|
||||||
|
this.emit('onVolumeChange', this.volume);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 🔇 切换静音
|
||||||
|
*/
|
||||||
|
toggleMute() {
|
||||||
|
this.muted = !this.muted;
|
||||||
|
this.gainNode.gain.value = this.muted ? 0 : this.volume;
|
||||||
|
this.emit('onVolumeChange', this.muted ? 0 : this.volume);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 🧩 触发事件回调
|
||||||
|
*/
|
||||||
|
emit(eventName, ...args) {
|
||||||
|
if (typeof this.options[eventName] === 'function') {
|
||||||
|
this.options[eventName](...args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bricks.Factory.register('ContinueAudioPlayer', bricks.ContinueAudioPlayer);
|
Loading…
Reference in New Issue
Block a user