simpleSound.js

Bei der Arbeit an der geplanten neuen Homepage für das Münchener Cafe Jasmin (dessen bestehende Seite ebenfalls von mir ist) habe ich die Gelegenheit genutzt, das iOS-Werbespiel des Cafes nach HTML5 zu portieren. Ziel hierbei war es, den FruitNinja-Klon auf allen gängigen Geräten lauffähig zu gestalten.

Angenehmerweise gab es auch keinerlei Probleme mit der plattformübergreifenden Umsetzung, alle benötigten Technologien sind auf modernen Endgeräten gleichermaßen verfügbar – bis auf den Sound. Hier gibt es nicht nur unterschiedliche Methoden, sondern auch abweichende unterstützte Dateiformate.

Abhilfe schafft simpleSound.js, das diese verschiedenen Funktionen und Formate vereint, um eine sehr einfache, einheitliche API für das Laden und Abspielen von Audiodateien zu ermöglichen.

Benutzung

Die Benutzung ist ausgesprochen einfach. Nachdem simpleSound.js eingebunden wurde, kann mit der Funktion simpleSound.load('dateiname') eine Datei eingebunden, und mit simpleSound.play('dateiname') abgespielt werden. Wichtig ist hierbei, dass die Sounddatei als mp3 wie auch ogg im gleichen Ordner vorliegt und der Dateiname ohne Endung angegeben wird.

Um den Sound ‘hello’ abzuspielen, müssen also die Dateien sound/hello.mp3 wie auch sound/hello.ogg vorhanden sein, und simpleSound.play('sound/hello') aufgerufen werden.

Download & Lizenz

simpleSound.js ist unter der MIT Lizenz verfügbar – kurz gesagt: macht damit, worauf ihr Lust habt. Ich freue mich natürlich trotzdem über eine Nachricht, wenn ihr damit irgendetwas cooles anstellt!

Den aktuellen Code findet ihr auf GitHub oder hier zum direkten Download. Pull Requests, Bugreports und Forks sind immer erwünscht!

 

Probleme bei der Audiowiedergabe

Das größte Problem bei plattformunabhängiger Audiowiedergabe ist die unterschiedliche Funktionsabdeckung zwischen den Browsern:

Browsermp3ogg<audio> TagAudioContextWebkitAudioContext
Internet ExplorerJaNeinJaNeinNein
FirefoxJeinJaJaJaNein
ChromeJaJaJaJaJa
SafariJaNeinJaNeinJa
OperaJaJaJaJaNein
Mobile SafariJaNeinJaNeinJa
Opera Mini/MobileJaJeinJaNeinNein
Android BrowserJaNeinJaNeinNein

Audiowiedergabe per <audio>-Tag ist zwar in allen Browsern möglich, benötigt jedoch für jede Instanz ein eigenes Tag. Das bedeutet, es ist nicht möglich, eine Datei zweimal gleichzeitig abzuspielen, ohne zwei Tags einzubauen.

Die Web Audio API ermöglicht nicht nur ein leichteres Erstellen von Instanzen, sie ist auch um einiges performanter. Leider ist sie noch nicht in allen Browsern verfügbar, und die API-Funktionen sind in den Browsern unterschiedlich benannt.

iOS Webkit hat eine Einschränkung, bei der ein Sound das erste mal nur von einem Userevent ausgelöst werden kann, etwa das Tippen auf den Bildschirm. Ist der Sound so erst einmal freigeschalten, kann er zu einem beliebigen Zeitpunkt abgespielt werden.

Lösungsansätze

simpleSound.js benutzt, wenn möglich, mp3-Sounds, fällt bei fehlender Unterstützung auf ogg zurück. Überprüft wird das, indem bei der automatischen Initialisierung des Scripts ein <audio>-Element erstellt wird, dessen canPlaytype() Methode überprüft wird.

Je nach Browser wird die entsprechende Web Audio API verwendet. Sollte diese nicht verfügbar sein, werden Audio-Elemente genutzt. Um das gleichzeitige Abspielen mehrerer Instanzen der gleichen Sounddatei zu ermöglichen, wird zum Abspielen ein Klon des ursprünglichen Elements erstellt, der nach Verwendung gelöscht wird.

Unter iOS Webkit (Mobiles Safari & Chrome) spielt das Script bei jedem Touch-Event die neu geladenen Sounddateien mit einer Lautstärke von 0 ab. So kann die Beschränkung auf Userevents umgangen werden.

Todo

simpleSound.js ist bewusst, wie der Name schon andeutet, sehr simpel gehalten. Es besteht aus zwei Methoden – einer zum Laden, einer zum Abspielen – und soll diese Einfachheit beibehalten. Dennoch gibt es ein paar Features, die noch geplant sind:

  • Handler für aktive Sounds
  • simpleSound.loop(url) um einen Sound zu wiederholen
  • simpleSound.stop(handler) um einen Sound zu stoppen
  • simpleSound.onReady(function) um eine Callback-Funktion aufzurufen, wenn alle Sounds geladen sind

Dank & Erwähnungen

Die Idee für simpleSound.js kam mir durch lowLag.js, ein ähnliches aber nicht ganz so simples Script von Kirk Israel.

Howler.js ist der nicht ganz so minimalistische, aber funktionsreichere Ansatz für plattformübergreifendes Audio. Es unterstützt Spriting, Lautstärkeregelung und 3D-Positionierungen.