如何使用Web Audio API将单声道音频转换为立体声音频

3

我正在获取一个包含音频和视频的远程媒体流。在这个流中,我得到的是单声道音频,而我需要立体声音频。

那么,如何使用Web Audio API将单声道音频转换为立体声音频呢?

1个回答

5
2016年8月更新:

显然,.connect()调用的行为已经发生了改变。过去,每次调用时输入/输出索引都会自动增加,但现在它们只是默认为0 - 因此未指定时,调用将始终将输出0连接到输入0。


如果输入流有两个通道,但只使用其中一个通道,则必须手动将该通道路由到左右扬声器。可以通过使用ChannelSplitter将立体声连接(带有MediaElementSource的连接)中的两个channels分解成两个单独的单声道connections。然后,左(或右,根据您的使用情况)通道连接可以轻松路由到ChannelMerger的左和右连接上(由于扇出支持允许将单个输出连接到多个不同的输入),这将把所有的mono input connections合并成一个stero output connection。如旧答案所示,增益节点是不必要的。

如上所述,可以通过指定正确的索引来执行这些连接:connect(AudioNode destination, optional unsigned long output = 0, optional unsigned long input = 0);

//create a source node to capture the audio from your video element
source = context.createMediaElementSource(document.querySelector('video'));

//Create the splitter and the merger
splitter = context.createChannelSplitter();
merger = context.createChannelMerger();

//route the source audio to the splitter. This is a stereo connection.
source.connect(splitter);

//route output 0 (left) from the splitter to input 0 (left) on the merger. This is a mono connection, carrying the left output signal to the left input of the Merger.
splitter.connect(merger, 0, 0);
//route output 0 (left) from the splitter to input 1 (right) on the merger. This is a mono connection as well, carrying the left output signal to the right input of the Merger.
splitter.connect(merger, 0, 1);

//finally, connect the merger to the destination. This is a stereo connection.
merger.connect(context.destination);

以下是图示,输入和分配器之间的连接以及合并器和目标之间的连接都是立体声连接(或更多,具体取决于配置 - 当您拥有2.1、5.1或7.1组合时,合并器和目标之间的连接可以分别包含3、6或8个信道),而分配器和合并器之间的两个连接是单声道连接。

+--------------+    +------------+    +-------------------+    +-----------+
| Stereo input |===>| Splitter   |    | Merger            |===>|destination|
+--------------+    |   channel0 |--->|   channel0 (left) |    +-----------+
                    |   channel1 | \  |                   |
                    |   etc      |  ->|   channel1 (right)|
                    +------------+    +-------------------+

我不是百分之百确定,但这可能可以使用通道合并节点来解决。你只需要将增益节点连接到输入1和2。(调用.connect两次)。

编辑(我现在有时间了,所以回答更详细):

你是否真的收到了单声道音频?因为根据这份文档,Web Audio应该会自动混音,它说:例如,如果将单声道音频流连接到立体声输入,则应适当地混合到左右声道中。 如果你收到的是一个立体声音频流,其中只有一个声道包含数据,那么你需要将其拆分成两个声道,然后将带有音频的声道连接到左右两个声道:(此处有工作示例)

gain = context.createGain();
splitter = context.createChannelSplitter();
merger = context.createChannelMerger();
merger.connect(context.destination);

source.connect(splitter);
splitter.connect(gain);
gain.connect(merger);
gain.connect(merger);

在合并器和分离器上发生的事情是,当你调用`.connect`时,你会取下一个通道,但实际上你只想取第一个通道,然后将其拆分。因此,我们将其路由到增益节点,并从那里将其拆分:
                +----------------+    +----+     +------------------+ 
+----------+    |    Splitter    |    |gain|     |  Merger          |
|mono input|--->|       channel0 |--->|    |---->| channel0 (left)  |   +-----------+
+----------+    |       channel1 |    |    |     |                  |-->|destination|
                |       etc      |    |    |---->| channel1 (right) |   +-----------+
                +----------------+    +----+     +------------------+ 


这个答案是不正确的,原因有几个:1. 增益节点只有一个输出,所以你不能将它连接到合并器的多个输入上。2. 分离器分离多个通道 - 但在你的情况下,你只有一个通道,所以它没有分离任何东西。 - Asher
@Asher:1. WebAudio 支持扇出,允许一个输出连接到多个不同的输入。2. 我假设询问者有一个立体声媒体流,只使用一个声道;如果是单声道媒体流,则应自动升级。无论如何,感谢提及 - 规范在2.5年内发生了一些变化,旧方法使用.connect()已经不再起作用 - 已经修复了这个问题 :). 因此,这个答案是正确的。 - MarijnS95

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接