网络音频 api、AudioContext 无法在通道 3 上播放。通道 4 及以上无法正常工作

问题描述 投票:0回答:1

5.1 音频系统通过 HDMI 连接。操作系统正确处理它,我可以测试每个单独的扬声器并获得预期的结果。

我需要使用JS将音频发送到特定通道(扬声器)。下面是代码。通道数量和其他细微差别工作正常。

  let source;
  const AudioContext = window.AudioContext || window.webkitAudioContext;
  const audioCtx = new AudioContext();

  const audioUrl = "1.mp3";
  const audioResp = await fetch(audioUrl);

  const arrayBuffer = await audioResp.arrayBuffer();
  const audioBuffer = await audioCtx.decodeAudioData(arrayBuffer);

  let channelCount = audioCtx.destination.maxChannelCount;
  let audioChannelCount = audioBuffer.numberOfChannels;

  const splitter = audioCtx.createChannelSplitter(channelCount);
  const merger = audioCtx.createChannelMerger(channelCount);

  source = audioCtx.createBufferSource();
  source.buffer = audioBuffer;
  source.connect(splitter);

  const test = splitter.connect(merger, 0, 0);
  const test2 = splitter.connect(merger, 0, 3);

  merger.connect(audioCtx.destination);

  source?.start();

如果我写 splitter.connect(merger, 0, 0);或 splitter.connect(合并, 0, 1);音频在左或右扬声器上正确播放。但是如果我写 splitter.connect(merger, 0, 3);它根本不玩。但是,如果我指定通道 4 或 5,则会得到与指定 0 或 1 相同的结果。所有其他列始终保持沉默。我如何联系他们?我需要能够将某个音频文件发送到某个频道。

javascript web-audio-api
1个回答
0
投票

是的,本质上问题是这样解决的:

const audioCtx = new AudioContext();
audioCtx.destination.channelCount = audioCtx.destination.maxChannelCount;

我的最终工作版本如下所示

const startBtn = document.getElementById('start');
  const stopBtn = document.getElementById('stop');
  const select = document.getElementById('select');

  document.addEventListener("DOMContentLoaded", async () => {
    let source;

    startBtn.addEventListener('click', async () => {
      const audioCtx = new AudioContext();
      const audioUrl = "https://www2.iis.fraunhofer.de/AAC/7.1auditionOutLeader_v2_rtb.mp4";

      const audioResp = await fetch(audioUrl);
      console.log('audioResp', audioResp);

      const arrayBuffer = await audioResp.arrayBuffer();
      console.log('arrayBuffer', arrayBuffer);

      const audioBuffer = await audioCtx.decodeAudioData(arrayBuffer);
      console.log('audioBuffer', audioBuffer);

      source = audioCtx.createBufferSource();
      source.buffer = audioBuffer;

      let channelCount = audioCtx.destination.maxChannelCount;
      let audioChannelCount = audioBuffer.numberOfChannels;

      audioCtx.destination.channelCount = channelCount; //Without this, there will only be two channels (0 and 1). The subwoofer will be silent and channels 2, 4 and above will duplicate 0 and 1.

      console.log('channelCount', channelCount);
      console.log('audioChannelCount', audioChannelCount);


      if (select.value === 'Original') {
        source.connect(audioCtx.destination);
      } else {
        const channelCountForSplitter = Math.max(channelCount, audioChannelCount);
        const splitter = audioCtx.createChannelSplitter(channelCountForSplitter);
        const merger = audioCtx.createChannelMerger(channelCountForSplitter);

        source.connect(splitter);
        for (let speakerChannel = 0; speakerChannel < channelCount; speakerChannel++) {
          for (let audioChannel = 0; audioChannel < audioChannelCount; audioChannel++) {
            splitter.connect(merger, audioChannel, speakerChannel);
          }
        }

        merger.connect(audioCtx.destination);

      }

      source?.start();

    });

    stopBtn.addEventListener('click', () => {
      source?.stop();
    });
  });
.menu {
    display: flex;
    gap: 2rem;
  }
<body>
<div class="menu">
  <select id="select">
    <option>
      Original
    </option>
    <option>
      Same on all speakers
    </option>
  </select>
  <button id="start">
    Start
  </button>
  <button id="stop">
    Stop
  </button>
</div>
</body>

© www.soinside.com 2019 - 2024. All rights reserved.