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

如何实现静音时仍持续显示的音频均衡器条形图

解决音频静音时均衡器条形图停止的问题

问题根源:使用原生audio控件的静音功能时,MediaElementAudioSourceNode的输出会被静音,导致analyser获取不到有效频率数据,条形图停止。我们可以通过Web Audio API的GainNode接管音量控制,让静音操作只控制输出音量,不影响analyser对原始音频流的获取。

修改方案一:自定义播放/静音控件

替换原生audio控件,用自定义按钮控制播放、暂停和静音,完全通过GainNode管理音量:

修改后的JavaScript代码

let canvas,
  ctx,
  source,
  context,
  analyser,
  gainNode,
  fbc_array,
  bar_count,
  bar_pos,
  bar_width,
  bar_height;

let audio = new Audio();

audio.src = "test.mp3";
audio.loop = true;
audio.autoplay = true;

// 创建自定义控件
const controlsContainer = document.createElement('div');
const playBtn = document.createElement('button');
playBtn.textContent = '播放';
const muteBtn = document.createElement('button');
muteBtn.textContent = '静音';
controlsContainer.appendChild(playBtn);
controlsContainer.appendChild(muteBtn);

window.addEventListener(
  "load",
  function() {
    const audioContainer = document.getElementById("audio");
    audioContainer.appendChild(audio);
    audioContainer.appendChild(controlsContainer);

    audio.onplay = function() {
      if (typeof(context) === "undefined") {
        context = new AudioContext();
        analyser = context.createAnalyser();
        gainNode = context.createGain();
        canvas = document.getElementById("canvas");
        ctx = canvas.getContext("2d");
        source = context.createMediaElementSource(audio);

        canvas.width = window.innerWidth * 0.80;
        canvas.height = window.innerHeight * 0.60;

        // 调整音频流连接顺序:源 -> 分析器 -> 音量控制器 -> 输出
        source.connect(analyser);
        analyser.connect(gainNode);
        gainNode.connect(context.destination);

        // 初始化音量
        gainNode.gain.value = audio.volume;
      }

      FrameLooper();
    };

    // 播放/暂停按钮逻辑
    playBtn.addEventListener('click', () => {
      if (audio.paused) {
        audio.play();
        playBtn.textContent = '暂停';
      } else {
        audio.pause();
        playBtn.textContent = '播放';
      }
    });

    // 静音按钮逻辑
    let isMuted = false;
    muteBtn.addEventListener('click', () => {
      isMuted = !isMuted;
      gainNode.gain.value = isMuted ? 0 : audio.volume;
      muteBtn.textContent = isMuted ? '取消静音' : '静音';
    });
  },
  false
);

function FrameLooper() {
  window.requestAnimationFrame(FrameLooper);

  fbc_array = new Uint8Array(analyser.frequencyBinCount);
  bar_count = window.innerWidth / 2;

  analyser.getByteFrequencyData(fbc_array);

  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ctx.fillStyle = "#ffffff";

  for (let i = 0; i < bar_count; i++) {
    bar_pos = i;
    bar_width = 1;
    bar_height = -(fbc_array[i] / 2);

    ctx.fillRect(bar_pos, canvas.height, bar_width, bar_height);
  }
}

修改方案二:保留原生控件

如果想继续使用原生audio控件,需要监听控件的音量变化事件,将操作同步到GainNode,同时阻止原生静音对音频流的影响:

修改后的JavaScript代码(核心部分)

// ... 其他代码不变
window.addEventListener(
  "load",
  function() {
    const audioContainer = document.getElementById("audio");
    audioContainer.appendChild(audio);
    audio.controls = true; // 保留原生控件

    audio.onplay = function() {
      if (typeof(context) === "undefined") {
        context = new AudioContext();
        analyser = context.createAnalyser();
        gainNode = context.createGain();
        canvas = document.getElementById("canvas");
        ctx = canvas.getContext("2d");
        source = context.createMediaElementSource(audio);

        canvas.width = window.innerWidth * 0.80;
        canvas.height = window.innerHeight * 0.60;

        source.connect(analyser);
        analyser.connect(gainNode);
        gainNode.connect(context.destination);

        // 初始化音量
        gainNode.gain.value = audio.muted ? 0 : audio.volume;

        // 监听原生控件的音量/静音变化,同步到GainNode
        audio.addEventListener('volumechange', () => {
          gainNode.gain.value = audio.muted ? 0 : audio.volume;
          // 取消原生静音状态,避免影响音频流
          audio.muted = false;
        });
      }

      FrameLooper();
    };
  },
  false
);
// ... 其他代码不变

原理说明

通过GainNode接管音量控制后,静音操作只是将输出音量设为0,音频流本身依然正常传输到analyser节点,因此analyser能持续获取原始音频的频率数据,均衡器条形图就不会停止显示。

内容的提问来源于stack exchange,提问作者SKNG

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 22:10:40