2016-07-19 33 views
3

Ich erstelle eine Komponente, die Informationen zum Audio eines Videos anzeigt. Ich benutze die AudioContext Schnittstelle, um Audio-Samples von einem HTML5-Videoelement zu erhalten. Es funktioniert gut, das erste Mal, dass ich die Komponente zu erstellen, aber wenn die Komponente abgehängt und dann zu einem späteren Zeitpunkt neu erstellt, bekomme ich folgende Fehlermeldung:Probleme beim Trennen von Knoten mit AudioContext (Web Audio API)

Uncaught InvalidStateError: Failed to execute 'createMediaElementSource' on 'AudioContext': HTMLMediaElement already connected previously to a different MediaElementSourceNode.

Hier ist, wie ich das Audio erhalten:

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) 

und wenn die Komponente abgehängt ich tun:

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

ich dachte, das mich in einen Zustand versetzen würde, wo ich sicher erstellen und neue Knoten verbinden. Aber das nächste Mal, wenn die Komponente montiert ist, wirft dieser Block der Fehler bereits erwähnt:

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

ich es, indem sie alles global arbeiten konnte, das heißt setzen source und scriptNode auf window statt this. Aber das wird nicht funktionieren, wenn sich mein Videoelement ändert. Was ist der richtige Weg, dies zu tun?

Antwort

1

Sie zerstören nicht den Knoten, den Sie mit context.createMediaSourceElement erstellt haben. Sie haben Ihr On-Page-Videoelement, das sich nicht geändert hat. Sie haben lediglich den Videoaudiostream von Ihrem Audiodiagramm getrennt. Daher ist das Videoelement immer noch an einen AudioNode gebunden, in diesem Fall 'this.source'. Anstatt zu versuchen, die Quelle neu zu erstellen, muss nur festgestellt werden, ob die Quelle bereits definiert ist.

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);