Boris Smus

interaction engineering

Musical mashups in pure JavaScript

When I want to learn a new song on guitar, I often search for chords online. There are many sites that provide chords and tabs, and Google indexes them nicely. But the quality of chords is often poor, and there's no way to submit corrections. When I ran a MoinMoin wiki, I kept my fixed versions of songs there. Even making modifications to existing chords was painful though, since it involved hand-editing a plain text file and ensuring that the chords were properly aligned with the lyrics. My preferred solution to this problem is to write a web application to facilitate easy collaborative editing of simple folk/rock/pop songs.

I started working on a proof-of-concept prototype. To begin with, I wanted an easy way of finding song lyrics, which provide the skeleton for most guitar pieces that I'm interested in. Later, I planned to work on annotating those lyrics. As I prepared to whip up a light django application to scrape lyrics sites, I realized that there may be a simpler way: if I found a friendly lyrics API, there would be no need to write any server side code. Could the entire service be written in Javascript?

LyricWiki.org had exactly what I need: a simple way to access lyrics in JSON format. Of course, you can't just do an XmlHttpRequest to lyricswiki.org because of XSS security restrictions. Instead, you can work around this cross-domain scripting issue by writing out <script> tags, and specifying the script src dynamically. Luckily, the LyricWiki JSON is wrapped (padded) in a variable named 'song'. As I later discovered, this practice of wrapping JSON in a variable is well established, and called JSONP. This technique makes it easy to simply evaluate the script tag, and wait for the song variable to change. Now If only there was a safe way of doing this sort of cross-domain scripting without introducing a host of XSS vulnerabilities, writing mashups would be a walk in the park!

After only two hours of hacking around, including learning jQuery, I came up with a little demo application, written in pure Javascript. Hooray for jQuery, humanmsg, and the LyricsWiki API!