有许多ReactJS组件提供UI来控制音频播放。其中大多数假设您将提供音频文件路径。我该如何代替UI来控制AudioContext.destination node的音频播放?
AudioContext将具有各种源和中间节点。我希望UI组件相应地在AudioContext上向用户提供信息(当前时间位置;音量状态)和控件(播放/暂停;音量,静音)。
答案 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,因为我是该软件包的作者。 :-)