Sound auf Hover abspielen – Web Audio API Edition

Avatar of Notary Sojac
Notary Sojac am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Ich erhielt eine E-Mail von einem Notary Sojac, der mein Tutorial zum Thema Sound auf Hover abspielen gesehen hatte. In diesem Tutorial mussten wir zu ziemlich hackigen Verhaltensweisen greifen, um den Sound schön auf unsere Ereignisse reagieren zu lassen. Notary Sojac hatte ein Update, um den bestehenden Code besser funktionieren zu lassen, aber wichtiger noch, er untersuchte die Web Audio API, um solche Dinge zu tun. Ich wusste nicht einmal, dass es so etwas gibt. Es stellt sich heraus, dass es nicht die HTML5-Audioelemente steuert, sondern einen tieferen Zugriff als das ermöglicht.

Das Folgende ist ein Gastbeitrag von Notary Sojac, der alles erklärt.

Wir sind alle beeindruckt von den Fähigkeiten des HTML5 Canvas. Die Idee, eine standardisierte und logische Methode zum Ausführen von 2D-Zeichenoperationen zu schaffen, eröffnete eine erstaunliche neue Welt, in der ein Programmierer eine Sprache lernen und erstaunliche Produkte entwickeln konnte, die auf allen relevanten Plattformen bereitgestellt werden konnten! Denken Sie einen Moment darüber nach, wie wichtig das ist. Denken Sie nun darüber nach, wer eine erstaunliche Grafik-Anwendung mit einem fehlerhaften, glitchen Sound-System haben möchte, das nur Momente nach dem Klicken Töne wiedergibt und manchmal sogar vergisst, Töne wiederzugeben? Das ist die Art von Produkt, die Sie erhalten (besonders auf mobilen Plattformen), wenn Sie den HTML5 <audio> Elementpfad wählen. In Desktop-Browsern ist es besser, aber leider wird es aus Gründen, die über den Rahmen dieses Artikels hinausgehen, niemals perfektioniert werden. Aber im Moment gibt es für den Desktop noch Hoffnung. Und es gibt auch in Zukunft Hoffnung für mobile Anwendungen. Diese Hoffnung heißt...

Web Audio API

Die Web Audio API ist für hohe Präzision und Low-Level-Zugriff konzipiert. Man kann buchstäblich Datenbits an die Samples schreiben. Ich bin mir nicht zu 100% sicher, was ein Sample ist, aber ich glaube, es hat etwas mit Luftdruck gegen ein Mikrofon (aka, die Position des Mikrofon-Treibers) zu einem bestimmten Zeitpunkt zu tun. Das ist ziemlich Low-Level, wenn Sie mich fragen. In Google Chrome werden alle Audiofunktionen in einem separaten Thread verarbeitet, um "Nicht-Wonkyness" zu gewährleisten.

Am 21. August begann Mozilla öffentlich bekannt zu geben, dass sie ihre ursprüngliche, wegweisende "Audio Data API" fallen lassen und beginnen, Googles "Web Audio API" in ihrem Browser zu implementieren. Aber das bedeutet, zum Zeitpunkt des Schreibens, dass Sie einen Fallback für Firefox verwenden müssen.

Von Chris Wilson gibt es hier eine gute Zusammenfassung in diesem Google I/O-Talk

Anwendung

Leider benötigt man mit der Web Audio API deutlich mehr JavaScript als mit einfachen HTML5-Audioelementen, aber oft ist die Präzision der Web Audio API unerlässlich.

Zuerst müssen wir den Sound laden, was mit einer Funktion wie dieser geschehen kann

// you'll put the PCM audio in here
var audioBuffer = null;  
var context = new webkitAudioContext();

function loadDogSound(url, variableToBufferSound) {
  var request = new XMLHttpRequest();
  request.open('GET', url, true);
  request.responseType = 'arraybuffer';

  // Decode asynchronously
  request.onload = function() {
    context.decodeAudioData(request.response, function(buffer) {
      variableToBufferSoundIn = buffer;
    }, onError);
  }
  request.send();
}

Dann spielen wir den Puffer ab, mit einer Funktion wie dieser

function playSound(buffer) {

  // creates a sound source
  var source = context.createBufferSource();

  // tell the source which sound to play
  source.buffer = buffer;          

  // connect the source to the context's destination (the speakers)           
  source.connect(context.destination);       
  
  // play the source now
  source.noteOn(0);                          
}

Das ist viel mehr Code, als wir als Designer benötigen, die nur einfache Mouseover-Soundeffekte abspielen wollen. Glücklicherweise habe ich ein kleines JavaScript-Framework für die Verwendung der Web Audio API zusammengebastelt.

Mit dieser neuen API muss man nur noch

  1. einen AudioContext erstellen
  2. einen Sound in diesen AudioContext laden
  3. den Sound abspielen

All diese Schritte sind Einzeiler! Fallbacks auf gutes altes HTML5 sind inklusive!

<script src="javascripts/webAudioApiForDesigners.js"></script>

<script>
// 1
var context = initializeNewWebAudioContext();

// 2
context.loadSound('audio/beep.ogg', 'beep');

$("#nav-one a")
  .mouseenter(function() {
    // 3
   context.playSound('beep');
  });
</script>

Demo ansehen

Gründe, warum HTML5-Audioelemente eine schlechte Wahl sein können

  • Probleme mit der Latenz, bei denen Töne zu falschen Zeiten abgespielt werden
  • Unerklärliche Knackgeräusche beim gleichzeitigen Abspielen mehrerer Audiodateien
  • Begrenzung der Anzahl von HTML5-Audioelementen, die gleichzeitig abgespielt werden können

Gründe, warum HTML5 für Ihr Projekt besser geeignet sein könnte

  • Sehr einfach und unkompliziert zu bedienen
  • Kann Hintergrundmusik problemlos abspielen
  • Irgendwann ( wilde Vermutung: nicht früher als in den nächsten 3 Jahren ) werden die Fehler in diesen HTML-DOM-Elementen behoben sein

Weitere Informationen

HTML5 Rocks hat eine solide Einführung.