fix: 基本逻辑

This commit is contained in:
white 2024-10-16 18:55:30 +08:00
parent dc7b8bf343
commit 5be54dd239
5 changed files with 986 additions and 808 deletions

View File

@ -146,6 +146,10 @@
<!-- 讯飞语音识别 --> <!-- 讯飞语音识别 -->
<script> <script>
window.onload = function () { window.onload = function () {
reset();
};
function reset() {
var videoElement = document.getElementById('myVideo'); var videoElement = document.getElementById('myVideo');
var startTime = 5; // 开始时间(以秒为单位) var startTime = 5; // 开始时间(以秒为单位)
var endTime = 10; // 结束时间(以秒为单位) var endTime = 10; // 结束时间(以秒为单位)
@ -154,7 +158,9 @@
// 指定段落 // 指定段落
function playVideoSegment(startTime, endTime) { function playVideoSegment(startTime, endTime) {
videoElement.currentTime = startTime; videoElement.currentTime = startTime;
videoElement.play(); setTimeout(() => {
videoElement.play();
}, 50);
// 添加timeupdate事件监听器 // 添加timeupdate事件监听器
timeUpdateListener = function() { timeUpdateListener = function() {
@ -182,7 +188,7 @@
timeUpdateListener = null; timeUpdateListener = null;
} }
} }
// 当前AI视频循环 // 当前AI视频循环
replayVideoSegment(0, 60); replayVideoSegment(0, 60);
@ -190,7 +196,7 @@
var audioElement = document.getElementById('myAudio'); var audioElement = document.getElementById('myAudio');
var isPlaying = false; // 是否播放 var isPlaying = false; // 是否播放
audioElement.muted = true; // 先静音 audioElement.muted = true; // 先静音
// 获取页面元素 // 获取页面元素
var element = document.getElementById("elementId"); var element = document.getElementById("elementId");
@ -205,7 +211,7 @@
endRec.style.display = "none"; endRec.style.display = "none";
stopRec.style.display = "none"; stopRec.style.display = "none";
var token = null; var token = null;
let times = null; let times = null;
@ -241,7 +247,7 @@
for (let i = 0; i < exampleData.length; i++) { for (let i = 0; i < exampleData.length; i++) {
exampleData[i].name = demoData[exampleData[i].type] exampleData[i].name = demoData[exampleData[i].type]
}; };
// 过滤掉非对象类型的值 // 过滤掉非对象类型的值
const filteredData = Object.entries(exampleData).filter(([key, value]) => typeof value === 'object'); const filteredData = Object.entries(exampleData).filter(([key, value]) => typeof value === 'object');
@ -254,218 +260,224 @@
/* /*
* 实例化迅飞语音听写流式版WebAPI * 实例化迅飞语音听写流式版WebAPI
*/ */
var seconds = 10;
let seconds = 10; var gaptime = null;
const voice = new Voice({ const voice = new Voice({
// 服务接口认证信息 // 服务接口认证信息
appId: '5f4ffdeb', appId: '5f4ffdeb',
apiSecret: 'OGIwM2RlMjBkOTI5Mzk5YTJlMzUwODI5', apiSecret: 'OGIwM2RlMjBkOTI5Mzk5YTJlMzUwODI5',
apiKey: '0b17a761b6b7174b789f639119d7e29a', apiKey: '0b17a761b6b7174b789f639119d7e29a',
onWillStatusChange: function (oldStatus, newStatus) {}, onWillStatusChange: function (oldStatus, newStatus) {
console.log(oldStatus, newStatus, '交互逻辑')
},
onTextChange: function (text) { onTextChange: function (text) {
// 监听识别结果的变化 // 监听识别结果的变化
voiceTxt.innerText = text; voiceTxt.innerText = text;
marquee("marquee", "voice-txt"); marquee("marquee", "voice-txt");
let timer = setInterval(() => { // 如果已有定时器在运行,则清除它
seconds--; if (gaptime) {
clearInterval(gaptime);
if (seconds <= 0) { };
clearInterval(timer); // 重置倒计时
seconds = 10;
console.log(text)
gaptime = setInterval(() => {
console.log(seconds, '倒计时')
seconds--;
if (voiceTxt.innerText) {
console.log('有 text 参数'); // 如果有 text 参数,打印 1
clearInterval(gaptime);
gaptime = null;
// 3秒钟内没有说话就自动关闭
if (text) { if (text) {
console.log(1); // 如果有 text 参数,打印 1 statusTxt.value = '正在听…';
} else { if (!isCallbackExecuted) {
console.log("没有传入 text 参数"); // 如果没有 text 参数,执行其他逻辑 clearTimeout(times);
} times = setTimeout(() => {
} this.stop();
}, 1000);
// 3秒钟内没有说话就自动关闭
if (text) {
statusTxt.value = '正在听…';
if (!isCallbackExecuted) {
clearTimeout(times);
times = setTimeout(() => {
this.stop();
statusTxt.value = '正在说话';
const params = { msg: text };
// 判断关键字是否存在
const result = parseHealthQuery(params.msg);
isCallbackExecuted = true;
if (result) {
DetailDay(result.dataKey, result.date).then(res => {
let TargetData = res.data.data;
if (result.dataKey == 'ECGData') { const params = { msg: text };
TargetData.map(item => {
delete item.data_msg.wavefrom;
delete item.data_msg.list;
})
}
if (result.dataKey == 'bloodLiquid') {
TargetData.map(item => {
item.data_msg.cholesterol = item.data_msg.cholesterol/100;
item.data_msg.highDensity = item.data_msg.highDensity/100;
item.data_msg.triacylglycerol = item.data_msg.triacylglycerol/100;
item.data_msg.uricAcidVal = item.data_msg.uricAcidVal/10000;
item.data_msg.lowDensity = item.data_msg.lowDensity/100;
})
}
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近测量的${result.dataKey}数据为${JSON.stringify(TargetData)}, #提示data_msg为值hour_minute为检测时间。#提示:“[]”表示数据为空,请在小程序上传数据。#限制:回复不要带英文,要都转化成汉语。#限制回复内容控制在150字。#限制:忽略“压力指数、疲劳指数、心肌炎风险、冠心病风险和动脉硬化”等数据。` // 判断关键字是否存在
const result = parseHealthQuery(params.msg);
console.log(Question, '问题=========================问题');
/*
* 调用接口 传递关键信息 文字转语音
*/
const xhr = new XMLHttpRequest();
const url = 'https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation';
const apiKey = 'sk-cbb9b5ff44374fa2a8a258160ebb292d';
// 打开请求,设置为异步
xhr.open('POST', url, true);
// 设置请求头
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.setRequestHeader('Authorization', 'Bearer ' + apiKey);
xhr.setRequestHeader('X-DashScope-SSE', 'enable');
// 处理流式数据的接收(使用 progress 事件)
xhr.onprogress = function () {
const data = xhr.responseText;
// SSE 数据解析处理
const lines = data.split('\n');
lines.forEach(line => {
if (line.startsWith('data:')) {
const jsonStr = line.substring(5); // 去掉 'data:' 前缀
const parsedData = JSON.parse(jsonStr);
// 解析 content 内容
const content = parsedData.output.choices[0].message.content;
if (content) {
// 检查内容是否已经存在
if (!Subtitles.includes(content)) {
Subtitles += content;
}
};
}
});
};
// 检查请求完成
xhr.onload = function () {
if (xhr.status === 200) {
statusTxt.value = '正在说话';
RequestMicrosoft();
}
};
// 错误处理
xhr.onerror = function () {
console.error('An error occurred during the transaction', xhr.statusText);
};
/*
* 关键字转换
*/
const requestBody = {
model: 'qwen-turbo',
input: {
messages: [
{"role": "system", "content": Question},
{"role": "user", "content": `请问我${params.msg}正常吗`}
]
},
parameters: {
result_format: 'message',
incremental_output: true
}
};
xhr.send(JSON.stringify(requestBody));
isCallbackExecuted = true; isCallbackExecuted = true;
return;
}) if (result) {
} else { DetailDay(result.dataKey, result.date).then(res => {
const xhr = new XMLHttpRequest(); let TargetData = res.data.data;
const url = 'https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation';
const apiKey = 'sk-cbb9b5ff44374fa2a8a258160ebb292d'; if (result.dataKey == 'ECGData') {
TargetData.map(item => {
// 打开请求,设置为异步 delete item.data_msg.wavefrom;
xhr.open('POST', url, true); delete item.data_msg.list;
})
// 设置请求头 }
xhr.setRequestHeader('Content-Type', 'application/json'); if (result.dataKey == 'bloodLiquid') {
xhr.setRequestHeader('Authorization', 'Bearer ' + apiKey); TargetData.map(item => {
xhr.setRequestHeader('X-DashScope-SSE', 'enable'); item.data_msg.cholesterol = item.data_msg.cholesterol/100;
item.data_msg.highDensity = item.data_msg.highDensity/100;
// 处理流式数据的接收(使用 progress 事件) item.data_msg.triacylglycerol = item.data_msg.triacylglycerol/100;
xhr.onprogress = function () { item.data_msg.uricAcidVal = item.data_msg.uricAcidVal/10000;
const data = xhr.responseText; item.data_msg.lowDensity = item.data_msg.lowDensity/100;
})
// SSE 数据解析处理 }
const lines = data.split('\n');
lines.forEach(line => { Question = `请模仿全科医生的口吻与我: ${user}对话,我最近测量的${result.dataKey}数据为${JSON.stringify(TargetData)}, #提示data_msg为值hour_minute为检测时间。#提示:“[]”表示数据为空,请在小程序上传数据。#限制:回复不要带英文,要都转化成汉语。#限制回复内容控制在150字。#限制:忽略“压力指数、疲劳指数、心肌炎风险、冠心病风险和动脉硬化”等数据。`
if (line.startsWith('data:')) {
const jsonStr = line.substring(5); // 去掉 'data:' 前缀 console.log(Question, '问题=========================问题');
const parsedData = JSON.parse(jsonStr);
// 解析 content 内容 /*
const content = parsedData.output.choices[0].message.content; * 调用接口 传递关键信息 文字转语音
if (content) { */
// 检查内容是否已经存在 const xhr = new XMLHttpRequest();
if (!Subtitles.includes(content)) { const url = 'https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation';
Subtitles += content; const apiKey = 'sk-cbb9b5ff44374fa2a8a258160ebb292d';
// 打开请求,设置为异步
xhr.open('POST', url, true);
// 设置请求头
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.setRequestHeader('Authorization', 'Bearer ' + apiKey);
xhr.setRequestHeader('X-DashScope-SSE', 'enable');
// 处理流式数据的接收(使用 progress 事件)
xhr.onprogress = function () {
const data = xhr.responseText;
// SSE 数据解析处理
const lines = data.split('\n');
lines.forEach(line => {
if (line.startsWith('data:')) {
const jsonStr = line.substring(5); // 去掉 'data:' 前缀
const parsedData = JSON.parse(jsonStr);
// 解析 content 内容
const content = parsedData.output.choices[0].message.content;
if (content) {
// 检查内容是否已经存在
if (!Subtitles.includes(content)) {
Subtitles += content;
}
};
}
});
};
// 检查请求完成
xhr.onload = function () {
if (xhr.status === 200) {
statusTxt.value = '正在说话';
RequestMicrosoft();
} }
}; };
}
}); // 错误处理
}; xhr.onerror = function () {
console.error('An error occurred during the transaction', xhr.statusText);
// 检查请求完成 };
xhr.onload = function () {
if (xhr.status === 200) { /*
statusTxt.value = '正在说话'; * 关键字转换
RequestMicrosoft(); */
const requestBody = {
model: 'qwen-turbo',
input: {
messages: [
{"role": "system", "content": Question},
{"role": "user", "content": `请问我${params.msg}正常吗`}
]
},
parameters: {
result_format: 'message',
incremental_output: true
}
};
xhr.send(JSON.stringify(requestBody));
isCallbackExecuted = true;
return;
})
} else {
const xhr = new XMLHttpRequest();
const url = 'https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation';
const apiKey = 'sk-cbb9b5ff44374fa2a8a258160ebb292d';
// 打开请求,设置为异步
xhr.open('POST', url, true);
// 设置请求头
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.setRequestHeader('Authorization', 'Bearer ' + apiKey);
xhr.setRequestHeader('X-DashScope-SSE', 'enable');
// 处理流式数据的接收(使用 progress 事件)
xhr.onprogress = function () {
const data = xhr.responseText;
// SSE 数据解析处理
const lines = data.split('\n');
lines.forEach(line => {
if (line.startsWith('data:')) {
const jsonStr = line.substring(5); // 去掉 'data:' 前缀
const parsedData = JSON.parse(jsonStr);
// 解析 content 内容
const content = parsedData.output.choices[0].message.content;
if (content) {
// 检查内容是否已经存在
if (!Subtitles.includes(content)) {
Subtitles += content;
}
};
}
});
};
// 检查请求完成
xhr.onload = function () {
if (xhr.status === 200) {
statusTxt.value = '正在说话';
RequestMicrosoft();
}
};
// 错误处理
xhr.onerror = function () {
console.error('An error occurred during the transaction', xhr.statusText);
};
// 发送请求
const requestBody = {
model: 'qwen-turbo',
input: {
messages: [
{"role": "system", "content": `请模仿全科医生的口吻与我对话`},
{"role": "user", "content": params.msg}
]
},
parameters: {
result_format: 'message',
incremental_output: true
}
};
xhr.send(JSON.stringify(requestBody));
isCallbackExecuted = true;
return;
} }
}; }, 3000);
// 错误处理
xhr.onerror = function () {
console.error('An error occurred during the transaction', xhr.statusText);
};
// 发送请求
const requestBody = {
model: 'qwen-turbo',
input: {
messages: [
{"role": "system", "content": `请模仿全科医生的口吻与我对话`},
{"role": "user", "content": params.msg}
]
},
parameters: {
result_format: 'message',
incremental_output: true
}
};
xhr.send(JSON.stringify(requestBody));
isCallbackExecuted = true;
return;
} }
}, 3000); }
} else if (seconds == 0){
reset();
} }
} }, 1000);
} }
}); });
@ -506,15 +518,24 @@
function startShibie() { function startShibie() {
/**开始识别**/ /**开始识别**/
voiceTxt.innerText = ''; voiceTxt.innerText = '';
stopRec.textContent = '暂停'; stopRec.textContent = '暂停';
voice.start();
isCallbackExecuted = false; isCallbackExecuted = false;
// 先静音即可处理解决(提前做交互) // 先静音即可处理解决(提前做交互)
audioElement.muted = false; audioElement.muted = false;
audioElement.pause();
audioElement.currentTime = 0; // 检查是否可以播放,避免中断
if (!audioElement.paused) {
audioElement.currentTime = 0;
audioElement.pause();
};
seconds = 10;
voice.start();
startRec.style.display = 'none'; startRec.style.display = 'none';
endRec.style.display = 'none'; endRec.style.display = 'none';
@ -523,20 +544,28 @@
} }
function closeShibie() { function closeShibie() {
reset();
/**关闭识别**/ /**关闭识别**/
voiceTxt.innerText = ''; voiceTxt.innerText = '';
statusTxt.value = ''; statusTxt.value = '';
stopRec.textContent = '暂停'; stopRec.textContent = '暂停';
voice.stop();
// 音频 // 音频
audioElement.pause(); // 检查是否可以播放,避免中断
audioElement.currentTime = 0; if (!audioElement.paused) {
// 视频 audioElement.currentTime = 0;
audioElement.pause();
};
// 视频
replayVideoSegment(0, 60); replayVideoSegment(0, 60);
isCallbackExecuted = false; isCallbackExecuted = false;
seconds = 10;
voice.stop();
console.log('关闭识别');
startRec.style.display = 'block'; startRec.style.display = 'block';
endRec.style.display = 'none'; endRec.style.display = 'none';
@ -548,7 +577,7 @@
function showModal() { function showModal() {
modal.style.display = 'block'; modal.style.display = 'block';
dialog.style.display = 'block'; dialog.style.display = 'block';
} }
// 隐藏弹窗和遮罩 // 隐藏弹窗和遮罩
function hideModal() { function hideModal() {
@ -647,9 +676,11 @@
stopRec.style.display = 'none'; stopRec.style.display = 'none';
statusTxt.value = ''; statusTxt.value = '';
voiceTxt.innerText = ''; voiceTxt.innerText = '';
voice.stop();
replayVideoSegment(0, 60); replayVideoSegment(0, 60);
hideModal() hideModal()
// 播放结束重新开始监听
startShibie();
}); });
Subtitles = ""; Subtitles = "";
@ -748,7 +779,7 @@
// 如果没有找到匹配的数据项则返回null或错误信息这里选择返回null // 如果没有找到匹配的数据项则返回null或错误信息这里选择返回null
return null; return null;
} }
}; }
</script> </script>

View File

@ -113,7 +113,7 @@
// 遍历每一行来找到 data 字段 // 遍历每一行来找到 data 字段
lines.forEach(line => { lines.forEach(line => {
if (line.trim().startsWith('data:')) { if (line.trim().startsWith('data:')) {
isDataLine = true; isDataLine = true;
dataLines.push(line.trim().slice(5)); // 移除 'data:' 前缀 dataLines.push(line.trim().slice(5)); // 移除 'data:' 前缀
} else if (isDataLine && !line.trim()) { } else if (isDataLine && !line.trim()) {
@ -146,6 +146,10 @@
<!-- 讯飞语音识别 --> <!-- 讯飞语音识别 -->
<script> <script>
window.onload = function () { window.onload = function () {
reset();
};
function reset() {
var videoElement = document.getElementById('myVideo'); var videoElement = document.getElementById('myVideo');
var startTime = 5; // 开始时间(以秒为单位) var startTime = 5; // 开始时间(以秒为单位)
var endTime = 10; // 结束时间(以秒为单位) var endTime = 10; // 结束时间(以秒为单位)
@ -154,7 +158,9 @@
// 指定段落 // 指定段落
function playVideoSegment(startTime, endTime) { function playVideoSegment(startTime, endTime) {
videoElement.currentTime = startTime; videoElement.currentTime = startTime;
videoElement.play(); setTimeout(() => {
videoElement.play();
}, 50);
// 添加timeupdate事件监听器 // 添加timeupdate事件监听器
timeUpdateListener = function() { timeUpdateListener = function() {
@ -182,7 +188,7 @@
timeUpdateListener = null; timeUpdateListener = null;
} }
} }
// 当前AI视频循环 // 当前AI视频循环
replayVideoSegment(0, 60); replayVideoSegment(0, 60);
@ -190,7 +196,7 @@
var audioElement = document.getElementById('myAudio'); var audioElement = document.getElementById('myAudio');
var isPlaying = false; // 是否播放 var isPlaying = false; // 是否播放
audioElement.muted = true; // 先静音 audioElement.muted = true; // 先静音
// 获取页面元素 // 获取页面元素
var element = document.getElementById("elementId"); var element = document.getElementById("elementId");
@ -205,7 +211,7 @@
endRec.style.display = "none"; endRec.style.display = "none";
stopRec.style.display = "none"; stopRec.style.display = "none";
var token = null; var token = null;
let times = null; let times = null;
@ -241,7 +247,7 @@
for (let i = 0; i < exampleData.length; i++) { for (let i = 0; i < exampleData.length; i++) {
exampleData[i].name = demoData[exampleData[i].type] exampleData[i].name = demoData[exampleData[i].type]
}; };
// 过滤掉非对象类型的值 // 过滤掉非对象类型的值
const filteredData = Object.entries(exampleData).filter(([key, value]) => typeof value === 'object'); const filteredData = Object.entries(exampleData).filter(([key, value]) => typeof value === 'object');
@ -254,201 +260,229 @@
/* /*
* 实例化迅飞语音听写流式版WebAPI * 实例化迅飞语音听写流式版WebAPI
*/ */
var seconds = 10;
var gaptime = null;
const voice = new Voice({ const voice = new Voice({
// 服务接口认证信息 // 服务接口认证信息
appId: '5f4ffdeb', appId: '5f4ffdeb',
apiSecret: 'OGIwM2RlMjBkOTI5Mzk5YTJlMzUwODI5', apiSecret: 'OGIwM2RlMjBkOTI5Mzk5YTJlMzUwODI5',
apiKey: '0b17a761b6b7174b789f639119d7e29a', apiKey: '0b17a761b6b7174b789f639119d7e29a',
onWillStatusChange: function (oldStatus, newStatus) {}, onWillStatusChange: function (oldStatus, newStatus) {
console.log(oldStatus, newStatus, '交互逻辑')
},
onTextChange: function (text) { onTextChange: function (text) {
// 监听识别结果的变化 // 监听识别结果的变化
voiceTxt.innerText = text; voiceTxt.innerText = text;
marquee("marquee", "voice-txt"); marquee("marquee", "voice-txt");
// 3秒钟内没有说话就自动关闭 // 如果已有定时器在运行,则清除它
if (text) { if (gaptime) {
statusTxt.value = '正在听…'; clearInterval(gaptime);
if (!isCallbackExecuted) { };
clearTimeout(times); // 重置倒计时
times = setTimeout(() => { seconds = 10;
this.stop();
statusTxt.value = '正在说话'; console.log(text)
const params = { msg: text }; gaptime = setInterval(() => {
console.log(seconds, '倒计时')
// 判断关键字是否存在 seconds--;
const result = parseHealthQuery(params.msg); if (voiceTxt.innerText) {
isCallbackExecuted = true; console.log('有 text 参数'); // 如果有 text 参数,打印 1
clearInterval(gaptime);
if (result) { gaptime = null;
DetailDay(result.dataKey, result.date).then(res => {
let TargetData = res.data.data; // 3秒钟内没有说话就自动关闭
if (text) {
statusTxt.value = '正在听…';
if (!isCallbackExecuted) {
clearTimeout(times);
times = setTimeout(() => {
this.stop();
statusTxt.value = '正在说话';
if (result.dataKey == 'ECGData') { const params = { msg: text };
TargetData.map(item => {
delete item.data_msg.wavefrom;
delete item.data_msg.list;
})
}
if (result.dataKey == 'bloodLiquid') {
TargetData.map(item => {
item.data_msg.cholesterol = item.data_msg.cholesterol/100;
item.data_msg.highDensity = item.data_msg.highDensity/100;
item.data_msg.triacylglycerol = item.data_msg.triacylglycerol/100;
item.data_msg.uricAcidVal = item.data_msg.uricAcidVal/10000;
item.data_msg.lowDensity = item.data_msg.lowDensity/100;
})
}
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近测量的${result.dataKey}数据为${JSON.stringify(TargetData)}, #提示data_msg为值hour_minute为检测时间。#提示:“[]”表示数据为空,请在小程序上传数据。#限制:回复不要带英文,要都转化成汉语。#限制回复内容控制在150字。#限制:忽略“压力指数、疲劳指数、心肌炎风险、冠心病风险和动脉硬化”等数据。` // 判断关键字是否存在
const result = parseHealthQuery(params.msg);
console.log(Question, '问题=========================问题');
/*
* 调用接口 传递关键信息 文字转语音
*/
const xhr = new XMLHttpRequest();
const url = 'https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation';
const apiKey = 'sk-cbb9b5ff44374fa2a8a258160ebb292d';
// 打开请求,设置为异步
xhr.open('POST', url, true);
// 设置请求头
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.setRequestHeader('Authorization', 'Bearer ' + apiKey);
xhr.setRequestHeader('X-DashScope-SSE', 'enable');
// 处理流式数据的接收(使用 progress 事件)
xhr.onprogress = function () {
const data = xhr.responseText;
// SSE 数据解析处理
const lines = data.split('\n');
lines.forEach(line => {
if (line.startsWith('data:')) {
const jsonStr = line.substring(5); // 去掉 'data:' 前缀
const parsedData = JSON.parse(jsonStr);
// 解析 content 内容
const content = parsedData.output.choices[0].message.content;
if (content) {
// 检查内容是否已经存在
if (!Subtitles.includes(content)) {
Subtitles += content;
}
};
}
});
};
// 检查请求完成
xhr.onload = function () {
if (xhr.status === 200) {
statusTxt.value = '正在说话';
RequestMicrosoft();
}
};
// 错误处理
xhr.onerror = function () {
console.error('An error occurred during the transaction', xhr.statusText);
};
/*
* 关键字转换
*/
const requestBody = {
model: 'qwen-turbo',
input: {
messages: [
{"role": "system", "content": Question},
{"role": "user", "content": `请问我${params.msg}正常吗`}
]
},
parameters: {
result_format: 'message',
incremental_output: true
}
};
xhr.send(JSON.stringify(requestBody));
isCallbackExecuted = true; isCallbackExecuted = true;
return;
}) if (result) {
} else { DetailDay(result.dataKey, result.date).then(res => {
const xhr = new XMLHttpRequest(); let TargetData = res.data.data;
const url = 'https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation';
const apiKey = 'sk-cbb9b5ff44374fa2a8a258160ebb292d'; if (result.dataKey == 'ECGData') {
TargetData.map(item => {
// 打开请求,设置为异步 delete item.data_msg.wavefrom;
xhr.open('POST', url, true); delete item.data_msg.list;
})
// 设置请求头 }
xhr.setRequestHeader('Content-Type', 'application/json'); if (result.dataKey == 'bloodLiquid') {
xhr.setRequestHeader('Authorization', 'Bearer ' + apiKey); TargetData.map(item => {
xhr.setRequestHeader('X-DashScope-SSE', 'enable'); item.data_msg.cholesterol = item.data_msg.cholesterol/100;
item.data_msg.highDensity = item.data_msg.highDensity/100;
// 处理流式数据的接收(使用 progress 事件) item.data_msg.triacylglycerol = item.data_msg.triacylglycerol/100;
xhr.onprogress = function () { item.data_msg.uricAcidVal = item.data_msg.uricAcidVal/10000;
const data = xhr.responseText; item.data_msg.lowDensity = item.data_msg.lowDensity/100;
})
// SSE 数据解析处理 }
const lines = data.split('\n');
lines.forEach(line => { Question = `请模仿全科医生的口吻与我: ${user}对话,我最近测量的${result.dataKey}数据为${JSON.stringify(TargetData)}, #提示data_msg为值hour_minute为检测时间。#提示:“[]”表示数据为空,请在小程序上传数据。#限制:回复不要带英文,要都转化成汉语。#限制回复内容控制在150字。#限制:忽略“压力指数、疲劳指数、心肌炎风险、冠心病风险和动脉硬化”等数据。`
if (line.startsWith('data:')) {
const jsonStr = line.substring(5); // 去掉 'data:' 前缀 console.log(Question, '问题=========================问题');
const parsedData = JSON.parse(jsonStr);
// 解析 content 内容 /*
const content = parsedData.output.choices[0].message.content; * 调用接口 传递关键信息 文字转语音
if (content) { */
// 检查内容是否已经存在 const xhr = new XMLHttpRequest();
if (!Subtitles.includes(content)) { const url = 'https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation';
Subtitles += content; const apiKey = 'sk-cbb9b5ff44374fa2a8a258160ebb292d';
// 打开请求,设置为异步
xhr.open('POST', url, true);
// 设置请求头
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.setRequestHeader('Authorization', 'Bearer ' + apiKey);
xhr.setRequestHeader('X-DashScope-SSE', 'enable');
// 处理流式数据的接收(使用 progress 事件)
xhr.onprogress = function () {
const data = xhr.responseText;
// SSE 数据解析处理
const lines = data.split('\n');
lines.forEach(line => {
if (line.startsWith('data:')) {
const jsonStr = line.substring(5); // 去掉 'data:' 前缀
const parsedData = JSON.parse(jsonStr);
// 解析 content 内容
const content = parsedData.output.choices[0].message.content;
if (content) {
// 检查内容是否已经存在
if (!Subtitles.includes(content)) {
Subtitles += content;
}
};
}
});
};
// 检查请求完成
xhr.onload = function () {
if (xhr.status === 200) {
statusTxt.value = '正在说话';
RequestMicrosoft();
} }
}; };
}
}); // 错误处理
}; xhr.onerror = function () {
console.error('An error occurred during the transaction', xhr.statusText);
// 检查请求完成 };
xhr.onload = function () {
if (xhr.status === 200) { /*
statusTxt.value = '正在说话'; * 关键字转换
RequestMicrosoft(); */
const requestBody = {
model: 'qwen-turbo',
input: {
messages: [
{"role": "system", "content": Question},
{"role": "user", "content": `请问我${params.msg}正常吗`}
]
},
parameters: {
result_format: 'message',
incremental_output: true
}
};
xhr.send(JSON.stringify(requestBody));
isCallbackExecuted = true;
return;
})
} else {
const xhr = new XMLHttpRequest();
const url = 'https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation';
const apiKey = 'sk-cbb9b5ff44374fa2a8a258160ebb292d';
// 打开请求,设置为异步
xhr.open('POST', url, true);
// 设置请求头
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.setRequestHeader('Authorization', 'Bearer ' + apiKey);
xhr.setRequestHeader('X-DashScope-SSE', 'enable');
// 处理流式数据的接收(使用 progress 事件)
xhr.onprogress = function () {
const data = xhr.responseText;
// SSE 数据解析处理
const lines = data.split('\n');
lines.forEach(line => {
if (line.startsWith('data:')) {
const jsonStr = line.substring(5); // 去掉 'data:' 前缀
const parsedData = JSON.parse(jsonStr);
// 解析 content 内容
const content = parsedData.output.choices[0].message.content;
if (content) {
// 检查内容是否已经存在
if (!Subtitles.includes(content)) {
Subtitles += content;
}
};
}
});
};
// 检查请求完成
xhr.onload = function () {
if (xhr.status === 200) {
statusTxt.value = '正在说话';
RequestMicrosoft();
}
};
// 错误处理
xhr.onerror = function () {
console.error('An error occurred during the transaction', xhr.statusText);
};
// 发送请求
const requestBody = {
model: 'qwen-turbo',
input: {
messages: [
{"role": "system", "content": `请模仿全科医生的口吻与我对话`},
{"role": "user", "content": params.msg}
]
},
parameters: {
result_format: 'message',
incremental_output: true
}
};
xhr.send(JSON.stringify(requestBody));
isCallbackExecuted = true;
return;
} }
}; }, 3000);
// 错误处理
xhr.onerror = function () {
console.error('An error occurred during the transaction', xhr.statusText);
};
// 发送请求
const requestBody = {
model: 'qwen-turbo',
input: {
messages: [
{"role": "system", "content": `请模仿全科医生的口吻与我对话`},
{"role": "user", "content": params.msg}
]
},
parameters: {
result_format: 'message',
incremental_output: true
}
};
xhr.send(JSON.stringify(requestBody));
isCallbackExecuted = true;
return;
} }
}, 3000); }
} else if (seconds == 0){
clearInterval(gaptime);
closeShibie();
reset();
gaptime = null;
seconds = 10;
} }
} }, 1000);
} }
}); });
@ -463,7 +497,7 @@
closeShibie(); closeShibie();
}); });
// 关闭识别 // 暂停识别
stopRec.addEventListener("click", function() { stopRec.addEventListener("click", function() {
stopPlay(); stopPlay();
}); });
@ -475,25 +509,38 @@
videoElement.play(); videoElement.play();
isPlaying = true; isPlaying = true;
stopRec.textContent = '暂停'; stopRec.textContent = '暂停';
statusTxt.value = '正在播放';
endRec.style.display = 'block';
} else { } else {
audioElement.pause(); audioElement.pause();
videoElement.pause(); videoElement.pause();
isPlaying = false; isPlaying = false;
stopRec.textContent = '继续播放'; stopRec.textContent = '继续播放';
statusTxt.value = '已暂停';
endRec.style.display = 'none';
} }
}; };
function startShibie() { function startShibie() {
/**开始识别**/ /**开始识别**/
voiceTxt.innerText = ''; voiceTxt.innerText = '';
stopRec.textContent = '暂停'; stopRec.textContent = '暂停';
voice.start();
isCallbackExecuted = false; isCallbackExecuted = false;
// 先静音即可处理解决(提前做交互) // 先静音即可处理解决(提前做交互)
audioElement.muted = false; audioElement.muted = false;
audioElement.pause();
audioElement.currentTime = 0; // 检查是否可以播放,避免中断
if (!audioElement.paused) {
audioElement.currentTime = 0;
audioElement.pause();
};
seconds = 10;
voice.start();
startRec.style.display = 'none'; startRec.style.display = 'none';
endRec.style.display = 'none'; endRec.style.display = 'none';
@ -507,15 +554,21 @@
statusTxt.value = ''; statusTxt.value = '';
stopRec.textContent = '暂停'; stopRec.textContent = '暂停';
voice.stop();
// 音频 // 音频
audioElement.pause(); // 检查是否可以播放,避免中断
audioElement.currentTime = 0; if (!audioElement.paused) {
// 视频 audioElement.currentTime = 0;
audioElement.pause();
};
// 视频
replayVideoSegment(0, 60); replayVideoSegment(0, 60);
isCallbackExecuted = false; isCallbackExecuted = false;
seconds = 10;
voice.stop();
console.log('关闭识别');
startRec.style.display = 'block'; startRec.style.display = 'block';
endRec.style.display = 'none'; endRec.style.display = 'none';
@ -527,7 +580,7 @@
function showModal() { function showModal() {
modal.style.display = 'block'; modal.style.display = 'block';
dialog.style.display = 'block'; dialog.style.display = 'block';
} }
// 隐藏弹窗和遮罩 // 隐藏弹窗和遮罩
function hideModal() { function hideModal() {
@ -602,6 +655,8 @@
const blob = new Blob([content_bytes], { type: 'audio/mp3' }); const blob = new Blob([content_bytes], { type: 'audio/mp3' });
const blobUrl = URL.createObjectURL(blob); const blobUrl = URL.createObjectURL(blob);
statusTxt.value = '正在说话';
// 字幕文字 // 字幕文字
voiceTxt.innerText = str; voiceTxt.innerText = str;
marquee("marquee", "voice-txt"); marquee("marquee", "voice-txt");
@ -621,11 +676,14 @@
// 停止倒计时 // 停止倒计时
startRec.style.display = 'block'; startRec.style.display = 'block';
endRec.style.display = 'none'; endRec.style.display = 'none';
stopRec.style.display = 'none';
statusTxt.value = ''; statusTxt.value = '';
voiceTxt.innerText = ''; voiceTxt.innerText = '';
voice.stop();
replayVideoSegment(0, 60); replayVideoSegment(0, 60);
hideModal() hideModal()
// 播放结束重新开始监听
startShibie();
}); });
Subtitles = ""; Subtitles = "";
@ -724,7 +782,7 @@
// 如果没有找到匹配的数据项则返回null或错误信息这里选择返回null // 如果没有找到匹配的数据项则返回null或错误信息这里选择返回null
return null; return null;
} }
}; }
</script> </script>

View File

@ -113,7 +113,7 @@
// 遍历每一行来找到 data 字段 // 遍历每一行来找到 data 字段
lines.forEach(line => { lines.forEach(line => {
if (line.trim().startsWith('data:')) { if (line.trim().startsWith('data:')) {
isDataLine = true; isDataLine = true;
dataLines.push(line.trim().slice(5)); // 移除 'data:' 前缀 dataLines.push(line.trim().slice(5)); // 移除 'data:' 前缀
} else if (isDataLine && !line.trim()) { } else if (isDataLine && !line.trim()) {
@ -146,6 +146,10 @@
<!-- 讯飞语音识别 --> <!-- 讯飞语音识别 -->
<script> <script>
window.onload = function () { window.onload = function () {
reset();
};
function reset() {
var videoElement = document.getElementById('myVideo'); var videoElement = document.getElementById('myVideo');
var startTime = 5; // 开始时间(以秒为单位) var startTime = 5; // 开始时间(以秒为单位)
var endTime = 10; // 结束时间(以秒为单位) var endTime = 10; // 结束时间(以秒为单位)
@ -154,7 +158,9 @@
// 指定段落 // 指定段落
function playVideoSegment(startTime, endTime) { function playVideoSegment(startTime, endTime) {
videoElement.currentTime = startTime; videoElement.currentTime = startTime;
videoElement.play(); setTimeout(() => {
videoElement.play();
}, 50);
// 添加timeupdate事件监听器 // 添加timeupdate事件监听器
timeUpdateListener = function() { timeUpdateListener = function() {
@ -182,7 +188,7 @@
timeUpdateListener = null; timeUpdateListener = null;
} }
} }
// 当前AI视频循环 // 当前AI视频循环
replayVideoSegment(0, 60); replayVideoSegment(0, 60);
@ -190,7 +196,7 @@
var audioElement = document.getElementById('myAudio'); var audioElement = document.getElementById('myAudio');
var isPlaying = false; // 是否播放 var isPlaying = false; // 是否播放
audioElement.muted = true; // 先静音 audioElement.muted = true; // 先静音
// 获取页面元素 // 获取页面元素
var element = document.getElementById("elementId"); var element = document.getElementById("elementId");
@ -205,7 +211,7 @@
endRec.style.display = "none"; endRec.style.display = "none";
stopRec.style.display = "none"; stopRec.style.display = "none";
var token = null; var token = null;
let times = null; let times = null;
@ -241,7 +247,7 @@
for (let i = 0; i < exampleData.length; i++) { for (let i = 0; i < exampleData.length; i++) {
exampleData[i].name = demoData[exampleData[i].type] exampleData[i].name = demoData[exampleData[i].type]
}; };
// 过滤掉非对象类型的值 // 过滤掉非对象类型的值
const filteredData = Object.entries(exampleData).filter(([key, value]) => typeof value === 'object'); const filteredData = Object.entries(exampleData).filter(([key, value]) => typeof value === 'object');
@ -254,201 +260,229 @@
/* /*
* 实例化迅飞语音听写流式版WebAPI * 实例化迅飞语音听写流式版WebAPI
*/ */
var seconds = 10;
var gaptime = null;
const voice = new Voice({ const voice = new Voice({
// 服务接口认证信息 // 服务接口认证信息
appId: '5f4ffdeb', appId: '5f4ffdeb',
apiSecret: 'OGIwM2RlMjBkOTI5Mzk5YTJlMzUwODI5', apiSecret: 'OGIwM2RlMjBkOTI5Mzk5YTJlMzUwODI5',
apiKey: '0b17a761b6b7174b789f639119d7e29a', apiKey: '0b17a761b6b7174b789f639119d7e29a',
onWillStatusChange: function (oldStatus, newStatus) {}, onWillStatusChange: function (oldStatus, newStatus) {
console.log(oldStatus, newStatus, '交互逻辑')
},
onTextChange: function (text) { onTextChange: function (text) {
// 监听识别结果的变化 // 监听识别结果的变化
voiceTxt.innerText = text; voiceTxt.innerText = text;
marquee("marquee", "voice-txt"); marquee("marquee", "voice-txt");
// 3秒钟内没有说话就自动关闭 // 如果已有定时器在运行,则清除它
if (text) { if (gaptime) {
statusTxt.value = '正在听…'; clearInterval(gaptime);
if (!isCallbackExecuted) { };
clearTimeout(times); // 重置倒计时
times = setTimeout(() => { seconds = 10;
this.stop();
statusTxt.value = '正在说话'; console.log(text)
const params = { msg: text }; gaptime = setInterval(() => {
console.log(seconds, '倒计时')
// 判断关键字是否存在 seconds--;
const result = parseHealthQuery(params.msg); if (voiceTxt.innerText) {
isCallbackExecuted = true; console.log('有 text 参数'); // 如果有 text 参数,打印 1
clearInterval(gaptime);
if (result) { gaptime = null;
DetailDay(result.dataKey, result.date).then(res => {
let TargetData = res.data.data; // 3秒钟内没有说话就自动关闭
if (text) {
statusTxt.value = '正在听…';
if (!isCallbackExecuted) {
clearTimeout(times);
times = setTimeout(() => {
this.stop();
statusTxt.value = '正在说话';
if (result.dataKey == 'ECGData') { const params = { msg: text };
TargetData.map(item => {
delete item.data_msg.wavefrom;
delete item.data_msg.list;
})
}
if (result.dataKey == 'bloodLiquid') {
TargetData.map(item => {
item.data_msg.cholesterol = item.data_msg.cholesterol/100;
item.data_msg.highDensity = item.data_msg.highDensity/100;
item.data_msg.triacylglycerol = item.data_msg.triacylglycerol/100;
item.data_msg.uricAcidVal = item.data_msg.uricAcidVal/10000;
item.data_msg.lowDensity = item.data_msg.lowDensity/100;
})
}
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近测量的${result.dataKey}数据为${JSON.stringify(TargetData)}, #提示data_msg为值hour_minute为检测时间。#提示:“[]”表示数据为空,请在小程序上传数据。#限制:回复不要带英文,要都转化成汉语。#限制回复内容控制在150字。#限制:忽略“压力指数、疲劳指数、心肌炎风险、冠心病风险和动脉硬化”等数据。` // 判断关键字是否存在
const result = parseHealthQuery(params.msg);
console.log(Question, '问题=========================问题');
/*
* 调用接口 传递关键信息 文字转语音
*/
const xhr = new XMLHttpRequest();
const url = 'https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation';
const apiKey = 'sk-cbb9b5ff44374fa2a8a258160ebb292d';
// 打开请求,设置为异步
xhr.open('POST', url, true);
// 设置请求头
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.setRequestHeader('Authorization', 'Bearer ' + apiKey);
xhr.setRequestHeader('X-DashScope-SSE', 'enable');
// 处理流式数据的接收(使用 progress 事件)
xhr.onprogress = function () {
const data = xhr.responseText;
// SSE 数据解析处理
const lines = data.split('\n');
lines.forEach(line => {
if (line.startsWith('data:')) {
const jsonStr = line.substring(5); // 去掉 'data:' 前缀
const parsedData = JSON.parse(jsonStr);
// 解析 content 内容
const content = parsedData.output.choices[0].message.content;
if (content) {
// 检查内容是否已经存在
if (!Subtitles.includes(content)) {
Subtitles += content;
}
};
}
});
};
// 检查请求完成
xhr.onload = function () {
if (xhr.status === 200) {
statusTxt.value = '正在说话';
RequestMicrosoft();
}
};
// 错误处理
xhr.onerror = function () {
console.error('An error occurred during the transaction', xhr.statusText);
};
/*
* 关键字转换
*/
const requestBody = {
model: 'qwen-turbo',
input: {
messages: [
{"role": "system", "content": Question},
{"role": "user", "content": `请问我${params.msg}正常吗`}
]
},
parameters: {
result_format: 'message',
incremental_output: true
}
};
xhr.send(JSON.stringify(requestBody));
isCallbackExecuted = true; isCallbackExecuted = true;
return;
}) if (result) {
} else { DetailDay(result.dataKey, result.date).then(res => {
const xhr = new XMLHttpRequest(); let TargetData = res.data.data;
const url = 'https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation';
const apiKey = 'sk-cbb9b5ff44374fa2a8a258160ebb292d'; if (result.dataKey == 'ECGData') {
TargetData.map(item => {
// 打开请求,设置为异步 delete item.data_msg.wavefrom;
xhr.open('POST', url, true); delete item.data_msg.list;
})
// 设置请求头 }
xhr.setRequestHeader('Content-Type', 'application/json'); if (result.dataKey == 'bloodLiquid') {
xhr.setRequestHeader('Authorization', 'Bearer ' + apiKey); TargetData.map(item => {
xhr.setRequestHeader('X-DashScope-SSE', 'enable'); item.data_msg.cholesterol = item.data_msg.cholesterol/100;
item.data_msg.highDensity = item.data_msg.highDensity/100;
// 处理流式数据的接收(使用 progress 事件) item.data_msg.triacylglycerol = item.data_msg.triacylglycerol/100;
xhr.onprogress = function () { item.data_msg.uricAcidVal = item.data_msg.uricAcidVal/10000;
const data = xhr.responseText; item.data_msg.lowDensity = item.data_msg.lowDensity/100;
})
// SSE 数据解析处理 }
const lines = data.split('\n');
lines.forEach(line => { Question = `请模仿全科医生的口吻与我: ${user}对话,我最近测量的${result.dataKey}数据为${JSON.stringify(TargetData)}, #提示data_msg为值hour_minute为检测时间。#提示:“[]”表示数据为空,请在小程序上传数据。#限制:回复不要带英文,要都转化成汉语。#限制回复内容控制在150字。#限制:忽略“压力指数、疲劳指数、心肌炎风险、冠心病风险和动脉硬化”等数据。`
if (line.startsWith('data:')) {
const jsonStr = line.substring(5); // 去掉 'data:' 前缀 console.log(Question, '问题=========================问题');
const parsedData = JSON.parse(jsonStr);
// 解析 content 内容 /*
const content = parsedData.output.choices[0].message.content; * 调用接口 传递关键信息 文字转语音
if (content) { */
// 检查内容是否已经存在 const xhr = new XMLHttpRequest();
if (!Subtitles.includes(content)) { const url = 'https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation';
Subtitles += content; const apiKey = 'sk-cbb9b5ff44374fa2a8a258160ebb292d';
// 打开请求,设置为异步
xhr.open('POST', url, true);
// 设置请求头
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.setRequestHeader('Authorization', 'Bearer ' + apiKey);
xhr.setRequestHeader('X-DashScope-SSE', 'enable');
// 处理流式数据的接收(使用 progress 事件)
xhr.onprogress = function () {
const data = xhr.responseText;
// SSE 数据解析处理
const lines = data.split('\n');
lines.forEach(line => {
if (line.startsWith('data:')) {
const jsonStr = line.substring(5); // 去掉 'data:' 前缀
const parsedData = JSON.parse(jsonStr);
// 解析 content 内容
const content = parsedData.output.choices[0].message.content;
if (content) {
// 检查内容是否已经存在
if (!Subtitles.includes(content)) {
Subtitles += content;
}
};
}
});
};
// 检查请求完成
xhr.onload = function () {
if (xhr.status === 200) {
statusTxt.value = '正在说话';
RequestMicrosoft();
} }
}; };
}
}); // 错误处理
}; xhr.onerror = function () {
console.error('An error occurred during the transaction', xhr.statusText);
// 检查请求完成 };
xhr.onload = function () {
if (xhr.status === 200) { /*
statusTxt.value = '正在说话'; * 关键字转换
RequestMicrosoft(); */
const requestBody = {
model: 'qwen-turbo',
input: {
messages: [
{"role": "system", "content": Question},
{"role": "user", "content": `请问我${params.msg}正常吗`}
]
},
parameters: {
result_format: 'message',
incremental_output: true
}
};
xhr.send(JSON.stringify(requestBody));
isCallbackExecuted = true;
return;
})
} else {
const xhr = new XMLHttpRequest();
const url = 'https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation';
const apiKey = 'sk-cbb9b5ff44374fa2a8a258160ebb292d';
// 打开请求,设置为异步
xhr.open('POST', url, true);
// 设置请求头
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.setRequestHeader('Authorization', 'Bearer ' + apiKey);
xhr.setRequestHeader('X-DashScope-SSE', 'enable');
// 处理流式数据的接收(使用 progress 事件)
xhr.onprogress = function () {
const data = xhr.responseText;
// SSE 数据解析处理
const lines = data.split('\n');
lines.forEach(line => {
if (line.startsWith('data:')) {
const jsonStr = line.substring(5); // 去掉 'data:' 前缀
const parsedData = JSON.parse(jsonStr);
// 解析 content 内容
const content = parsedData.output.choices[0].message.content;
if (content) {
// 检查内容是否已经存在
if (!Subtitles.includes(content)) {
Subtitles += content;
}
};
}
});
};
// 检查请求完成
xhr.onload = function () {
if (xhr.status === 200) {
statusTxt.value = '正在说话';
RequestMicrosoft();
}
};
// 错误处理
xhr.onerror = function () {
console.error('An error occurred during the transaction', xhr.statusText);
};
// 发送请求
const requestBody = {
model: 'qwen-turbo',
input: {
messages: [
{"role": "system", "content": `请模仿全科医生的口吻与我对话`},
{"role": "user", "content": params.msg}
]
},
parameters: {
result_format: 'message',
incremental_output: true
}
};
xhr.send(JSON.stringify(requestBody));
isCallbackExecuted = true;
return;
} }
}; }, 3000);
// 错误处理
xhr.onerror = function () {
console.error('An error occurred during the transaction', xhr.statusText);
};
// 发送请求
const requestBody = {
model: 'qwen-turbo',
input: {
messages: [
{"role": "system", "content": `请模仿全科医生的口吻与我对话`},
{"role": "user", "content": params.msg}
]
},
parameters: {
result_format: 'message',
incremental_output: true
}
};
xhr.send(JSON.stringify(requestBody));
isCallbackExecuted = true;
return;
} }
}, 3000); }
} else if (seconds == 0){
clearInterval(gaptime);
closeShibie();
reset();
gaptime = null;
seconds = 10;
} }
} }, 1000);
} }
}); });
@ -463,7 +497,7 @@
closeShibie(); closeShibie();
}); });
// 关闭识别 // 暂停识别
stopRec.addEventListener("click", function() { stopRec.addEventListener("click", function() {
stopPlay(); stopPlay();
}); });
@ -475,25 +509,38 @@
videoElement.play(); videoElement.play();
isPlaying = true; isPlaying = true;
stopRec.textContent = '暂停'; stopRec.textContent = '暂停';
statusTxt.value = '正在播放';
endRec.style.display = 'block';
} else { } else {
audioElement.pause(); audioElement.pause();
videoElement.pause(); videoElement.pause();
isPlaying = false; isPlaying = false;
stopRec.textContent = '继续播放'; stopRec.textContent = '继续播放';
statusTxt.value = '已暂停';
endRec.style.display = 'none';
} }
}; };
function startShibie() { function startShibie() {
/**开始识别**/ /**开始识别**/
voiceTxt.innerText = ''; voiceTxt.innerText = '';
stopRec.textContent = '暂停'; stopRec.textContent = '暂停';
voice.start();
isCallbackExecuted = false; isCallbackExecuted = false;
// 先静音即可处理解决(提前做交互) // 先静音即可处理解决(提前做交互)
audioElement.muted = false; audioElement.muted = false;
audioElement.pause();
audioElement.currentTime = 0; // 检查是否可以播放,避免中断
if (!audioElement.paused) {
audioElement.currentTime = 0;
audioElement.pause();
};
seconds = 10;
voice.start();
startRec.style.display = 'none'; startRec.style.display = 'none';
endRec.style.display = 'none'; endRec.style.display = 'none';
@ -507,15 +554,21 @@
statusTxt.value = ''; statusTxt.value = '';
stopRec.textContent = '暂停'; stopRec.textContent = '暂停';
voice.stop();
// 音频 // 音频
audioElement.pause(); // 检查是否可以播放,避免中断
audioElement.currentTime = 0; if (!audioElement.paused) {
// 视频 audioElement.currentTime = 0;
audioElement.pause();
};
// 视频
replayVideoSegment(0, 60); replayVideoSegment(0, 60);
isCallbackExecuted = false; isCallbackExecuted = false;
seconds = 10;
voice.stop();
console.log('关闭识别');
startRec.style.display = 'block'; startRec.style.display = 'block';
endRec.style.display = 'none'; endRec.style.display = 'none';
@ -527,7 +580,7 @@
function showModal() { function showModal() {
modal.style.display = 'block'; modal.style.display = 'block';
dialog.style.display = 'block'; dialog.style.display = 'block';
} }
// 隐藏弹窗和遮罩 // 隐藏弹窗和遮罩
function hideModal() { function hideModal() {
@ -602,6 +655,8 @@
const blob = new Blob([content_bytes], { type: 'audio/mp3' }); const blob = new Blob([content_bytes], { type: 'audio/mp3' });
const blobUrl = URL.createObjectURL(blob); const blobUrl = URL.createObjectURL(blob);
statusTxt.value = '正在说话';
// 字幕文字 // 字幕文字
voiceTxt.innerText = str; voiceTxt.innerText = str;
marquee("marquee", "voice-txt"); marquee("marquee", "voice-txt");
@ -621,11 +676,14 @@
// 停止倒计时 // 停止倒计时
startRec.style.display = 'block'; startRec.style.display = 'block';
endRec.style.display = 'none'; endRec.style.display = 'none';
stopRec.style.display = 'none';
statusTxt.value = ''; statusTxt.value = '';
voiceTxt.innerText = ''; voiceTxt.innerText = '';
voice.stop();
replayVideoSegment(0, 60); replayVideoSegment(0, 60);
hideModal() hideModal()
// 播放结束重新开始监听
startShibie();
}); });
Subtitles = ""; Subtitles = "";
@ -724,7 +782,7 @@
// 如果没有找到匹配的数据项则返回null或错误信息这里选择返回null // 如果没有找到匹配的数据项则返回null或错误信息这里选择返回null
return null; return null;
} }
}; }
</script> </script>

View File

@ -146,6 +146,10 @@
<!-- 讯飞语音识别 --> <!-- 讯飞语音识别 -->
<script> <script>
window.onload = function () { window.onload = function () {
reset();
};
function reset() {
var videoElement = document.getElementById('myVideo'); var videoElement = document.getElementById('myVideo');
var startTime = 5; // 开始时间(以秒为单位) var startTime = 5; // 开始时间(以秒为单位)
var endTime = 10; // 结束时间(以秒为单位) var endTime = 10; // 结束时间(以秒为单位)
@ -154,7 +158,9 @@
// 指定段落 // 指定段落
function playVideoSegment(startTime, endTime) { function playVideoSegment(startTime, endTime) {
videoElement.currentTime = startTime; videoElement.currentTime = startTime;
videoElement.play(); setTimeout(() => {
videoElement.play();
}, 50);
// 添加timeupdate事件监听器 // 添加timeupdate事件监听器
timeUpdateListener = function() { timeUpdateListener = function() {
@ -182,7 +188,7 @@
timeUpdateListener = null; timeUpdateListener = null;
} }
} }
// 当前AI视频循环 // 当前AI视频循环
replayVideoSegment(0, 60); replayVideoSegment(0, 60);
@ -190,7 +196,7 @@
var audioElement = document.getElementById('myAudio'); var audioElement = document.getElementById('myAudio');
var isPlaying = false; // 是否播放 var isPlaying = false; // 是否播放
audioElement.muted = true; // 先静音 audioElement.muted = true; // 先静音
// 获取页面元素 // 获取页面元素
var element = document.getElementById("elementId"); var element = document.getElementById("elementId");
@ -205,7 +211,7 @@
endRec.style.display = "none"; endRec.style.display = "none";
stopRec.style.display = "none"; stopRec.style.display = "none";
var token = null; var token = null;
let times = null; let times = null;
@ -241,7 +247,7 @@
for (let i = 0; i < exampleData.length; i++) { for (let i = 0; i < exampleData.length; i++) {
exampleData[i].name = demoData[exampleData[i].type] exampleData[i].name = demoData[exampleData[i].type]
}; };
// 过滤掉非对象类型的值 // 过滤掉非对象类型的值
const filteredData = Object.entries(exampleData).filter(([key, value]) => typeof value === 'object'); const filteredData = Object.entries(exampleData).filter(([key, value]) => typeof value === 'object');
@ -254,218 +260,224 @@
/* /*
* 实例化迅飞语音听写流式版WebAPI * 实例化迅飞语音听写流式版WebAPI
*/ */
var seconds = 10;
let seconds = 10; var gaptime = null;
const voice = new Voice({ const voice = new Voice({
// 服务接口认证信息 // 服务接口认证信息
appId: '5f4ffdeb', appId: '5f4ffdeb',
apiSecret: 'OGIwM2RlMjBkOTI5Mzk5YTJlMzUwODI5', apiSecret: 'OGIwM2RlMjBkOTI5Mzk5YTJlMzUwODI5',
apiKey: '0b17a761b6b7174b789f639119d7e29a', apiKey: '0b17a761b6b7174b789f639119d7e29a',
onWillStatusChange: function (oldStatus, newStatus) {}, onWillStatusChange: function (oldStatus, newStatus) {
console.log(oldStatus, newStatus, '交互逻辑')
},
onTextChange: function (text) { onTextChange: function (text) {
// 监听识别结果的变化 // 监听识别结果的变化
voiceTxt.innerText = text; voiceTxt.innerText = text;
marquee("marquee", "voice-txt"); marquee("marquee", "voice-txt");
let timer = setInterval(() => { // 如果已有定时器在运行,则清除它
seconds--; if (gaptime) {
clearInterval(gaptime);
if (seconds <= 0) { };
clearInterval(timer); // 重置倒计时
seconds = 10;
console.log(text)
gaptime = setInterval(() => {
console.log(seconds, '倒计时')
seconds--;
if (voiceTxt.innerText) {
console.log('有 text 参数'); // 如果有 text 参数,打印 1
clearInterval(gaptime);
gaptime = null;
// 3秒钟内没有说话就自动关闭
if (text) { if (text) {
console.log(1); // 如果有 text 参数,打印 1 statusTxt.value = '正在听…';
} else { if (!isCallbackExecuted) {
console.log("没有传入 text 参数"); // 如果没有 text 参数,执行其他逻辑 clearTimeout(times);
} times = setTimeout(() => {
} this.stop();
}, 1000);
// 3秒钟内没有说话就自动关闭
if (text) {
statusTxt.value = '正在听…';
if (!isCallbackExecuted) {
clearTimeout(times);
times = setTimeout(() => {
this.stop();
statusTxt.value = '正在说话';
const params = { msg: text };
// 判断关键字是否存在
const result = parseHealthQuery(params.msg);
isCallbackExecuted = true;
if (result) {
DetailDay(result.dataKey, result.date).then(res => {
let TargetData = res.data.data;
if (result.dataKey == 'ECGData') { const params = { msg: text };
TargetData.map(item => {
delete item.data_msg.wavefrom;
delete item.data_msg.list;
})
}
if (result.dataKey == 'bloodLiquid') {
TargetData.map(item => {
item.data_msg.cholesterol = item.data_msg.cholesterol/100;
item.data_msg.highDensity = item.data_msg.highDensity/100;
item.data_msg.triacylglycerol = item.data_msg.triacylglycerol/100;
item.data_msg.uricAcidVal = item.data_msg.uricAcidVal/10000;
item.data_msg.lowDensity = item.data_msg.lowDensity/100;
})
}
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近测量的${result.dataKey}数据为${JSON.stringify(TargetData)}, #提示data_msg为值hour_minute为检测时间。#提示:“[]”表示数据为空,请在小程序上传数据。#限制:回复不要带英文,要都转化成汉语。#限制回复内容控制在150字。#限制:忽略“压力指数、疲劳指数、心肌炎风险、冠心病风险和动脉硬化”等数据。` // 判断关键字是否存在
const result = parseHealthQuery(params.msg);
console.log(Question, '问题=========================问题');
/*
* 调用接口 传递关键信息 文字转语音
*/
const xhr = new XMLHttpRequest();
const url = 'https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation';
const apiKey = 'sk-cbb9b5ff44374fa2a8a258160ebb292d';
// 打开请求,设置为异步
xhr.open('POST', url, true);
// 设置请求头
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.setRequestHeader('Authorization', 'Bearer ' + apiKey);
xhr.setRequestHeader('X-DashScope-SSE', 'enable');
// 处理流式数据的接收(使用 progress 事件)
xhr.onprogress = function () {
const data = xhr.responseText;
// SSE 数据解析处理
const lines = data.split('\n');
lines.forEach(line => {
if (line.startsWith('data:')) {
const jsonStr = line.substring(5); // 去掉 'data:' 前缀
const parsedData = JSON.parse(jsonStr);
// 解析 content 内容
const content = parsedData.output.choices[0].message.content;
if (content) {
// 检查内容是否已经存在
if (!Subtitles.includes(content)) {
Subtitles += content;
}
};
}
});
};
// 检查请求完成
xhr.onload = function () {
if (xhr.status === 200) {
statusTxt.value = '正在说话';
RequestMicrosoft();
}
};
// 错误处理
xhr.onerror = function () {
console.error('An error occurred during the transaction', xhr.statusText);
};
/*
* 关键字转换
*/
const requestBody = {
model: 'qwen-turbo',
input: {
messages: [
{"role": "system", "content": Question},
{"role": "user", "content": `请问我${params.msg}正常吗`}
]
},
parameters: {
result_format: 'message',
incremental_output: true
}
};
xhr.send(JSON.stringify(requestBody));
isCallbackExecuted = true; isCallbackExecuted = true;
return;
}) if (result) {
} else { DetailDay(result.dataKey, result.date).then(res => {
const xhr = new XMLHttpRequest(); let TargetData = res.data.data;
const url = 'https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation';
const apiKey = 'sk-cbb9b5ff44374fa2a8a258160ebb292d'; if (result.dataKey == 'ECGData') {
TargetData.map(item => {
// 打开请求,设置为异步 delete item.data_msg.wavefrom;
xhr.open('POST', url, true); delete item.data_msg.list;
})
// 设置请求头 }
xhr.setRequestHeader('Content-Type', 'application/json'); if (result.dataKey == 'bloodLiquid') {
xhr.setRequestHeader('Authorization', 'Bearer ' + apiKey); TargetData.map(item => {
xhr.setRequestHeader('X-DashScope-SSE', 'enable'); item.data_msg.cholesterol = item.data_msg.cholesterol/100;
item.data_msg.highDensity = item.data_msg.highDensity/100;
// 处理流式数据的接收(使用 progress 事件) item.data_msg.triacylglycerol = item.data_msg.triacylglycerol/100;
xhr.onprogress = function () { item.data_msg.uricAcidVal = item.data_msg.uricAcidVal/10000;
const data = xhr.responseText; item.data_msg.lowDensity = item.data_msg.lowDensity/100;
})
// SSE 数据解析处理 }
const lines = data.split('\n');
lines.forEach(line => { Question = `请模仿全科医生的口吻与我: ${user}对话,我最近测量的${result.dataKey}数据为${JSON.stringify(TargetData)}, #提示data_msg为值hour_minute为检测时间。#提示:“[]”表示数据为空,请在小程序上传数据。#限制:回复不要带英文,要都转化成汉语。#限制回复内容控制在150字。#限制:忽略“压力指数、疲劳指数、心肌炎风险、冠心病风险和动脉硬化”等数据。`
if (line.startsWith('data:')) {
const jsonStr = line.substring(5); // 去掉 'data:' 前缀 console.log(Question, '问题=========================问题');
const parsedData = JSON.parse(jsonStr);
// 解析 content 内容 /*
const content = parsedData.output.choices[0].message.content; * 调用接口 传递关键信息 文字转语音
if (content) { */
// 检查内容是否已经存在 const xhr = new XMLHttpRequest();
if (!Subtitles.includes(content)) { const url = 'https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation';
Subtitles += content; const apiKey = 'sk-cbb9b5ff44374fa2a8a258160ebb292d';
// 打开请求,设置为异步
xhr.open('POST', url, true);
// 设置请求头
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.setRequestHeader('Authorization', 'Bearer ' + apiKey);
xhr.setRequestHeader('X-DashScope-SSE', 'enable');
// 处理流式数据的接收(使用 progress 事件)
xhr.onprogress = function () {
const data = xhr.responseText;
// SSE 数据解析处理
const lines = data.split('\n');
lines.forEach(line => {
if (line.startsWith('data:')) {
const jsonStr = line.substring(5); // 去掉 'data:' 前缀
const parsedData = JSON.parse(jsonStr);
// 解析 content 内容
const content = parsedData.output.choices[0].message.content;
if (content) {
// 检查内容是否已经存在
if (!Subtitles.includes(content)) {
Subtitles += content;
}
};
}
});
};
// 检查请求完成
xhr.onload = function () {
if (xhr.status === 200) {
statusTxt.value = '正在说话';
RequestMicrosoft();
} }
}; };
}
}); // 错误处理
}; xhr.onerror = function () {
console.error('An error occurred during the transaction', xhr.statusText);
// 检查请求完成 };
xhr.onload = function () {
if (xhr.status === 200) { /*
statusTxt.value = '正在说话'; * 关键字转换
RequestMicrosoft(); */
const requestBody = {
model: 'qwen-turbo',
input: {
messages: [
{"role": "system", "content": Question},
{"role": "user", "content": `请问我${params.msg}正常吗`}
]
},
parameters: {
result_format: 'message',
incremental_output: true
}
};
xhr.send(JSON.stringify(requestBody));
isCallbackExecuted = true;
return;
})
} else {
const xhr = new XMLHttpRequest();
const url = 'https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation';
const apiKey = 'sk-cbb9b5ff44374fa2a8a258160ebb292d';
// 打开请求,设置为异步
xhr.open('POST', url, true);
// 设置请求头
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.setRequestHeader('Authorization', 'Bearer ' + apiKey);
xhr.setRequestHeader('X-DashScope-SSE', 'enable');
// 处理流式数据的接收(使用 progress 事件)
xhr.onprogress = function () {
const data = xhr.responseText;
// SSE 数据解析处理
const lines = data.split('\n');
lines.forEach(line => {
if (line.startsWith('data:')) {
const jsonStr = line.substring(5); // 去掉 'data:' 前缀
const parsedData = JSON.parse(jsonStr);
// 解析 content 内容
const content = parsedData.output.choices[0].message.content;
if (content) {
// 检查内容是否已经存在
if (!Subtitles.includes(content)) {
Subtitles += content;
}
};
}
});
};
// 检查请求完成
xhr.onload = function () {
if (xhr.status === 200) {
statusTxt.value = '正在说话';
RequestMicrosoft();
}
};
// 错误处理
xhr.onerror = function () {
console.error('An error occurred during the transaction', xhr.statusText);
};
// 发送请求
const requestBody = {
model: 'qwen-turbo',
input: {
messages: [
{"role": "system", "content": `请模仿全科医生的口吻与我对话`},
{"role": "user", "content": params.msg}
]
},
parameters: {
result_format: 'message',
incremental_output: true
}
};
xhr.send(JSON.stringify(requestBody));
isCallbackExecuted = true;
return;
} }
}; }, 3000);
// 错误处理
xhr.onerror = function () {
console.error('An error occurred during the transaction', xhr.statusText);
};
// 发送请求
const requestBody = {
model: 'qwen-turbo',
input: {
messages: [
{"role": "system", "content": `请模仿全科医生的口吻与我对话`},
{"role": "user", "content": params.msg}
]
},
parameters: {
result_format: 'message',
incremental_output: true
}
};
xhr.send(JSON.stringify(requestBody));
isCallbackExecuted = true;
return;
} }
}, 3000); }
} else if (seconds == 0){
reset();
} }
} }, 1000);
} }
}); });
@ -506,15 +518,24 @@
function startShibie() { function startShibie() {
/**开始识别**/ /**开始识别**/
voiceTxt.innerText = ''; voiceTxt.innerText = '';
stopRec.textContent = '暂停'; stopRec.textContent = '暂停';
voice.start();
isCallbackExecuted = false; isCallbackExecuted = false;
// 先静音即可处理解决(提前做交互) // 先静音即可处理解决(提前做交互)
audioElement.muted = false; audioElement.muted = false;
audioElement.pause();
audioElement.currentTime = 0; // 检查是否可以播放,避免中断
if (!audioElement.paused) {
audioElement.currentTime = 0;
audioElement.pause();
};
seconds = 10;
voice.start();
startRec.style.display = 'none'; startRec.style.display = 'none';
endRec.style.display = 'none'; endRec.style.display = 'none';
@ -523,20 +544,28 @@
} }
function closeShibie() { function closeShibie() {
reset();
/**关闭识别**/ /**关闭识别**/
voiceTxt.innerText = ''; voiceTxt.innerText = '';
statusTxt.value = ''; statusTxt.value = '';
stopRec.textContent = '暂停'; stopRec.textContent = '暂停';
voice.stop();
// 音频 // 音频
audioElement.pause(); // 检查是否可以播放,避免中断
audioElement.currentTime = 0; if (!audioElement.paused) {
// 视频 audioElement.currentTime = 0;
audioElement.pause();
};
// 视频
replayVideoSegment(0, 60); replayVideoSegment(0, 60);
isCallbackExecuted = false; isCallbackExecuted = false;
seconds = 10;
voice.stop();
console.log('关闭识别');
startRec.style.display = 'block'; startRec.style.display = 'block';
endRec.style.display = 'none'; endRec.style.display = 'none';
@ -548,7 +577,7 @@
function showModal() { function showModal() {
modal.style.display = 'block'; modal.style.display = 'block';
dialog.style.display = 'block'; dialog.style.display = 'block';
} }
// 隐藏弹窗和遮罩 // 隐藏弹窗和遮罩
function hideModal() { function hideModal() {
@ -647,9 +676,11 @@
stopRec.style.display = 'none'; stopRec.style.display = 'none';
statusTxt.value = ''; statusTxt.value = '';
voiceTxt.innerText = ''; voiceTxt.innerText = '';
voice.stop();
replayVideoSegment(0, 60); replayVideoSegment(0, 60);
hideModal() hideModal()
// 播放结束重新开始监听
startShibie();
}); });
Subtitles = ""; Subtitles = "";
@ -748,7 +779,7 @@
// 如果没有找到匹配的数据项则返回null或错误信息这里选择返回null // 如果没有找到匹配的数据项则返回null或错误信息这里选择返回null
return null; return null;
} }
}; }
</script> </script>