voice get
This commit is contained in:
11
Html/apps/static/js/audio-processor.js
Normal file
11
Html/apps/static/js/audio-processor.js
Normal file
@@ -0,0 +1,11 @@
|
||||
class AudioProcessor extends AudioWorkletProcessor {
|
||||
process(inputs, outputs) {
|
||||
const input = inputs[0];
|
||||
if (input.length > 0) {
|
||||
this.port.postMessage(input[0]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
registerProcessor('audio-processor', AudioProcessor);
|
||||
@@ -4,7 +4,7 @@ let system_message_idx = 0
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
data = window.appData;
|
||||
console.log(data);
|
||||
socket = io('wss://hsamooc.com/agent', {
|
||||
socket = io('wss://hsamooc.cn/agent', {
|
||||
query: {
|
||||
user_uuid: data.user_uuid,
|
||||
folder: data.folder
|
||||
@@ -18,6 +18,11 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
OpenIframe();
|
||||
});
|
||||
// 监听来自服务器的消息
|
||||
socket.on('voiceMessage', function (data) {
|
||||
console.log(data)
|
||||
const input = document.createElement('messageInput');
|
||||
input.data = data['data'];
|
||||
});
|
||||
socket.on('message', function (data) {
|
||||
// 显示服务器的回复消息
|
||||
const serverMessage = document.createElement('div');
|
||||
@@ -212,58 +217,76 @@ function handleMouseClick(event) {
|
||||
stopRecording();
|
||||
}
|
||||
//发送语音
|
||||
const startAudioRecording = async () => {
|
||||
try {
|
||||
const stream = await navigator.mediaDevices.getUserMedia({
|
||||
audio: {
|
||||
sampleRate: 16000,
|
||||
channelCount: 1,
|
||||
echoCancellation: true,
|
||||
noiseSuppression: true
|
||||
}
|
||||
});
|
||||
const mediaRecorder = new MediaRecorder(stream);
|
||||
const audioContext = new AudioContext({
|
||||
sampleRate: 16000
|
||||
});
|
||||
|
||||
// Load the AudioWorklet
|
||||
await audioContext.audioWorklet.addModule('/static/js/audio-processor.js');
|
||||
|
||||
const source = audioContext.createMediaStreamSource(stream);
|
||||
const workletNode = new AudioWorkletNode(audioContext, 'audio-processor');
|
||||
let audioChunks = [];
|
||||
|
||||
workletNode.port.onmessage = (e) => {
|
||||
audioChunks.push(new Float32Array(e.data));
|
||||
|
||||
if (audioChunks.length >= 16) {
|
||||
// 合并所有音频块
|
||||
const totalLength = audioChunks.reduce((acc, chunk) => acc + chunk.length, 0);
|
||||
const mergedData = new Float32Array(totalLength);
|
||||
let offset = 0;
|
||||
for (const chunk of audioChunks) {
|
||||
mergedData.set(chunk, offset);
|
||||
offset += chunk.length;
|
||||
}
|
||||
|
||||
const audioMessage = {
|
||||
id: window.data.user_uuid,
|
||||
type: 'audio',
|
||||
data: mergedData,
|
||||
sampleRate: 16000,
|
||||
timestamp: Date.now()
|
||||
};
|
||||
socket.emit('voice', audioMessage);
|
||||
console.log("voice sended")
|
||||
audioChunks = [];
|
||||
}
|
||||
};
|
||||
|
||||
source.connect(workletNode);
|
||||
workletNode.connect(audioContext.destination);
|
||||
|
||||
mediaRecorder.value = {
|
||||
stop: () => {
|
||||
source.disconnect();
|
||||
workletNode.disconnect();
|
||||
stream.getTracks().forEach(track => track.stop());
|
||||
audioContext.close();
|
||||
}
|
||||
}
|
||||
|
||||
isRecording.value = true;
|
||||
} catch (error) {
|
||||
console.error('Error starting audio recording:', error);
|
||||
}
|
||||
};
|
||||
function sendVoiceMessage() {
|
||||
p = pyaudio.PyAudio()
|
||||
startAudioRecording()
|
||||
//变换录音中图标
|
||||
document.getElementById('recordIcon').className = 'bi bi-record-circle';
|
||||
//监听
|
||||
document.addEventListener('click', handleMouseClick);
|
||||
//打开麦克风流
|
||||
voice_stream = p.open(format = FORMAT,
|
||||
channels = CHANNELS,
|
||||
rate = SAMPLE_RATE,
|
||||
input = True,
|
||||
frames_per_buffer = CHUNK_SIZE)
|
||||
audio_chunks = []
|
||||
|
||||
recordingInterval = setInterval(() => {
|
||||
if (!isRecording) {
|
||||
clearInterval(recordingInterval);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// 从麦克风读取音频数据
|
||||
let audio_data = voice_stream.read(CHUNK_SIZE);
|
||||
|
||||
if (!audio_data || audio_data.length === 0) {
|
||||
stopRecording();
|
||||
return;
|
||||
}
|
||||
|
||||
// 保留原始 PCM 二进制数据
|
||||
audio_chunks.push(audio_data);
|
||||
|
||||
// 当积累到一定数量的块时,发送
|
||||
if (audio_chunks.length >= 16) {
|
||||
const merged_data = new Uint8Array(
|
||||
audio_chunks.reduce((acc, chunk) => acc + chunk.length, 0)
|
||||
);
|
||||
let offset = 0;
|
||||
for (const chunk of audio_chunks) {
|
||||
merged_data.set(new Uint8Array(chunk), offset);
|
||||
offset += chunk.length;
|
||||
}
|
||||
// 发送到服务器
|
||||
socket.emit('VoiceMessage', merged_data, { binary: true });
|
||||
// 清空音频块,准备接收下一批数据
|
||||
audio_chunks = [];
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error reading audio data:', error);
|
||||
stopRecording();
|
||||
}
|
||||
}, 10); // 每 10 毫秒检查一次录音状态
|
||||
}
|
||||
|
||||
//停止录音
|
||||
|
||||
Reference in New Issue
Block a user