Explorar el Código

优化语音组件添加了mediaStream变量来存储媒体流引用,并结束和报错卸载是销毁资源

liyanbo hace 3 meses
padre
commit
01f4890716
Se han modificado 1 ficheros con 20 adiciones y 1 borrados
  1. 20 1
      src/components/ai/voice/VoiceInput.vue

+ 20 - 1
src/components/ai/voice/VoiceInput.vue

@@ -7,6 +7,7 @@
     >
       <div class="waveform-container" v-if="isRecording">
         <LiveWaveform
+            style="min-width: 50px;"
             :active="isRecording"
             :processing="false"
             :height="25"
@@ -53,6 +54,7 @@ const recognition = ref(null) // 语音识别实例
 const countdown = ref(0) // 倒计时剩余秒数
 const countdownTimer = ref(null) // 倒计时定时器
 const isBrowserSupported = ref(true) // 浏览器是否支持语音识别
+const mediaStream = ref(null) // 媒体流引用,用于释放资源
 
 // 检测浏览器是否支持语音识别
 const checkBrowserSupport = () => {
@@ -100,6 +102,11 @@ const initSpeechRecognition = () => {
     isRecording.value = false
     countdown.value = 0
     emit('recordingStatusChanged', false)
+    // 释放媒体流资源
+    if (mediaStream.value) {
+      mediaStream.value.getTracks().forEach(track => track.stop())
+      mediaStream.value = null
+    }
   }
 
   instance.onerror = (event) => {
@@ -109,6 +116,11 @@ const initSpeechRecognition = () => {
     emit('recordingStatusChanged', false)
     ElMessage.error('语音输入失败,请重试!', true)
     countdown.value = 0
+    // 释放媒体流资源
+    if (mediaStream.value) {
+      mediaStream.value.getTracks().forEach(track => track.stop())
+      mediaStream.value = null
+    }
   }
 
   return instance
@@ -173,7 +185,9 @@ const toggleSpeechInput = () => {
     }
 
     navigator.mediaDevices.getUserMedia({ audio: true })
-        .then(() => {
+        .then((stream) => {
+          // 存储媒体流,以便后续释放
+          mediaStream.value = stream
           // 先设置UI状态,让用户知道系统正在准备
           isRecording.value = true
           emit('recordingStatusChanged', true)
@@ -195,6 +209,11 @@ const toggleSpeechInput = () => {
 onUnmounted(() => {
   clearInterval(countdownTimer.value)
   recognition.value?.stop()
+  // 释放媒体流资源
+  if (mediaStream.value) {
+    mediaStream.value.getTracks().forEach(track => track.stop())
+    mediaStream.value = null
+  }
 })
 </script>