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

Ris*_*shi 3 web-audio-api

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

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

Mar*_*S95 5

2016 年 8 月更新:


显然,调用的行为.connect()发生了变化;过去,输入/输出索引会随着每次调用而自动递增,但现在它们默认为 0 - 因此,当未指定时,调用将始终将输出 0 连接到输入 0。


如果输入流有两个声道,但仅使用其中一个声道,则您必须手动将该声道路由到左扬声器和右扬声器。通过使用 ChannelSplitter,可以将channels立体声中的两个connection(与 的连接MediaElementSource)分成两个单独的单声道。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);
Run Code Online (Sandbox Code Playgroud)

这是它在图表中的样子。请记住,输入和分配器以及合并器和目标之间的连接是立体声连接(或更多,具体取决于配置 - 当您设置 2.1、5.1 或 7.1 时,合并器和目标之间的连接可以包含 3、6 或分别为 8 个通道),而分离器和合并器之间的两个连接是单声道连接。

+--------------+    +------------+    +-------------------+    +-----------+
| Stereo input |===>| Splitter   |    | Merger            |===>|destination|
+--------------+    |   channel0 |--->|   channel0 (left) |    +-----------+
                    |   channel1 | \  |                   |
                    |   etc      |  ->|   channel1 (right)|
                    +------------+    +-------------------+
Run Code Online (Sandbox Code Playgroud)

我不是百分百确定,但这可能适用于渠道合并节点。您只需将增益节点连接到输入 1 和 2。(调用.connect两次)。

编辑(我现在有时间,所以更完整的答案):

您是否真的收到单声道音频,因为 webAudio 应该自动混合该音频,根据此文档,其中指出:For example, if a mono audio stream is connected to a stereo input it should just mix to left and right channels appropriately.。如果您收到立体声流,其中只有一个通道包含数据,则需要将其分成两个通道,然后将带有音频的通道连接到左侧和右侧:(此处的工作示例

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);
Run Code Online (Sandbox Code Playgroud)

merger和上发生的情况splitter是,当您调用 时.connect,您会占用下一个通道,但您只想占用第一个通道,然后将其拆分。因此,我们将其路由到增益节点,并从那里将其拆分:

                +----------------+    +----+     +------------------+ 
+----------+    |    Splitter    |    |gain|     |  Merger          |
|mono input|--->|       channel0 |--->|    |---->| channel0 (left)  |   +-----------+
+----------+    |       channel1 |    |    |     |                  |-->|destination|
                |       etc      |    |    |---->| channel1 (right) |   +-----------+
                +----------------+    +----+     +------------------+ 
Run Code Online (Sandbox Code Playgroud)