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 相同的结果。所有其他列始终保持沉默。我如何联系他们?我需要能够将某个音频文件发送到某个频道。
是的,本质上问题是这样解决的:
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>