tob*_*sen 7 html javascript audio web-audio-api
我正在构建一个显示有关视频音频的信息的组件。我使用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)
Run Code Online (Sandbox Code Playgroud)
当组件被卸载时,我会这样做:
if (this.source && this.scriptNode) {
this.source.disconnect(this.scriptNode)
this.scriptNode.disconnect(window.audioContext.destination)
}
Run Code Online (Sandbox Code Playgroud)
我认为这会让我处于可以安全地创建和连接新节点的状态。但是下次挂载组件时,这个块会抛出前面提到的错误:
if (!this.source && !this.scriptNode) {
this.source = window.audioContext.createMediaElementSource(video) // this throws the error
this.scriptNode = window.audioContext.createScriptProcessor(4096, 1, 1)
}
Run Code Online (Sandbox Code Playgroud)
我可以做的一切全球性的,即把它去工作source,并scriptNode于window而不是this。但如果我的视频元素发生变化,这将不起作用。这样做的正确方法是什么?
小智 3
您不会销毁使用 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);
Run Code Online (Sandbox Code Playgroud)