|
@@ -6,12 +6,20 @@ import { showFailToast, showSuccessToast, showDialog } from 'vant';
|
|
|
const props = defineProps<{
|
|
|
id: string
|
|
|
}>()
|
|
|
-console.log('props : ', props.id)
|
|
|
+console.log('任务ID : ', props.id)
|
|
|
|
|
|
const router = useRouter()
|
|
|
|
|
|
function onClickLeft() {
|
|
|
- router.back()
|
|
|
+ showDialog({
|
|
|
+ title: '提醒',
|
|
|
+ message: '没有完成全部的流程,确定退出吗?',
|
|
|
+ showCancelButton: true,
|
|
|
+ confirmButtonText: '确定',
|
|
|
+ cancelButtonText: '取消',
|
|
|
+ }).then(() => {
|
|
|
+ router.back()
|
|
|
+ })
|
|
|
}
|
|
|
|
|
|
const loading = ref(true)
|
|
@@ -27,22 +35,82 @@ const current = ref(0)
|
|
|
const list = ref<any[]>([])
|
|
|
|
|
|
request({
|
|
|
- url: '/aimooc/xnszr_audio/get_demo_text'
|
|
|
+ url: '/aimooc/xnszr_audio/get_demo_text',
|
|
|
+ data: {
|
|
|
+ voiceId: props.id,
|
|
|
+ }
|
|
|
}).then(res => {
|
|
|
+ console.log('完整信息 : ', res.data)
|
|
|
|
|
|
- list.value = Object.values(res.data).sort((a: any, b: any) => a.audioId - b.audioId)
|
|
|
- console.log('list.value : ', list.value)
|
|
|
+ list.value = Object.values(res.data.data).sort((a: any, b: any) => a.audioId - b.audioId)
|
|
|
+ console.log('文本列表 : ', list.value)
|
|
|
+ let _current = res.data.pre_data?.axa_sycj_scbz_v2 ? parseInt(res.data.pre_data?.axa_sycj_scbz_v2) : 0
|
|
|
+ console.log('已读到 : ', current.value)
|
|
|
+ if (_current === list.value.length) {
|
|
|
+ // showSuccessToast('已完成全部录音')
|
|
|
+ showDialog({
|
|
|
+ title: '提醒',
|
|
|
+ message: '已完成全部录音,直接提交',
|
|
|
+ showCancelButton: true,
|
|
|
+ confirmButtonText: '确定',
|
|
|
+ }).then(() => {
|
|
|
+ handleSubmitTask()
|
|
|
+ }).catch(() => {
|
|
|
+ router.back()
|
|
|
+ })
|
|
|
+ }
|
|
|
+ current.value = _current
|
|
|
loading.value = false
|
|
|
})
|
|
|
|
|
|
-function playAudio() {
|
|
|
- const audio = new Audio(list.value[current.value].demoAudio);
|
|
|
+let audio: HTMLAudioElement = new Audio();
|
|
|
+audio.addEventListener('ended', () => {
|
|
|
+ console.log('播放结束')
|
|
|
+});
|
|
|
+audio.addEventListener('paused', () => {
|
|
|
+ console.log('播放手动停止')
|
|
|
+});
|
|
|
+
|
|
|
+function breforeAudioPlay() {
|
|
|
+ if (isRecording.value) {
|
|
|
+ showFailToast('正在录制中,无法播放');
|
|
|
+ throw Error('正在录制中,无法播放')
|
|
|
+ }
|
|
|
+ if (audio) {
|
|
|
+ console.log('停止正在进行的播放')
|
|
|
+ audio.pause();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+function playDemoAudio() {
|
|
|
+ breforeAudioPlay()
|
|
|
+ console.log('开始播放demo录音')
|
|
|
+ audio.src = list.value[current.value].demoAudio;
|
|
|
+ audio.load();
|
|
|
audio.play().then(() => {
|
|
|
- console.log('audio play success')
|
|
|
+ console.log('播放成功')
|
|
|
}).catch((error) => {
|
|
|
- console.error('Failed to play audio: ' + error);
|
|
|
+ console.error('播放失败: ' + error);
|
|
|
showFailToast('播放失败');
|
|
|
- });
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+const userAudio = ref<string | undefined>()
|
|
|
+function playUserAudio() {
|
|
|
+ breforeAudioPlay()
|
|
|
+ if (!userAudio.value) {
|
|
|
+ showFailToast('录音后才能预览');
|
|
|
+ return
|
|
|
+ }
|
|
|
+ console.log('开始播放用户录音')
|
|
|
+ audio.src = userAudio.value;
|
|
|
+ audio.load();
|
|
|
+ audio.play().then(() => {
|
|
|
+ console.log('播放成功')
|
|
|
+ }).catch((error) => {
|
|
|
+ console.error('播放失败: ' + error);
|
|
|
+ showFailToast('播放失败');
|
|
|
+ })
|
|
|
}
|
|
|
|
|
|
|
|
@@ -52,13 +120,21 @@ let isRecording = ref(false)
|
|
|
|
|
|
let audioChunks: any[] = []
|
|
|
|
|
|
+// if (MediaRecorder.isTypeSupported('audio/wav')) {
|
|
|
+// console.log('Opus codec in a wav container is supported');
|
|
|
+// } else {
|
|
|
+// console.log('Opus codec in a wav container is not supported');
|
|
|
+// }
|
|
|
+
|
|
|
function startAudioRecord() {
|
|
|
console.log('点击 开始录音')
|
|
|
+ breforeAudioPlay()
|
|
|
+ audioChunks = []
|
|
|
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
|
|
|
console.log('浏览器支持相关 API')
|
|
|
navigator.mediaDevices.getUserMedia({ audio: true })
|
|
|
.then((stream) => {
|
|
|
- console.log('stream')
|
|
|
+ console.log('stream 生成成功')
|
|
|
isRecording.value = true
|
|
|
|
|
|
mediaRecorder = new MediaRecorder(stream);
|
|
@@ -86,23 +162,59 @@ function startAudioRecord() {
|
|
|
}
|
|
|
|
|
|
function stopAudioRecord() {
|
|
|
- if (!mediaRecorder) {
|
|
|
+ if (!isRecording.value) {
|
|
|
console.log('停止录音 录音机未启动时触发')
|
|
|
return
|
|
|
}
|
|
|
console.log('停止录音')
|
|
|
- mediaRecorder.stop();
|
|
|
+ mediaRecorder?.stop();
|
|
|
mediaRecorder = null
|
|
|
+
|
|
|
+ const blob = new Blob(audioChunks, { type: 'video/webm' });
|
|
|
+ userAudio.value = window.URL.createObjectURL(blob);
|
|
|
+
|
|
|
isRecording.value = false
|
|
|
}
|
|
|
|
|
|
onUnmounted(() => {
|
|
|
- if (mediaRecorder) {
|
|
|
- mediaRecorder.stop();
|
|
|
- mediaRecorder = null
|
|
|
+ if (isRecording.value) {
|
|
|
+ mediaRecorder!.stop();
|
|
|
}
|
|
|
+ mediaRecorder = null
|
|
|
})
|
|
|
|
|
|
+function handleSubmitTask() {
|
|
|
+ request({
|
|
|
+ url: '/aimooc/xnszr_audio/submit_job',
|
|
|
+ data: {
|
|
|
+ voiceId: props.id,
|
|
|
+ }
|
|
|
+ }).then((res: any) => {
|
|
|
+ if (res?.code === '1') {
|
|
|
+ console.log('提交成功')
|
|
|
+ showDialog({
|
|
|
+ title: '成功提醒',
|
|
|
+ message: '声音采集成功',
|
|
|
+ showCancelButton: false,
|
|
|
+ confirmButtonText: '确定',
|
|
|
+ }).then(() => {
|
|
|
+ router.back()
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ console.info(res?.msg)
|
|
|
+ // showFailToast(res?.msg)
|
|
|
+ showDialog({
|
|
|
+ title: '失败提醒',
|
|
|
+ message: res?.msg,
|
|
|
+ showCancelButton: false,
|
|
|
+ confirmButtonText: '重新提交',
|
|
|
+ }).then(() => {
|
|
|
+ handleSubmitTask()
|
|
|
+ })
|
|
|
+ }
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
function submitAudio() {
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
|
@@ -113,16 +225,17 @@ function submitAudio() {
|
|
|
return reject()
|
|
|
}
|
|
|
setTimeout(() => {
|
|
|
+ // 其实浏览器不支持wav 交给后端转换
|
|
|
const audioBlob = new Blob(audioChunks, { type: 'audio/wav' });
|
|
|
- console.log('audioBlob : ', audioBlob)
|
|
|
- // const filedata = new File([audioBlob], 'audio.wav', { type: 'audio/wav' });
|
|
|
+ const filedata = new File([audioBlob], 'audio.wav', { type: 'audio/wav' });
|
|
|
mediaRecorder = null
|
|
|
-
|
|
|
+ audioChunks = []
|
|
|
request({
|
|
|
- url: '/upload/main/file',
|
|
|
+ url: '/aimooc/xnszr_audio/detect_audio',
|
|
|
data: {
|
|
|
- filedata: audioBlob,
|
|
|
- aliyun_oss: 1
|
|
|
+ voiceId: props.id,
|
|
|
+ audioRecordId: list.value[current.value].audioId,
|
|
|
+ file: filedata,
|
|
|
},
|
|
|
transformRequest: [
|
|
|
function (data: any) {
|
|
@@ -132,52 +245,26 @@ function submitAudio() {
|
|
|
},
|
|
|
],
|
|
|
})
|
|
|
- // Promise.resolve({})
|
|
|
- .then((res) => {
|
|
|
- if (res.code !== '1') {
|
|
|
- return reject()
|
|
|
- }
|
|
|
- // return res
|
|
|
- const url = res.data.oss_url
|
|
|
- // console.log('https://aimoocapi.bozedu.net/' + url)
|
|
|
- console.log(url)
|
|
|
- return request({
|
|
|
- url: '/aimooc/xnszr_audio/detect_audio',
|
|
|
- data: {
|
|
|
- voiceId: props.id,
|
|
|
- audioRecordId: list.value[current.value].audioId,
|
|
|
- recordUrl: url,
|
|
|
- }
|
|
|
- })
|
|
|
- }).then((res: any) => {
|
|
|
- if (current.value === list.value.length) {
|
|
|
- request({
|
|
|
- url: '/aimooc/xnszr_audio/submit_job',
|
|
|
- data: {
|
|
|
- voiceId: props.id,
|
|
|
- }
|
|
|
- })
|
|
|
- showDialog({
|
|
|
- title: '成功提醒',
|
|
|
- message: '采集成功',
|
|
|
- showCancelButton: false,
|
|
|
- confirmButtonText: '确定',
|
|
|
- }).then(() => {
|
|
|
- router.back()
|
|
|
- })
|
|
|
- } else {
|
|
|
- if (res?.code === '1') {
|
|
|
- current.value++
|
|
|
- showSuccessToast('声音采集识别成功')
|
|
|
+ .then((res: any) => {
|
|
|
+ // console.log(res.data?.url?.url)
|
|
|
+ if (res?.code === '1') {
|
|
|
+ console.log('current : ', current.value)
|
|
|
+ if (current.value === list.value.length - 1) {
|
|
|
+ handleSubmitTask()
|
|
|
} else {
|
|
|
- showFailToast(res?.msg)
|
|
|
+ showSuccessToast('声音采集识别成功')
|
|
|
+ userAudio.value = undefined
|
|
|
+ current.value++
|
|
|
}
|
|
|
+ } else {
|
|
|
+ console.info(res?.msg)
|
|
|
+ showFailToast(res?.msg)
|
|
|
}
|
|
|
resolve(res?.data)
|
|
|
}).catch(err => {
|
|
|
reject(err)
|
|
|
})
|
|
|
- }, 500);
|
|
|
+ }, 0);
|
|
|
})
|
|
|
|
|
|
}
|
|
@@ -191,14 +278,15 @@ function submitAudio() {
|
|
|
<template v-else>
|
|
|
<div class="w-full flex flex-col items-center mb-12">
|
|
|
<div class="text-xl mt-26px"><span class="text-hex-DB664D">{{ current + 1 }}</span> / {{ list.length }}</div>
|
|
|
- <p class="text-base indent mt-28px">
|
|
|
+ <p class="text-base indent mt-28px mb-32px">
|
|
|
{{ list[current]?.text }}
|
|
|
</p>
|
|
|
+ <van-button size="small" @click="playDemoAudio">试听demo</van-button>
|
|
|
</div>
|
|
|
|
|
|
|
|
|
<div class="flex w-full justify-around text-hex-242731">
|
|
|
- <div class="p-4 rounded-8 bg-white " @click="playAudio">
|
|
|
+ <div :class="['p-4 rounded-8 bg-white', userAudio ? '' : 'opacity-20']" @click="playUserAudio">
|
|
|
<van-icon name="volume" size="28" />
|
|
|
</div>
|
|
|
<div class="p-4 rounded-8 bg-white " @click="() => isRecording ? stopAudioRecord() : startAudioRecord()">
|