GateWay/src/assets/js/audio-transmitter.js
2025-03-26 17:10:39 +08:00

204 lines
5.9 KiB
JavaScript

// audio-transmitter.js
export default {
data() {
return {
ws: null, // WebSocket 连接
mediaRecorder: null, // MediaRecorder 实例
audioChunks: [], // 音频数据
status: '点击按钮开始传输音频',
isRecording: false, // 用于判断是否在录音
audioConfig: {
sampleRate: 44100, // 固定为 44100Hz
bitsPerSample: 16, // 固定为 16 位深度
channels: 2 // 固定为双声道
},
stream: null,
audioContext: null,
worklet: null,
lastSendTime: 0,
sendInterval: 200, // 数据传输间隔(毫秒)
audioWs: null, // 音频 WebSocket 连接
};
},
beforeDestroy() {
// 组件销毁前清理资源
this.cleanup();
// 关闭主 WebSocket 连接
if (this.ws) {
console.log('关闭主 WebSocket 连接');
this.ws.close();
this.ws = null;
}
},
methods: {
toggleRecording() {
if (this.isRecording) {
this.stopRecording();
} else {
this.startRecording();
}
},
async startRecording() {
if (this.isRecording) return;
console.log('音频传输器: 开始录音');
this.status = '开始录音并传输音频...';
this.isRecording = true;
const constraints = {
audio: {
sampleRate: this.audioConfig.sampleRate,
channelCount: this.audioConfig.channels,
sampleSize: this.audioConfig.bitsPerSample
}
};
console.log('使用的音频配置:', constraints);
try {
// 直接获取麦克风权限,不再重新建立 WebSocket 连接
const stream = await navigator.mediaDevices.getUserMedia(constraints);
console.log('成功获取麦克风权限');
const audioContext = new AudioContext({
sampleRate: this.audioConfig.sampleRate
});
await audioContext.audioWorklet.addModule('audio-processor.js');
const source = audioContext.createMediaStreamSource(stream);
const worklet = new AudioWorkletNode(audioContext, 'audio-processor');
worklet.port.onmessage = (event) => {
if (this.audioWs && this.audioWs.readyState === WebSocket.OPEN) {
const currentTime = Date.now();
if (!this.lastSendTime || currentTime - this.lastSendTime > this.sendInterval) {
const pcmData = new Int16Array(event.data);
console.log('发送的音频数据:', Array.from(pcmData.slice(0, 20)));
this.audioWs.send(event.data);
this.lastSendTime = currentTime;
}
}
};
source.connect(worklet);
worklet.connect(audioContext.destination);
this.stream = stream;
this.audioContext = audioContext;
this.worklet = worklet;
} catch (error) {
console.error('音频初始化失败:', error);
this.cleanup();
return;
}
},
// stopRecording() {
// console.log('音频传输器: 停止录音');
// this.status = '停止录音';
// this.isRecording = false;
// // 关闭音频资源
// if (this.stream) {
// console.log('关闭音频流');
// this.stream.getTracks().forEach(track => track.stop());
// }
// if (this.worklet) {
// console.log('断开 AudioWorklet');
// this.worklet.disconnect();
// }
// if (this.audioContext) {
// console.log('关闭音频上下文');
// this.audioContext.close();
// }
// // 关闭音频 WebSocket 连接
// if (this.audioWs) {
// console.log('关闭音频 WebSocket 连接');
// this.audioWs.close();
// this.audioWs = null;
// }
// }
// 修改停止录音方法
stopRecording() {
console.log('音频传输器: 停止录音');
this.status = '停止录音';
this.isRecording = false;
// 异步关闭防止状态冲突
const cleanup = async () => {
// 优先关闭音频流
if (this.stream) {
console.log('关闭音频流');
this.stream.getTracks().forEach(track => track.stop());
this.stream = null;
}
// 断开音频处理节点
if (this.worklet) {
console.log('断开 AudioWorklet');
this.worklet.disconnect();
this.worklet = null;
}
// 安全关闭音频上下文
if (this.audioContext && this.audioContext.state !== 'closed') {
console.log('关闭音频上下文');
await this.audioContext.close();
this.audioContext = null;
}
// 移除关闭 WebSocket 的代码
// if (this.audioWs) {
// console.log('关闭音频 WebSocket 连接');
// this.audioWs.close();
// this.audioWs = null;
// }
};
cleanup().catch(error => {
console.error('清理过程中发生错误:', error);
});
},
async cleanup() {
console.log('开始清理音频资源...');
// 停止录音
if (this.isRecording) {
this.isRecording = false;
}
// 优先关闭音频流
if (this.stream) {
console.log('关闭音频流');
this.stream.getTracks().forEach(track => track.stop());
this.stream = null;
}
// 断开音频处理节点
if (this.worklet) {
console.log('断开 AudioWorklet');
this.worklet.disconnect();
this.worklet = null;
}
// 安全关闭音频上下文
if (this.audioContext && this.audioContext.state !== 'closed') {
console.log('关闭音频上下文');
await this.audioContext.close();
this.audioContext = null;
}
// 关闭音频 WebSocket 连接
// if (this.audioWs) {
// console.log('关闭音频 WebSocket 连接');
// this.audioWs.close();
// this.audioWs = null;
// }
}
}
};