فهرست منبع

feat(speaking): startRecording accepts AbortSignal for cancel during mic acquisition

Two abort checkpoints: before getUserMedia (cheap pre-flight) and
after (the realistic cancel point — user clicks cancel while the
permission prompt is open). The post-getUserMedia abort releases
the just-acquired track.
jimmylee 1 هفته پیش
والد
کامیت
92faa6fbe2
1فایلهای تغییر یافته به همراه12 افزوده شده و 1 حذف شده
  1. 12 1
      src/views/Editor/EnglishSpeaking/composables/useAudioRecorder.ts

+ 12 - 1
src/views/Editor/EnglishSpeaking/composables/useAudioRecorder.ts

@@ -74,10 +74,14 @@ export function useAudioRecorder() {
     analyser = null
   }
 
-  async function startRecording(): Promise<void> {
+  async function startRecording(signal?: AbortSignal): Promise<void> {
     pcmChunks = []
     silenceDetected.value = false
 
+    if (signal?.aborted) {
+      throw new DOMException('Aborted', 'AbortError')
+    }
+
     // 获取麦克风
     try {
       mediaStream = await navigator.mediaDevices.getUserMedia({ audio: true })
@@ -89,6 +93,13 @@ export function useAudioRecorder() {
       throw err
     }
 
+    if (signal?.aborted) {
+      // User cancelled while the permission prompt was open. Release the track.
+      mediaStream.getTracks().forEach(t => t.stop())
+      mediaStream = null
+      throw new DOMException('Aborted', 'AbortError')
+    }
+
     // 创建 AudioContext(不指定 sampleRate,用硬件默认 — iOS Safari 不支持自定义采样率)
     audioContext = new AudioContext()
     sampleRate.value = audioContext.sampleRate