使用AudioContext断开节点的问题(Web Audio API)

时间:2016-07-19 14:11:46

标签: javascript html5 audio web-audio

我正在构建一个显示视频音频信息的组件。我使用AudioContext接口从HTML5视频元素中获取音频样本。它在我第一次创建组件时工作正常,但是当卸载组件然后在以后重新创建时,我收到以下错误消息:

  

未捕获的InvalidStateError:无法执行   'AudioContext'上的'createMediaElementSource':HTMLMediaElement已经存在   先前连接到不同的MediaElementSourceNode。

以下是我获取音频的方式:

const video = document.querySelectorAll('video')[0]

if (!window.audioContext) {
  window.audioContext = new (window.AudioContext || window.webkitAudioContext)
}

if (!this.source && !this.scriptNode) {
  this.source = window.audioContext.createMediaElementSource(video)
  this.scriptNode = window.audioContext.createScriptProcessor(4096, 1, 1)
}

this.scriptNode.onaudioprocess = (evt) => {
 // Processing audio works fine...
}

this.source.connect(this.scriptNode)
this.scriptNode.connect(window.audioContext.destination)

当卸载组件时,我会这样做:

if (this.source && this.scriptNode) {
  this.source.disconnect(this.scriptNode)
  this.scriptNode.disconnect(window.audioContext.destination)
}

我认为这会让我处于可以安全地创建和连接新节点的状态。但是下次安装组件时,此块会抛出前面提到的错误:

if (!this.source && !this.scriptNode) {
  this.source = window.audioContext.createMediaElementSource(video) // this throws the error
  this.scriptNode = window.audioContext.createScriptProcessor(4096, 1, 1)
}

我可以通过让所有内容全局化来实现它,即将sourcescriptNode放在window而不是this上。但是,如果我的视频元素发生变化,那将无效。这样做的正确方法是什么?

1 个答案:

答案 0 :(得分:1)

您没有销毁使用context.createMediaSourceElement创建的节点。您的页面视频元素没有改变,您所做的一切都是从音频图表中断开视频音频流。因此,视频元素仍然绑定到AudioNode,在这种情况下是' this.source'。而不是尝试重新创建源只是检测源是否已经定义。

if (this.source == undefined) {
  // Build element
  this.source = window.audioContext.createMediaElementSource(video);
}

this.scriptNode = window.audioContext.createScriptProcessor(4096, 1, 1)
this.source.connect(this.scriptNode);
this.scriptNode.connect(window.audioContext.destination);