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