如何解决将setSinkId与stereoPanner结合使用?
我正在编写一个Electron应用程序,使用Focusrite Scarlett 18i20 USB声卡将单独的音频流传输到10个音频通道。 Windows 10将输出拆分为以下立体声输出:
- 焦点1 + 2
- 焦点3 + 4
- 焦点5 + 6
- 焦点7 + 8
- 焦点9 + 10
因此,我需要该应用程序将音频发送到特定的输出,以及拆分立体声通道。示例:要将音频传递到第三输出,我需要将其发送到左声道的“ Focusrite 3 + 4”。不幸的是,我似乎无法同时做这两项。
我从一个音频对象开始:
let audio = new Audio("https://test.com/test.mp3");
let devices = await navigator.mediaDevices.enumerateDevices();
devices = devices.filter(device => device.kind === 'audiooutput');
audio.setSinkId(sinkId).then(() => {
audio.play();
}
工作:我只播放左声道:
let audioContext = new AudioContext();
let source = audioContext.createMediaElementSource(audio);
let panner = audioContext.createStereoPanner();
panner.pan.value = -1;
source.connect(panner);
panner.connect(audioContext.destination);
到目前为止,一切都很好。但是,当我尝试合并这些对象时,sinkId将被忽略,并且音频将被发送到默认音频输出。我尝试了几种方法,包括这种方法:
audio.setSinkId(sinkId).then(() => {
let audioContext = new AudioContext();
let source = audioContext.createMediaElementSource(audio);
let panner = audioContext.createStereoPanner();
panner.pan.value = -1;
source.connect(panner);
panner.connect(audioContext.destination);
}
我还尝试了使用audioContext.createChannelMerger
而不是stereoPanner的方法。它可以完美地单独运行,但不能与setSinkId结合使用。在Windows 10和Mac上,我得到相同的行为。
有什么想法吗?
解决方法
要将 AudioContext
的音频输出路由到特定输出设备,您需要将 MediaStreamAudioDestinationNode
与另一个音频元素结合使用。现有音频元素的 sinkId
路由到 AudioContext
后不再有任何影响。
所需的信号流以某种方式看起来像这样:
audio
↓
MediaElementAudioSourceNode
↓
StereoPannerNode
↓
MediaStreamAudioDestinationNode
↓
outputAudio
然后需要更改您的 AudioContext
代码以将所有内容路由到 MediaStreamAudioDestinationNode
而不是默认目的地。
let audioContext = new AudioContext();
let source = audioContext.createMediaElementSource(audio);
let panner = audioContext.createStereoPanner();
let destination = audioContext.createMediaStreamDestination();
panner.pan.value = -1;
source.connect(panner).connect(destination);
最后一部分是将 stream
的 MediaStreamAudioDestinationNode
路由到新创建的音频元素,然后可用于设置 sinkId
。
const outputAudio = new Audio();
outputAudio.srcObject = destination.stream;
outputAudio.setSinkId(sinkId);
outputAudio.play();
请注意,仅使用音频元素来设置 sinkId
有点小技巧。有计划将 sinkId
设置为 AudioContext
的一项功能。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。