Mit HTML 5 kommt auch das neue <audio> Element. Es erlaubt das abspielen von Audiodateien direkt im Browser. Eine kleine Gruppe Entwickler bei Mozilla bemühen sich auch um eine Audio API, die das Abfragen und Manipulieren der Audioelemente ermöglichen kann. Noch gilt die API als experimentel, soll aber in zukünftige Firefox Versionen zu finden sein.
Was für Möglichkeiten sich mit dieser API ergeben zeigen zahlreiche eindrucksvolle Beispiele. Hier ist eines meiner Experimente:
Favelizer – ein 16 x 16 Pixel Frequenz Spectrum in der Browseradresszeile:
Eine Live-Vorschau findet sich hier: http://labs.daslaboratorium.de/favelizer
Wer sich die gepatchte Firefox-Beta nicht herunterladen möchte, kann den Favelizer auch hier in Aktion ansehen (leider ohne Sound):
So funktionierts:
Das Audio-Element erhält ein onaudiowritten Attribut, mit dem wir beim Abspielen der Musik fortlaufend eine beliebige Javascript Funktion aufrufen können:
<audio src="datei.ogg" controls="true" onaudiowritten="update(event);">
Mit dem übergebenen event-Objekt können wir auf die Audio-Signale zugreifen:
function update(event) {
signal = event.mozFrameBuffer;
spectrum = event.mozSpectrum;
}
Um das Favicon dynamisch und möglichst schnell erzeugen zu können, greife ich auf processing.js zurück. Das ist wesentlich einfacher als beispielsweise mit
ctx = $('frame').getContext('2d');
ctx.fillStyle = '#000';
ctx.fillRect(1, 1, 1, 16);
Pixel für Pixel einzeln zu färben.
Processing.js ist eine durch Javascript verwirklichte eigene Programmiersprache und gleicht in seinem Aufbau Java. Processing.js nutzt das html5 canvas object und ermöglicht beeindruckende Graphikdarstellungen im Browser – ganz ohne Flash.
Mit einem bisschen Mathematik lässt sich so ganz einfach ein Frequenz Spectrum auf 16 x 16 Pixel bringen:
void draw() {
background(0);
strokeWeight(1.0);
if (spectrum.length > 0) {
for (int i = 0; i <= 16; i++) {
var j = i + 30 * spectrum.item(i * 4);
var log = -1 * Math.log(1 / j);
var magnitude = 16 - spectrum.item(i * 4) * 256 * log;
stroke(0, 255, 0);
line(i, 16, i, 16 - magnitude);
}
}
}
Das Favicon brauchen wir dann nur noch in regelmäßigen Abständen auszutauschen:
window.setInterval(function() {
var icon = $('icon');
var newIcon = icon.cloneNode(true);
newIcon.setAttribute('href', ctx.canvas.toDataURL());
icon.parentNode.replaceChild(newIcon, icon);
}, 60);
Es lohnt sich auf jeden Fall ein Blick in den Sourcecode: http://labs.daslaboratorium.de/favelizer
Es stockt bei mir!?
Das liegt daran, dass wir zum Austausch der einzelnen Favicon-Frames ein neues Objekt erstellen und damit das alte Icon auswechseln müssen. Da häuft sich natürlich einiges an Datenmüll (alte, nicht mehr verwendete Objekte) an, der aufwendig beseitigt werden muss. Der sg. Garbage-Collector verschluckt sich. Eine schnelle Lösung habe ich im Moment leider noch nicht parat.