|
|
|
@@ -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 () => {});
|
|
|
|
|