Procházet zdrojové kódy

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 před 1 týdnem
rodič
revize
92faa6fbe2

+ 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