JLBA202505130001_关于吉林银行新建AI智能培训系统的需求_完善流式语音代码

This commit is contained in:
田岩
2026-02-11 13:38:59 +08:00
parent 589fa3e179
commit 517c9068e6
15 changed files with 149 additions and 201 deletions
@@ -0,0 +1,6 @@
// components/touch-btn/touch-btn.images.ts
// 统一导出所有需要的图片资源
export { default as cancelBtn } from '@/static/images/course/cancel.png';
export { default as cancelActiveBtn } from '@/static/images/course/cancel-active.png';
export { default as translateBtn } from '@/static/images/course/translate.png';
export { default as translateActiveBtn } from '@/static/images/course/translate-active.png';
+15
View File
@@ -0,0 +1,15 @@
import { get_base_url } from '@/api/request.js';
// const url = '/trapractice/voiceCallSocket/voiceCall'
// const url = '/traapp/voiceTransSocket/open';
const url = '/traapp/voiceAiModelSocket/open';
const _baseUrl = get_base_url(url).split('http').join('ws');
export const wsUrl = _baseUrl + url;
const windowInfo = uni.getWindowInfo();
// 安全区域信息
const safeArea = windowInfo.safeArea;
// 按钮高度
const btnHeight = (windowInfo.screenWidth / 750) * 234;
// 按钮的顶部边界
export const bottomAreaTopBoundary = safeArea.bottom - btnHeight;
// 屏幕横向分割线
export const horizontalSplitX = safeArea.right / 2;
@@ -0,0 +1 @@
export type StatusType = 'voice' | 'input' | 'text';
+60 -61
View File
@@ -89,27 +89,22 @@
</view>
</template>
<script setup>
import cancelBtn from '@/static/images/course/cancel.png';
import cancelActiveBtn from '@/static/images/course/cancel-active.png';
import translateBtn from '@/static/images/course/translate.png';
import translateActiveBtn from '@/static/images/course/translate-active.png';
<script setup lang="ts">
// 导出图片
import { cancelBtn, cancelActiveBtn, translateBtn, translateActiveBtn } from './touch-btn.images';
import { StatusType } from './touch-btn.types';
import { wsUrl, bottomAreaTopBoundary, horizontalSplitX } from './touch-btn';
import { ref, computed, onMounted, nextTick, watch, reactive } from 'vue';
import common from '@/common/common';
import { onHide } from '@dcloudio/uni-app';
import permission from '@/common/permission.js';
import { getPhoneEnvBool } from '@/common/common.js';
import { initRecord } from '@/composables/useExamSubject.js';
import { getToken } from '@/common/common';
import { getPhoneEnvBool, getToken } from '@/common/common.js';
import { startAudioRecord, stopAudioRecord } from '@/uni_modules/ty-recording';
import { get_base_url } from '@/api/request.js';
import { ProtocolCodec, MessageType, ControlCommand,ControlCode } from '@/pages/sparring/js/ProtocolCodec';
// const url = '/trapractice/voiceCallSocket/voiceCall'
// const url = '/traapp/voiceTransSocket/open';
const url = '/traapp/voiceAiModelSocket/open';
const _baseUrl = get_base_url(url).split('http').join('ws');
import { ProtocolCodec, MessageType, ControlCommand, ControlCode } from '@/pages/sparring/js/ProtocolCodec';
import permissionApi from '@/common/permission';
const emit = defineEmits(['submit']);
const ws = ref(null);
const status = ref<StatusType>('voice');
const props = defineProps({
isDisabled: {
default: false,
@@ -147,15 +142,11 @@
});
// 记录 按下移动位置
const touchPos = reactive({ x: 0, y: 0 });
const windowInfo = uni.getWindowInfo();
// 安全区域信息
const safeArea = windowInfo.safeArea;
console.log('safeArea', safeArea);
// 计算是否超出按下盒子位置01代表下方盒子,02代表左上03代表右上
const isOutStatus = computed(() => {
const btnHeight = (windowInfo.screenWidth / 750) * 234;
if (touchPos.y < safeArea.bottom - btnHeight) {
if (touchPos.x < safeArea.right / 2) return '02';
if (touchPos.y < bottomAreaTopBoundary) {
if (touchPos.x < horizontalSplitX) return '02';
else return '03';
} else {
return '01';
@@ -175,16 +166,20 @@
const popupRef = ref(null);
const inputText = ref('');
let startTime = 0;
const startTimer = ref(null); // 延迟启动的定时器ID
const startFlag = ref(1);
// 开启语音
const startRecord = async (obj) => {
try {
await permissionApi.judgeIosPermission('record');
} catch (e) {
console.error('麦克风权限申请失败:', e);
return;
}
const changedTouche = obj.touches[0];
touchPos.x = changedTouche.clientX;
touchPos.y = changedTouche.clientY;
const wsUrl = _baseUrl + url + '?summary=' + getToken();
ws.value = uni.connectSocket({
url: wsUrl,
url: wsUrl + '?summary=' + getToken(),
fail: () => {},
success: () => {}
});
@@ -192,21 +187,22 @@
console.log('ws已连接');
popupRef.value.open();
startAudioRecord({
onFrame:(pcmData) => {
// pcmData 是ByteArray类型的原始音频数据
console.log('采集到音频数据长度1:', pcmData.length);
onFrame: (pcmData) => {
ws.value.send({
data: ProtocolCodec.pack(MessageType.AUDIO_DATA, pcmData)
});
// 可在此处将PCM转Base64/编码为MP3等,或直接传输
},
onStop:(pcmData) => {
onStart: ({ startTime }) => {
console.log('开始', startTime);
},
onStop: () => {
console.log('关闭');
},
onError:(err) => {
console.log('err', err.errMsg);
console.log('err', err.errCode);
},
onError: ({ errCode, errMsg }) => {
if (errCode === 9010001) {
console.log(errMsg);
}
}
});
});
ws.value.onError((err) => {
@@ -216,17 +212,20 @@
console.log('onClose', err);
});
ws.value.onMessage((res) => {
const { msgType, body } = ProtocolCodec.unpack(res.data);
console.log('来消息了', msgType, body);
if (msgType === MessageType.TEXT_MESSAGE) {
tempText.value = '';
allText.value = allText.value + body;
} else if (msgType === MessageType.TIP_MESSAGE) {
tempText.value = body;
try {
const { msgType, body } = ProtocolCodec.unpack(res.data);
console.log('来消息了', msgType, body);
if (msgType === MessageType.TEXT_MESSAGE) {
tempText.value = '';
allText.value = allText.value + body;
} else if (msgType === MessageType.TIP_MESSAGE) {
tempText.value = body;
}
} catch (e) {
console.log('后端发来的信息有问题');
}
});
};
// 关掉遮罩层
const closePopup = () => {
nextTick(() => {
@@ -234,19 +233,21 @@
tempText.value = '';
popupRef.value.close();
});
ws.value.close({
code: 1000,
reason: '挂断',
success: () => {
console.log('挂断success');
},
fail: () => {
console.log('挂断fail');
},
complete: () => {
console.log('挂断complete');
}
});
ws.value &&
ws.value.close({
code: 1000,
reason: '挂断',
success: () => {
console.log('挂断success');
},
fail: () => {
console.log('挂断fail');
},
complete: () => {
console.log('挂断complete');
}
});
};
// 松开按钮
const loosenButton = () => {
@@ -255,7 +256,7 @@
// 03转文字
console.log('已发送', '03转文字');
ws.value.send({
data: ProtocolCodec.pack(MessageType.CONTROL_CMD, {type:ControlCode.FRNOT_TO_SERVER_OVER})
data: ProtocolCodec.pack(MessageType.CONTROL_CMD, { type: ControlCode.FRNOT_TO_SERVER_OVER })
});
} else {
closePopup();
@@ -273,10 +274,8 @@
} else if (isOutStatus.value === '03') {
// 03转文字
}
stopAudioRecord();
};
onMounted(async () => {});