3s没有接受到新消息才会创建新聊天框
This commit is contained in:
@@ -20,6 +20,7 @@ class AgoraService {
|
|||||||
this.inConversation = false; // 是否在对话状态中
|
this.inConversation = false; // 是否在对话状态中
|
||||||
this.speechSegmentCallback = null; // 语音段落回调函数
|
this.speechSegmentCallback = null; // 语音段落回调函数
|
||||||
this.readableTextCallback = null; // 可读文本回调函数
|
this.readableTextCallback = null; // 可读文本回调函数
|
||||||
|
this.lastMessageTime = null; // 最后一次消息接收时间,用于判断是否需要创建新消息
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -40,45 +41,71 @@ class AgoraService {
|
|||||||
|
|
||||||
this.client.on('stream-message', (uid, message) => {
|
this.client.on('stream-message', (uid, message) => {
|
||||||
try {
|
try {
|
||||||
// 确认接收到的是字节流(Uint8Array)
|
// 确认接收到的是字节流(Uint8Array)
|
||||||
if (message instanceof Uint8Array) {
|
if (message instanceof Uint8Array) {
|
||||||
const decodedMessage = new TextDecoder().decode(message);
|
const decodedMessage = new TextDecoder().decode(message);
|
||||||
// console.log('Decoded message (Raw String):', decodedMessage);
|
const parts = decodedMessage.split('|');
|
||||||
|
const base64Data = parts[parts.length - 1];
|
||||||
const parts = decodedMessage.split('|');
|
|
||||||
const base64Data = parts[parts.length - 1];
|
|
||||||
// console.log('Extracted Base64 data:', base64Data);
|
|
||||||
|
|
||||||
const jsonString = atob(base64Data);
|
|
||||||
console.log('Decoded JSON string:', jsonString);
|
|
||||||
|
|
||||||
jsonBuffer += jsonString;
|
|
||||||
if (isCompleteJson(jsonBuffer)) {
|
|
||||||
const jsonData = JSON.parse(jsonString); // 将字符串解析为 JSON 对象
|
|
||||||
console.log('Parsed JSON object:', jsonData);
|
|
||||||
|
|
||||||
if (this.readableTextCallback && typeof this.readableTextCallback === 'function') {
|
const jsonString = atob(base64Data);
|
||||||
this.readableTextCallback(jsonData.text); // 传递解码后的文本到回调
|
console.log('Decoded JSON string:', jsonString);
|
||||||
|
|
||||||
|
// 如果新的JSON字符串以 { 开头,说明是一个新的JSON对象的开始
|
||||||
|
// 丢弃之前已经累积的数据
|
||||||
|
if (jsonString.trim().startsWith('{')) {
|
||||||
|
console.log('检测到新的JSON对象开始,重置缓冲区');
|
||||||
|
jsonBuffer = '';
|
||||||
}
|
}
|
||||||
jsonBuffer = '';
|
|
||||||
|
// 累积JSON字符串
|
||||||
return jsonData.text;
|
jsonBuffer += jsonString;
|
||||||
|
|
||||||
|
// 检查是否是完整的JSON
|
||||||
|
if (isCompleteJson(jsonBuffer)) {
|
||||||
|
const jsonData = JSON.parse(jsonBuffer); // 将字符串解析为 JSON 对象
|
||||||
|
console.log('成功解析完整JSON对象:', jsonData);
|
||||||
|
|
||||||
|
// 记录最后一次消息接收时间,用于判断是否需要创建新消息
|
||||||
|
const currentTime = new Date();
|
||||||
|
if (!this.lastMessageTime) {
|
||||||
|
this.lastMessageTime = currentTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算时间差(毫秒)
|
||||||
|
const timeDiff = currentTime - this.lastMessageTime;
|
||||||
|
|
||||||
|
// 更新最后一次消息时间
|
||||||
|
this.lastMessageTime = currentTime;
|
||||||
|
|
||||||
|
if (this.readableTextCallback && typeof this.readableTextCallback === 'function') {
|
||||||
|
this.readableTextCallback(jsonData.text); // 传递解码后的文本到回调
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonBuffer = '';
|
||||||
|
return jsonData.text;
|
||||||
|
} else {
|
||||||
|
console.log('JSON不完整,当前累积长度:', jsonBuffer.length);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log('接收的消息不是Uint8Array:', message);
|
||||||
}
|
}
|
||||||
|
} catch (error) {
|
||||||
} else {
|
console.error('处理stream-message时出错:', error);
|
||||||
console.log('Received message is not Uint8Array:', message);
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
|
||||||
console.error('Error processing stream-message:', error);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
function isCompleteJson(jsonString) {
|
function isCompleteJson(jsonString) {
|
||||||
|
const openBraces = (jsonString.match(/{/g) || []).length;
|
||||||
|
const closeBraces = (jsonString.match(/}/g) || []).length;
|
||||||
|
if (openBraces === 0 || openBraces !== closeBraces) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
JSON.parse(jsonString); // 解析测试是否为合法 JSON
|
JSON.parse(jsonString);
|
||||||
return true; // 如果能被解析,说明是完整的 JSON
|
return true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return false; // 捕获解析错误,说明 JSON 不完整
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -218,6 +245,7 @@ class AgoraService {
|
|||||||
this.inConversation = true;
|
this.inConversation = true;
|
||||||
this.speechSegmentCallback = speechCallback;
|
this.speechSegmentCallback = speechCallback;
|
||||||
this.readableTextCallback = textCallback;
|
this.readableTextCallback = textCallback;
|
||||||
|
this.lastMessageTime = new Date(); // 重置最后一次消息时间
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -104,12 +104,33 @@ export const useChatStore = defineStore('chat', {
|
|||||||
handleReadableText(text) {
|
handleReadableText(text) {
|
||||||
if (!text || !text.trim()) return;
|
if (!text || !text.trim()) return;
|
||||||
const isFromAI = text.includes('\n\n') || text.includes('<think>\n');
|
const isFromAI = text.includes('\n\n') || text.includes('<think>\n');
|
||||||
|
const currentTime = new Date();
|
||||||
|
const sender = isFromAI ? 'ai' : 'user';
|
||||||
|
|
||||||
|
// 获取最后一条消息
|
||||||
|
const lastMessage = this.lastMessage;
|
||||||
|
|
||||||
|
// 检查是否需要创建新消息或更新现有消息
|
||||||
|
if (lastMessage && lastMessage.sender === sender) {
|
||||||
|
// 计算时间差(毫秒)
|
||||||
|
const timeDiff = currentTime - new Date(lastMessage.timestamp);
|
||||||
|
|
||||||
|
// 如果时间差小于3秒,更新最后一条消息
|
||||||
|
if (timeDiff < 3000) {
|
||||||
|
// 更新最后一条消息的内容
|
||||||
|
lastMessage.content = text;
|
||||||
|
// 更新时间戳
|
||||||
|
lastMessage.timestamp = currentTime.toISOString();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果时间差大于3秒或者是不同发送者,添加新消息
|
||||||
this.addMessage({
|
this.addMessage({
|
||||||
id: Date.now(),
|
id: Date.now(),
|
||||||
content: text,
|
content: text,
|
||||||
sender: isFromAI ? 'ai' : 'user',
|
sender: sender,
|
||||||
timestamp: new Date().toISOString(),
|
timestamp: currentTime.toISOString(),
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -176,15 +197,41 @@ export const useChatStore = defineStore('chat', {
|
|||||||
* @param {string} text - 语音段落文本
|
* @param {string} text - 语音段落文本
|
||||||
*/
|
*/
|
||||||
handleSpeechSegment(text) {
|
handleSpeechSegment(text) {
|
||||||
|
console.log("处理语音段落:", text);
|
||||||
console.log("我在这里!");
|
|
||||||
if (!text || !text.trim()) return;
|
if (!text || !text.trim()) return;
|
||||||
|
|
||||||
// 更新当前转写
|
// 更新当前转写
|
||||||
this.updateTranscript(text);
|
this.updateTranscript(text);
|
||||||
|
|
||||||
// 发送消息
|
// 使用与handleReadableText相同的逻辑处理消息
|
||||||
this.sendMessage(text);
|
const currentTime = new Date();
|
||||||
|
const sender = 'user'; // 语音段落总是来自用户
|
||||||
|
|
||||||
|
// 获取最后一条消息
|
||||||
|
const lastMessage = this.lastMessage;
|
||||||
|
|
||||||
|
// 检查是否需要创建新消息或更新现有消息
|
||||||
|
if (lastMessage && lastMessage.sender === sender) {
|
||||||
|
// 计算时间差(毫秒)
|
||||||
|
const timeDiff = currentTime - new Date(lastMessage.timestamp);
|
||||||
|
|
||||||
|
// 如果时间差小于3秒,更新最后一条消息
|
||||||
|
if (timeDiff < 3000) {
|
||||||
|
// 更新最后一条消息的内容
|
||||||
|
lastMessage.content = text;
|
||||||
|
// 更新时间戳
|
||||||
|
lastMessage.timestamp = currentTime.toISOString();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果时间差大于3秒或者是不同发送者,添加新消息
|
||||||
|
this.addMessage({
|
||||||
|
id: Date.now(),
|
||||||
|
content: text,
|
||||||
|
sender: sender,
|
||||||
|
timestamp: currentTime.toISOString(),
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -201,9 +248,9 @@ export const useChatStore = defineStore('chat', {
|
|||||||
stopListening() {
|
stopListening() {
|
||||||
if (!this.inConversation) return;
|
if (!this.inConversation) return;
|
||||||
|
|
||||||
// 如果有转写内容,发送消息
|
// 如果有转写内容,使用handleSpeechSegment处理消息
|
||||||
if (this.currentTranscript.trim()) {
|
if (this.currentTranscript.trim()) {
|
||||||
this.sendMessage(this.currentTranscript.trim());
|
this.handleSpeechSegment(this.currentTranscript.trim());
|
||||||
}
|
}
|
||||||
|
|
||||||
this.endConversation();
|
this.endConversation();
|
||||||
|
|||||||
Reference in New Issue
Block a user