将音频播放器UI连接到AudioContext.destination

时间:2019-04-15 08:42:44

标签: javascript reactjs web-audio-api

有许多ReactJS组件提供UI来控制音频播放。其中大多数假设您将提供音频文件路径。我该如何代替UI来控制AudioContext.destination node的音频播放?

AudioContext将具有各种源和中间节点。我希望UI组件相应地在AudioContext上向用户提供信息(当前时间位置;音量状态)和控件(播放/暂停;音量,静音)。

1 个答案:

答案 0 :(得分:0)

不幸的是,没有简单的方法可以将AudioElement的传输功能映射到AudioContext,但是当然有一些相似之处。

在以下示例中,我不会使用任何React,但是希望将代码片段包装在一个可由您选择的前端框架使用的Component中。

假设您有一个AudioContext实例。

const audioContext = new AudioContext();

在这种情况下,audioContext仅用于通过使用OscillatorNode来播放简单的连续正弦波。

const oscillatorNode = new OscillatorNode(audioContext);

oscillatorNode.start();
oscillatorNode.connect(audioContext.destination);

当然可以通过调用oscillatorNode来停止oscillatorNode.stop(),但这将使oscillatorNode无效。无法再次启动。如果每个OscillatorNode都不止一个,则还必须执行此操作。

但是有一种方法可以通过将其暂停来暂停整个AudioContext。

audioContext.suspend();

这将返回一个承诺,该承诺将在AudioContext暂停时解析。要使AudioContext重新运行,可以使用其resume()方法。

audioContext.resume();

就像suspend()方法resume()一样,也会返回一个承诺,该承诺将在上下文再次运行时解决。

除了AudioContext还具有state属性,该属性可用于确定audioContext'running''suspended'还是'closed'

控制整个audioContext的音量比较棘手。每个AudioContext都有一个目的地,即所有节点都必须连接到的AudioNode。但是目的地不允许修改音量。我认为获得此功能的最简单方法是使用额外的GainNode作为代理。

const destinationGainNode = new GainNode(audioContext);

destinationGainNode.connect(audioContext.destination);

然后,您必须确保将所有内容都连接到destinationGainNode。对于上面介绍的oscillatorNode,它看起来像这样:

oscillatorNode.connect(destinationGainNode);

有了该代理,您可以使用gain的{​​{1}} AudioParam来控制音量。要使信号通话静音...

destinationGainNode

...然后再次取消静音,只需致电...

destinationGainNode.gain.value = 0;

我希望这有助于创建一个React组件来控制AudioContext。

请注意,所有示例均使用Web Audio API的最新语法,该语法在Edge和Safari中尚不可用。为了使示例在这些浏览器中运行,需要使用polyfill。我当然推荐standardized-audio-context,因为我是该软件包的作者。 :-)