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

如何用JavaScript实现耳机左右单侧音频播放与音量控制

实现单侧耳机播放声音的JavaScript方案

需求说明

点击按钮时,仅在左/右单侧耳机播放声音(另一侧完全静音),且不能通过编辑音频文件实现,必须用JavaScript动态处理。

解决方案

原生Audio对象无法直接控制单个声道的音量,需要使用Web Audio API来实现声道分离与独立增益控制。以下是修改后的完整代码:

完整代码

<head>
  <script src="https://cdn.tailwindcss.com/"></script>
</head>

<body class="h-screen grid place-items-center bg-gray-200 overflow-hidden">
  <div class="flex gap-[5vmin]">
    <div class="flex gap-[5vmin]">
    <!-- left -->
      <button title="🎶 Left sound" class="transition hover:-translate-y-1 hover:shadow-2xl focus:rotate-3 hover:border-blue-200 hover:shadow-blue-200 focus:border-blue-500 focus:shadow-blue-500 border-4 border-blue-50 shadow-md p-[10vmin] bg-white rounded-[3vmin] text-[10vmin] text-blue-500 after:content-[attr(title)] relative after:absolute after:text-sm after:-bottom-20 after:left-0 after:w-max after:bg-white after:shadow-lg after:-translate-x-[50%] after:left-[50%] after:px-4 after:py-2 after:rounded-lg after:opacity-0 focus:after:opacity-100 focus:after:duration-500 after:translate-y-12 focus:after:translate-y-0 focus:after:animate-pulse focus:animate-bounce"
        onclick="playSound({left:true})">
        🡰
      </button>
      
      <!-- right -->
      <button title="🎶 Right sound" class="transition hover:-translate-y-1 hover:shadow-2xl focus:rotate-3 hover:border-blue-200 hover:shadow-blue-200 focus:border-blue-500 focus:shadow-blue-500 border-4 border-blue-50 shadow-md p-[10vmin] bg-white rounded-[3vmin] text-[10vmin] text-blue-500 after:content-[attr(title)] relative after:absolute after:text-sm after:-bottom-20 after:left-0 after:w-max after:bg-white after:shadow-lg after:-translate-x-[50%] after:left-[50%] after:px-4 after:py-2 after:rounded-lg after:opacity-0 focus:after:opacity-100 focus:after:duration-500 after:translate-y-12 focus:after:translate-y-0 focus:after:animate-pulse focus:animate-bounce"
        onclick="playSound({right:true})">
        🡲
      </button>
    </div>

    <script>
      console.clear();

      function playSound(options) {
        const choosedDirection = () => {
          return Object.keys(options)
            .reverse()
            .find(direction => direction === "left" || direction === "right");
        };

        const direction = choosedDirection();
        if (!direction) return;

        // 初始化AudioContext,兼容旧版浏览器
        const audioContext = new (window.AudioContext || window.webkitAudioContext)();
        
        // 加载并解码音频文件
        fetch('audio.mp3')
          .then(response => response.arrayBuffer())
          .then(arrayBuffer => audioContext.decodeAudioData(arrayBuffer))
          .then(audioBuffer => {
            // 创建音频源节点
            const source = audioContext.createBufferSource();
            source.buffer = audioBuffer;

            // 创建声道分离器,将立体声拆分为左右两个独立声道
            const splitter = audioContext.createChannelSplitter(2);
            source.connect(splitter);

            // 创建增益节点,用于控制单个声道的音量
            const leftGain = audioContext.createGain();
            const rightGain = audioContext.createGain();

            // 根据选择的方向设置声道增益
            if (direction === 'left') {
              leftGain.gain.value = 1; // 左声道保持正常音量
              rightGain.gain.value = 0; // 右声道静音
            } else {
              leftGain.gain.value = 0; // 左声道静音
              rightGain.gain.value = 1; // 右声道保持正常音量
            }

            // 连接分离器到对应增益节点
            splitter.connect(leftGain, 0);
            splitter.connect(rightGain, 1);

            // 创建声道合并器,将处理后的声道合并回立体声输出
            const merger = audioContext.createChannelMerger(2);
            leftGain.connect(merger, 0, 0);
            rightGain.connect(merger, 0, 1);

            // 连接到系统音频输出
            merger.connect(audioContext.destination);

            // 开始播放
            source.start();
          })
          .catch(error => console.error('音频处理失败:', error));
      }
    </script>
</body>

关键逻辑说明

  1. 声道分离与合并:使用ChannelSplitterNode将立体声音频拆分为左右两个独立声道,处理后再通过ChannelMergerNode合并输出。
  2. 音量控制:通过GainNode精确设置单个声道的增益值(1为正常音量,0为完全静音),实现单侧播放效果。
  3. 异步处理:音频加载与解码是异步操作,通过fetch和decodeAudioData完成后再创建播放节点。
  4. 浏览器兼容:兼容旧版webkit内核浏览器的webkitAudioContext前缀。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 18:35:10