Häufig gestellte Fragen zu Web-Audio

Boris Smus

In den letzten Monaten hat sich die WebKit Web Audio API zu einer überzeugenden Plattform für Spiele und Audioanwendungen im Web entwickelt. Während sich Entwickler damit vertraut machen, tauchen immer wieder ähnliche Fragen auf. Mit diesem kurzen Update möchten wir versuchen, einige der am häufigsten gestellten Fragen zu beantworten, um Ihre Erfahrung mit der Web Audio API zu verbessern.

F: Hilfe, ich kann keine Töne abspielen.

A: Wenn Sie mit der Web Audio API noch nicht vertraut sind, sehen Sie sich die Anleitung für die ersten Schritte oder das Rezept von Eric für die Audiowiedergabe auf Basis der Nutzerinteraktion an.

F: Wie viele Audiokontexte sollte ich haben?

A: Im Allgemeinen sollten Sie ein AudioContext pro Seite angeben. Ein einzelner Audiokontext kann viele damit verbundene Knoten unterstützen. Sie können zwar mehrere AudioContexts auf einer einzelnen Seite angeben, 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 abspielen, aber noteOn() macht nichts. Ich brauche Unterstützung.

A: Sobald ein Quellknoten die Wiedergabe beendet hat, kann er keine weiteren Inhalte wiedergeben. Für eine erneute Wiedergabe des zugrunde liegenden Puffers sollten Sie ein neues AudioBufferSourceNode erstellen und noteOn() aufrufen.

Obwohl die Neuerstellung des Quellknotens möglicherweise ineffizient erscheint, sind Quellknoten stark für dieses Muster optimiert. Wenn du einen Handle für den AudioBuffer behältst, musst du außerdem keine weitere Anfrage an das Asset senden, um denselben Ton noch einmal abzuspielen. Wenn Sie dieses Muster wiederholen müssen, kapseln Sie die Wiedergabe mit einer einfachen Hilfsfunktion wie playSound(buffer).

F: Warum muss jedes Mal ein neuer Quellknoten erstellt werden, wenn ein Ton abgespielt wird?

A: Bei dieser Architektur wird das Audio-Asset vom Wiedergabestatus entkoppelt. Wie bei einem Plattenspieler: Puffer sind analog zu Einträgen und Quellen zu Abspielköpfen. Da bei vielen Anwendungen mehrere Versionen desselben Puffers gleichzeitig abgespielt werden, ist dieses Muster unerlässlich.

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

A: MediaElementAudioSourceNode wird vorbereitet. Sofern verfügbar, funktioniert das ungefähr so (Hinzufügen eines Filtereffekts zu einem Sample, das über das Audio-Tag abgespielt wird):

<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 in diesem Crbug erfasst. Bei dieser Einrichtung muss mediaSourceNode.noteOn() nicht aufgerufen werden. Das Audio-Tag steuert die Wiedergabe.

F: Wann erhalte ich Ton von einem Mikrofon?

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

F: Wie kann ich nachsehen, ob ein AudioSourceNode zu Ende gespielt hat?

A: Derzeit müssen Sie einen JavaScript-Timer verwenden, da das Web Audio API diese Funktion nicht unterstützt. Das folgende Snippet aus der Anleitung 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, durch den die Web Audio API einen genaueren Callback implementiert wird.

F: Wenn die Töne geladen werden, stürzt der gesamte Thread der Benutzeroberfläche in den Hintergrund und meine Benutzeroberfläche reagiert nicht mehr. Hilfe!**

A: Verwenden Sie die decodeAudioData API für asynchrones Laden, damit der Hauptthread nicht blockiert wird. Sehen Sie sich dieses Beispiel an.

F: Kann das Web Audio API verwendet werden, um Töne schneller als in Echtzeit zu verarbeiten?

A: Ja, an einer Lösung wird gearbeitet. Hab noch etwas Geduld!

F: Ich habe eine tolle Web Audio API-Anwendung erstellt, aber wenn der Tab, in dem sie ausgeführt wird, im Hintergrund läuft, ist der Sound seltsam!

A: Das liegt wahrscheinlich daran, dass du setTimeouts verwendest. Dieses Verhalten funktioniert anders, wenn die Seite im Hintergrund ist. In Zukunft wird die Web Audio API zu bestimmten Zeiten einen Callback mit dem internen Timer von Web Audio (context.currentTime-Attribut) erreichen können. Weitere Informationen finden Sie in dieser Funktionsanfrage.

Generell bietet es sich an, die Wiedergabe zu beenden, wenn die App im Hintergrund läuft. Mithilfe der Page Viewable API können Sie erkennen, wenn eine Seite in den Hintergrund verschoben wird.

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

A: playbackRate im Quellknoten ändern.

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

A: Die Web Audio API könnte einen PitchNode im Audiokontext haben, aber dies ist schwer zu implementieren. Das liegt daran, dass es in der Audio-Community keinen einfachen Algorithmus zum Ändern der Tonlage gibt. Bekannte Verfahren verursachen Artefakte, insbesondere in Fällen, in denen die Tonhöhenverschiebung groß ist. Es gibt zwei Arten von Ansätzen, um dieses Problem zu lösen:

  • Zeitbereichsalgorithmen, die zu wiederholten Segmenten mit Artefakten führen
  • Frequenzbereichstechniken, die nachhallende Tonartefakte verursachen.

Obwohl es keinen nativen Knoten für diese Techniken gibt, können Sie dies mit einem JavaScriptAudioNode vornehmen. Dieses Code-Snippet kann als Ausgangspunkt dienen.

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

A: Derzeit wird diese Funktion nicht unterstützt, wir arbeiten aber daran. Hier finden Sie eine Funktionsanfrage.

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