You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript音频录制无法停止问题:stopAudio()失效求助

调用stopAudio()无法停止录制,提示非活跃但麦克风图标显示正在录制的问题解决

问题根源

核心问题是你在startAudio函数中创建了MediaRecorder实例,但从未调用mediaRecorder.start()启动录制流程。浏览器顶部的麦克风图标亮起,只是因为getUserMedia成功获取了麦克风权限,但MediaRecorder实际上处于未激活状态,此时调用stop()自然会提示“录制已处于非活跃状态”。

此外还有两处潜在问题:

  • stopAudio未做状态校验,直接调用stop会在mediaRecorder未初始化时抛出错误
  • 录制结束后未主动释放媒体流,可能导致麦克风被持续占用

修复后的代码

let recorder;
let audioChunks = [];
let mediaRecorder = null;
let audioPlayer = null;
let mediaStream = null; // 保存媒体流,用于录制结束后释放麦克风

function startAudio() {
  // 停止之前的音频播放
  if (audioPlayer !== null) {
    audioPlayer.pause();
  }

  // 如果已有正在录制的实例,先停止
  if (mediaRecorder?.state === "recording") {
    stopAudio();
  }

  navigator.mediaDevices.getUserMedia({ audio: true })
    .then(stream => {
      mediaStream = stream;
      const chunks = [];
      mediaRecorder = new MediaRecorder(stream);

      mediaRecorder.addEventListener('dataavailable', event => {
        chunks.push(event.data);
      });

      mediaRecorder.addEventListener('stop', () => {
        const blob = new Blob(chunks, { type: 'audio/wav' });
        const audioUrl = URL.createObjectURL(blob);

        // 创建音频元素并插入容器
        const audioElement = document.createElement('audio');
        audioElement.src = audioUrl;
        audioElement.controls = true;
        const container = document.getElementById('AudioContainer');
        container.innerHTML = '';
        container.appendChild(audioElement);
        
        audioPlayer = audioElement;
        AudioClip = `<audio src='${audioUrl}' controls='true' />`;
        
        // 释放媒体流,关闭麦克风
        mediaStream.getTracks().forEach(track => track.stop());
        mediaStream = null;
      });

      // 启动录制——这是之前缺失的关键步骤
      mediaRecorder.start();
    })
    .catch(err => {
      console.error('获取麦克风权限失败:', err);
    });
}

function stopAudio() {
  // 仅在录制状态时执行停止操作
  if (mediaRecorder && mediaRecorder.state === "recording") {
    mediaRecorder.stop();
  } else {
    console.warn('当前没有正在进行的录制');
    // 强制释放麦克风,避免图标一直亮起
    if (mediaStream) {
      mediaStream.getTracks().forEach(track => track.stop());
      mediaStream = null;
    }
    mediaRecorder = null;
  }
}

关键修改点

  • 补充mediaRecorder.start()调用:这是启动录制的核心步骤,没有它MediaRecorder始终处于空闲状态
  • 新增媒体流释放逻辑:录制结束后主动关闭麦克风轨道,避免浏览器麦克风图标持续亮起
  • 增加状态校验:startAudio中避免重复创建录制实例,stopAudio中仅在有效状态下执行停止操作
  • 优化DOM操作:用原生API代替字符串拼接创建音频元素,更安全易维护

内容的提问来源于stack exchange,提问作者Heavy Weapons Guy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 12:58:22