I just did some tinkering with offline sound and it turns out you can embed an audio clip in an HTML file, and play it without using Flash. I could have demo’d this in a raw HTML file, but it was just as easy to stick it in a Tiddlywiki file. So I made a TiddlyWiki called JinglyWiki. Click on the button and it will play a sound. If you grab the file (safest using a tool like Curl or wget, as the browser will sometimes Save As something different), you can run it offline and it will still play the sound.

JinglyWiki started after an office conversation yesterday. We had a flaky wifi connection and were pleased to be able to play a beat on http://instantrimshot.com to signify a re-connection. This got us thinking about playing beats in Tiddlywiki. Jeremy mentioned the possibility of data: URIs, and I thought back to Reinier’s great effort in playing sound without Flash. I wondered if it would work with data: URIs and to my pleasant surprise, it did. At least in FF3, which is all I’ve tested so far. I also forgot how tiny the code is to play audio without Flash - you just add an element to the page.

The point of JinglyWiki is you can stick a 300K file on your local file system or a USB stick and play gratuitous sounds without being online. Your iPod cost you several hundred bucks, whereas JinglyWiki is entirely free. Free as in you can spend your money on beer instead. JinglyWiki may well be the best portable music player you never paid a penny for. Groovy.

It would be so much more useful with some code to dynamically generate WAVs, but that’s a project for another day.

As for the name, it’s a play on the much more important project Phil Hawksworth has initiated to build a JQuery based Tiddlywiki framework: JigglyWiki. I think this nascent effort is going to produce some wonderful plugins for the JQuery community and be an important enough project to derive novelty joke names out of :), so I’m setting the trend here.

The data itself is 15KB for about a second of voice content.

Here’s the plugin code. Trivial or wot?!!!

[javascript] config.macros.jingle = {} config.macros.jingle.handler = function(place,macroName,params,wikifier,paramString,tiddler) {

button = document.createElement(“button”); button.style.fontSize = “4em”; button.innerHTML = “Play Me! Play Me!” button.onclick = function(ev) { startWav(SOUND_URL); } place.appendChild(button);

// cancel dbl-click so we can follow our natural urge to click on the button incessantly story.getTiddler(tiddler.title).ondblclick = function() {}

}

// non-flash sound handling adapted from http://www.zwitserloot.com/files/soundkit/soundcheck.html

var embedEl;

function startWav(uri) { stopWav(); embedEl = document.createElement(“embed”); embedEl.setAttribute(“src”, uri); embedEl.setAttribute(“hidden”, true); embedEl.setAttribute(“autostart”, true); document.body.appendChild(embedEl); }

function stopWav() { if (embedEl) document.body.removeChild(embedEl); embedEl = null; }

// To make a new sound, cut and paste into hixie’s handy Data URI Kitchen // http://software.hixie.ch/utilities/cgi/data/data.pl

var SOUND_URL=”data:audio/x-wav,RIFF%17%1C%00%00WAVEfmt%20%10%00%00%00%01%00%01%00%40%1F%00%00%40 ……………………” // snipped [/javascript]