zhuf vor 1 Jahr
Ursprung
Commit
7a9ee90c6e

+ 1 - 1
src/pages/caiji/rx/read.vue

@@ -7,7 +7,7 @@ function onClickLeft() {
   router.back()
 }
 
-const leftTime = ref(15)
+const leftTime = ref(1)
 const timer = ref()
 
 onMounted(() => {

+ 1 - 0
src/pages/caiji/sy/name.vue

@@ -24,6 +24,7 @@ function onSubmit(values: any) {
     }
   }).then(res => {
     const info = res.data.one_info
+    console.log('info : ', info)
     // {
     //   "axa_id": "58",
     //   "axa_sycj_json_v2": "",

+ 151 - 63
src/pages/caiji/sy/record/[id].vue

@@ -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()">

+ 17 - 2
src/pages/home/caiji/index.vue

@@ -1,15 +1,31 @@
 <script setup lang='ts'>
 import rx from '~/assets/caiji/rx.webp'
 import sy from '~/assets/caiji/sy.webp'
+import request from '~/request'
 
 const router = useRouter()
 
+function routerToSycj() {
+  request({
+    url: '/aimooc/xnszr_audio/get_demo_text',
+  }).then((res: any) => {
+    console.log('完整信息 : ', res.data)
+    const axa_sycj_zdysyid_v2 = res.data.pre_data?.axa_sycj_zdysyid_v2
+    console.log('axa_sycj_zdysyid_v2 : ', axa_sycj_zdysyid_v2)
+    if (axa_sycj_zdysyid_v2) {
+      router.push({ name: "caiji-sy-record-id", params: { id: axa_sycj_zdysyid_v2 } })
+    } else {
+      router.push({ name: 'caiji-sy-read' })
+    }
+  })
+}
+
 </script>
 
 <template>
   <van-nav-bar title="AI慕课采集"></van-nav-bar>
   <div class="flex flex-col items-center space-y-6 px-24px py-18px">
-    <div class="relative" @click="router.push({ name: 'caiji-sy-read' })">
+    <div class="relative" @click="routerToSycj">
       <img :src="sy" alt="">
       <div class="absolute inset-0 flex flex-col items-center text-white font-bold mt-40px space-y-20px">
         <div>声音采集</div>
@@ -27,7 +43,6 @@ const router = useRouter()
       <li>录音时位置确定后尽量不要动,就是说嘴和话筒的距离确定后不要随便乱动,有的人好动,这个避免不了,但是幅度不要太大,要不然会影响音色和动态。</li>
       <li>拍摄时现场严禁大声喧哗,嬉笑打闹;人脸正面免冠照片,需露出眉毛、眼睛及耳朵,亮度均衡。</li>
     </ul>
-
   </div>
 </template>