Häufig gestellte Fragen zu Web-Audio

Boris Smus

In den letzten Monaten hat sich die Web Audio API von WebKit als überzeugende Plattform für Spiele und Audioanwendungen im Web etabliert. Wenn sich Entwickler mit der Funktion vertraut machen, höre ich immer wieder ähnliche Fragen. In diesem kurzen Update möchten wir einige der am häufigsten gestellten Fragen beantworten, um die Nutzung der Web Audio API zu erleichtern.

F: Hilfe, ich kann keine Töne machen!

A: Wenn Sie noch nicht mit der Web Audio API vertraut sind, sehen Sie sich die Einstiegsanleitung oder Erics Rezept zum Abspielen von Audio basierend auf Nutzerinteraktionen an.

F: Wie viele Audiokontexte sollte ich haben?

A: Im Allgemeinen sollte eine Seite eine AudioContext enthalten. Ein einzelner Audiokontext kann viele damit verbundene Knoten unterstützen. Sie können zwar mehrere AudioContexts auf einer einzelnen Seite einfügen, dies kann jedoch zu Leistungseinbußen führen.

F: Ich habe einen AudioBufferSourceNode, den ich gerade mit noteOn() wiedergegeben habe. Ich möchte ihn noch einmal wiedergeben, aber noteOn() tut nichts. Was kann ich tun?

A: Sobald die Wiedergabe eines Quellknotens beendet ist, kann er nicht mehr wiedergegeben werden. Wenn du den zugrunde liegenden Puffer noch einmal abspielen möchtest, solltest du eine neue AudioBufferSourceNode erstellen und noteOn() aufrufen.

Auch wenn es ineffizient erscheint, den Quellknoten neu zu erstellen, sind Quellknoten für dieses Muster stark optimiert. Wenn Sie einen Handle für den AudioBuffer beibehalten, müssen Sie nicht noch einmal eine Anfrage an das Asset senden, um denselben Ton noch einmal abzuspielen. Wenn du dieses Muster wiederholen musst, solltest du die Wiedergabe in einer einfachen Hilfsfunktion wie playSound(buffer) kapseln.

F: Warum müssen Sie bei der Wiedergabe eines Tons jedes Mal einen neuen Quellknoten erstellen?

A: Bei dieser Architektur wird das Audio-Asset vom Wiedergabestatus getrennt. In Analogie zu einem Plattenspieler sind Puffer analog zu den Platten und Quellen zu den Abtastköpfen. Da bei vielen Anwendungen mehrere Versionen desselben Buffers gleichzeitig wiedergegeben werden, ist dieses Muster unerlässlich.

F: Wie kann ich Audioinhalte von audio- und video-Tags verarbeiten?

A: MediaElementAudioSourceNode ist in Arbeit. Wenn es verfügbar ist, funktioniert es ungefähr so:

<audio src="sounds/sample.wav" controls>
var audioElement = document.querySelector('audio');
var mediaSourceNode = context.createMediaElementSource(audioElement);
mediaSourceNode.connect(filter);
filter.connect(context.destination);

Diese Funktion wird unter diesem CRBug verfolgt. Bei dieser Konfiguration muss mediaSourceNode.noteOn() nicht aufgerufen werden, da die Wiedergabe über das Audio-Tag gesteuert wird.

F: Wann kann ich Ton über ein Mikrofon hören?

A: Der Audioeingabeteil wird als Teil von WebRTC mit getUserMedia implementiert und als spezieller Quellknoten in der Web Audio API verfügbar sein. Sie funktioniert in Verbindung mit createMediaElementSource.

F: Wie kann ich sehen, wann die Wiedergabe einer AudioSourceNode beendet ist?

A: Derzeit müssen Sie einen JavaScript-Timer verwenden, da diese Funktion von der Web Audio API nicht unterstützt wird. Das folgende Snippet aus dem Tutorial „Erste Schritte mit der Web Audio API“ ist ein Beispiel dafür:

// Assume source and buffer are previously defined.
source.noteOn(0);
var timer = setTimeout(function() {
    console.log('playback finished');
}, buffer.duration * 1000);

Es gibt einen offenen Fehler, der dazu führt, dass die Web Audio API einen genaueren Rückruf implementiert.

F: Beim Laden von Tönen wird der gesamte UI-Thread blockiert und die Benutzeroberfläche reagiert nicht mehr. Hilfe!**

A: Die decodeAudioData API für das asynchrone Laden verwenden, um den Hauptthread nicht zu blockieren. Siehe dieses Beispiel.

F: Kann die Web Audio API verwendet werden, um Audio schneller als in Echtzeit zu verarbeiten?

A: Ja, an einer Lösung wird gearbeitet. Bleiben Sie dran!

F: Ich habe eine tolle Web Audio API-Anwendung erstellt, aber immer wenn der Tab, in dem sie ausgeführt wird, in den Hintergrund wechselt, klingen die Töne seltsam.

A: Das liegt wahrscheinlich daran, dass Sie setTimeouts verwenden, das sich anders verhält, wenn die Seite im Hintergrund ist. In Zukunft kann die Web Audio API mithilfe des internen Timers von Web Audio (context.currentTime-Attribut) zu bestimmten Zeiten einen Rückruf ausführen. Weitere Informationen finden Sie in dieser Funktionsanfrage.

Im Allgemeinen kann es sinnvoll sein, die Wiedergabe zu beenden, wenn Ihre App in den Hintergrund wechselt. Mit der Page Visibility API können Sie erkennen, wenn eine Seite in den Hintergrund wechselt.

F: Wie kann ich mit der Web Audio API die Tonhöhe eines Tons ändern?

A: Ändern Sie die playbackRate am Quellknoten.

F: Kann ich die Tonhöhe ändern, ohne die Geschwindigkeit zu ändern?

A: Die Web Audio API könnte einen PitchNode im Audiokontext haben, dies ist jedoch schwer zu implementieren. Das liegt daran, dass es in der Audio-Community keinen einfachen Algorithmus zur Tonhöhenänderung gibt. Bekannte Techniken führen zu Artefakten, insbesondere wenn die Tonhöhe stark verändert wird. Es gibt zwei Ansätze, um dieses Problem zu lösen:

  • Zeitdomänenalgorithmen, die zu wiederholten Segmentechos führen
  • Frequenzbereichstechniken, die zu hallenden Audioartefakten führen.

Es gibt zwar keinen nativen Knoten für diese Techniken, aber Sie können sie mit einem JavaScriptAudioNode ausführen. Dieses Code-Snippet kann als Ausgangspunkt dienen.

F: Wie kann ich einen AudioContext mit einer beliebigen Abtastrate erstellen?

A: Derzeit wird dies nicht unterstützt. Wir arbeiten aber daran. Weitere Informationen

Wenn Sie weitere Fragen haben, können Sie sie unter dem Tag web-audio auf StackOverflow stellen.