在家开发了录音按钮功能
This commit is contained in:
+2
-3
@@ -2,11 +2,10 @@
|
||||
ENV = 'development'
|
||||
# 'development'
|
||||
|
||||
#VITE_APP_BASE_API_Url = 'https://aits.jlbank.com.cn:7001'
|
||||
VITE_APP_BASE_API_Url = 'https://aits.jlbank.com.cn:7001'
|
||||
|
||||
|
||||
VITE_APP_BASE_API_Url = 'https://aitstest.jlbank.com.cn:7002'
|
||||
|
||||
#VITE_APP_BASE_API_Url = 'https://aitstest.jlbank.com.cn:7002'
|
||||
|
||||
# DEV
|
||||
#VITE_APP_BASE_API_Url = 'http://25.18.122.65:7001'
|
||||
|
||||
@@ -243,6 +243,16 @@
|
||||
.gif-box {
|
||||
display: none;
|
||||
}
|
||||
.textarea {
|
||||
visibility: visible;
|
||||
pointer-events: none;
|
||||
user-select: none;
|
||||
}
|
||||
}
|
||||
&.is-translate.success .textarea {
|
||||
visibility: visible;
|
||||
pointer-events: auto;
|
||||
user-select: auto;
|
||||
}
|
||||
&::after {
|
||||
content: '';
|
||||
@@ -262,7 +272,11 @@
|
||||
&.success::after {
|
||||
left: 78% !important;
|
||||
}
|
||||
|
||||
|
||||
// 输入框默认并不可见
|
||||
.textarea {
|
||||
visibility: hidden;
|
||||
}
|
||||
&.failed,&.networkError {
|
||||
width: 506rpx;
|
||||
height: 114rpx;
|
||||
@@ -275,17 +289,14 @@
|
||||
.error-tip-div {
|
||||
display: flex !important;
|
||||
visibility: visible; // 激活后可见
|
||||
// animation: fadeIn 0.4s ease-out 0.1s forwards;
|
||||
}
|
||||
.textarea {
|
||||
visibility: hidden; // 初始不可见且不占交互位置
|
||||
}
|
||||
}
|
||||
&.init{
|
||||
.textarea {
|
||||
visibility: hidden; // 初始不可见且不占交互位置
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
.talk-dialog {
|
||||
width: 100%;
|
||||
|
||||
@@ -8,8 +8,8 @@ const IsAndEnv = getPhoneEnvBool('AND')
|
||||
// const url = '/traapp/asrAiModelSocket/open';
|
||||
const url = '/traapp/asrAiModelSocket/open';
|
||||
const _baseUrl = get_base_url(url).split('http').join('ws');
|
||||
export const wsUrl = _baseUrl + url + '?summary=' + getToken();
|
||||
// export const wsUrl = 'wss://ty_chat_test.home.tymas.cn:8000/ws/audio';
|
||||
// export const wsUrl = _baseUrl + url + '?summary=' + getToken();
|
||||
export const wsUrl = 'ws://10.10.10.8:8000/ws/asr';
|
||||
const windowInfo = uni.getWindowInfo();
|
||||
// 安全区域信息
|
||||
const safeArea = windowInfo.safeArea;
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
*/
|
||||
export type StatusType = 'default' | 'voice_recording' | 'text_input' | 'voice_to_text' | 'voice_send_ing' | 'send_over';
|
||||
|
||||
|
||||
/**
|
||||
* 语音转文字的子状态(仅当主状态为 voice_to_text 时生效)
|
||||
*/
|
||||
@@ -20,6 +21,7 @@ export type VoiceToTextSubStatus =
|
||||
| 'failed' // 转换失败(网络/识别错误等)
|
||||
| 'networkError'; // 转换失败(网络错误等)
|
||||
|
||||
export type WorkModeType = 'both' | 'text-only' | 'voice-only' ;
|
||||
|
||||
/** 错误码枚举 - 直接映射提示文本 */
|
||||
export enum ErrorCode {
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
ref="inputRef"
|
||||
v-model="inputText"
|
||||
:maxlength="props.maxlength"
|
||||
:adjustPosition="false"
|
||||
:adjustPosition="props.adjustPosition"
|
||||
placeholderStyle="color:#999999;font-size:26rpx"
|
||||
placeholder="请输入文字"
|
||||
:disabled="props.isDisabled"
|
||||
@@ -110,7 +110,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import * as TouchBtnImages from './touch-btn.images'; // 导出图片
|
||||
import { StatusType, VoiceToTextSubStatus, ErrorCode } from './touch-btn.types';
|
||||
import { StatusType, VoiceToTextSubStatus, ErrorCode,WorkModeType } from './touch-btn.types';
|
||||
import type { TouchBtnEmits } from './touch-btn.types';
|
||||
import { wsUrl, bottomAreaTopBoundary, horizontalSplitX, initWebSocket, showErrorTip, vibrateLight } from './touch-btn';
|
||||
import { ref, computed, onMounted, nextTick, watch, reactive } from 'vue';
|
||||
@@ -161,6 +161,10 @@
|
||||
type: Number,
|
||||
default: 1000
|
||||
},
|
||||
adjustPosition:{
|
||||
default: true,
|
||||
type: Boolean
|
||||
},
|
||||
answerMethod:{
|
||||
type: String,
|
||||
default: '01',
|
||||
@@ -170,7 +174,7 @@
|
||||
}
|
||||
}
|
||||
});
|
||||
const workMode = computed(() => {
|
||||
const workMode = computed<WorkModeType>(() => {
|
||||
const modeMap = {
|
||||
'01': 'both',
|
||||
'02': 'text-only',
|
||||
@@ -254,6 +258,7 @@
|
||||
voice_to_text_status.value = '';
|
||||
tempText.value = '';
|
||||
allText.value = '';
|
||||
console.log('都清空了');
|
||||
initWebSocket(wsUrl)
|
||||
.then((socketTask) => {
|
||||
ws.value = socketTask;
|
||||
@@ -267,7 +272,7 @@
|
||||
tempText.value = '';
|
||||
allText.value = allText.value + body;
|
||||
} else if (msgType === MessageType.TIP_MESSAGE) {
|
||||
tempText.value = body as string;
|
||||
tempText.value += body as string;
|
||||
} else if (msgType === MessageType.CONTROL_CMD) {
|
||||
// 返回结束消息
|
||||
const controlBody = body as ControlBody;
|
||||
@@ -305,7 +310,7 @@
|
||||
});
|
||||
})
|
||||
.catch(() => {
|
||||
// stopRecord('networkError');
|
||||
stopRecord('networkError');
|
||||
console.log('网络出现问题');
|
||||
});
|
||||
pressTimer.value = setTimeout(() => {
|
||||
@@ -321,6 +326,7 @@
|
||||
startAudioRecord({
|
||||
onFrame: (pcmData: any) => {
|
||||
if (wsStatus.value && ws.value) {
|
||||
console.log('pcmData', pcmData.length);
|
||||
ws.value.send({ data: ProtocolCodec.pack(MessageType.AUDIO_DATA, pcmData) });
|
||||
}
|
||||
},
|
||||
@@ -439,9 +445,14 @@
|
||||
};
|
||||
|
||||
// 切换键盘语音
|
||||
const changeBtn = () => {
|
||||
const changeBtn = (_isInputVisible = true) => {
|
||||
if (props.isDisabled) return;
|
||||
isInputVisible.value = !isInputVisible.value;
|
||||
// 只要不是仅录音,就可以切换到录音按钮
|
||||
if(workMode.value === 'text-only') {
|
||||
isInputVisible.value = false
|
||||
}
|
||||
// 否则为true
|
||||
isInputVisible.value = _isInputVisible;
|
||||
inputText.value = '';
|
||||
};
|
||||
// 按钮右侧图标(三个功能)
|
||||
@@ -454,8 +465,6 @@
|
||||
} else {
|
||||
isInputVisible.value = !isInputVisible.value;
|
||||
}
|
||||
|
||||
inputText.value = '';
|
||||
};
|
||||
// 禁用时点击给的提示
|
||||
const disabled_click = () => {
|
||||
@@ -471,7 +480,7 @@
|
||||
closePopup();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
setupKeyboardHeightListener((height: number) => {
|
||||
const _height = Math.max(height - 100, 0);
|
||||
pageBoxMarginBottom.value = `${_height}px`;
|
||||
|
||||
@@ -135,7 +135,7 @@
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
<TouchBtn
|
||||
<!-- <TouchBtn
|
||||
class="talk-btns"
|
||||
@uploadVoice="uploadRecordNow"
|
||||
@submitAnswer="submitAnswerNow"
|
||||
@@ -144,10 +144,10 @@
|
||||
:isLoading="!answerIsOver"
|
||||
:adjustPosition="true"
|
||||
:isDisabled="isHistory"
|
||||
/>
|
||||
<!-- <touch-btn @uploadVoice="uploadRecordNow" @submitAnswer="submitAnswerNow"
|
||||
/> -->
|
||||
<touch-btn @uploadVoice="uploadRecordNow" @submitAnswer="submitAnswerNow"
|
||||
@startRecord="startRecordCallback" :loadingText="sendLoadingText" :isLoading="!answerIsOver"
|
||||
:adjustPosition="true" :isDisabled="isHistory" /> -->
|
||||
:adjustPosition="true" :isDisabled="isHistory" />
|
||||
|
||||
<History ref="historyRef" @showDetail="showHistoryDetail"></History>
|
||||
<PreviewVue ref="previewRef" />
|
||||
@@ -167,7 +167,7 @@
|
||||
import { ref, unref, onMounted, watch, nextTick, computed, onActivated } from 'vue';
|
||||
import common from '@/common/common';
|
||||
import { setupKeyboardHeightListener } from '@/common/common';
|
||||
import TouchBtn from '@/pages/course/components/touchBtn.vue';
|
||||
// import TouchBtn from '@/pages/course/components/touchBtn.vue';
|
||||
import TalkingItem from './components/talking-item.vue';
|
||||
import PreviewVue from './components/preview.vue';
|
||||
import { useSocketStore } from '@/store/socket.js';
|
||||
|
||||
@@ -14,7 +14,7 @@ import AtomicBoolean from "java.util.concurrent.atomic.AtomicBoolean";
|
||||
const isRecording = new AtomicBoolean(false); // 原子布尔值,保证线程安全
|
||||
|
||||
// 1. 音频采集参数(极简配置,适配大部分设备)
|
||||
const sampleRate : Int = 48000; // 采样率
|
||||
const sampleRate : Int = 16000; // 采样率
|
||||
const channelConfig = AudioFormat.CHANNEL_IN_MONO; // 单声道
|
||||
const audioFormat = AudioFormat.ENCODING_PCM_16BIT; // 16位PCM
|
||||
const minBufferSize = AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioFormat);
|
||||
|
||||
Reference in New Issue
Block a user