Playdar Homepage
About
Press
Downloads
Demos

Resolver Docs
HTTP API Docs

Playdar.js Docs

Source Code
Twitter
Mailing List
Bug Tracker
IRC (freenode, #playdar)

Playdar - the Music Content Resolver

Playdar HTTP API

Playdar is a service - it runs a small HTTP server locally on your desktop, and has a HTTP API which returns JSON. All the important API calls also support JSONP, so you can call them from the web. If you append &jsonp=mycallback to any webservice call, the result will be JSONP, eg: mycallback({...json response...});

The following examples are webservice calls made on my machine (called 'rjhome') and illustrate how you use playdar to find a source for a track - in this case: 'Surfing with the Alien' by 'Joe Satriani'.

NB: I'm ignoring album names for now to keep things simple.

Checking if Playdar is available

/api/?method=stat

{
    "name" : "playdar",
    "version" : "0.1.0",
}

Initiating a search for one song

When you tell Playdar to start resolving a track, it gives you back a query id (qid). You use ths qid to check the status of the query in subsequent calls.

/api/?method=resolve&artist=Joe%20Satriani&album=&track=Surfing%20with%20the%20Alien

{
    "qid" : "ccefa69c-0057-11de-a517-0018f32e506c"
}
You can also specify a qid yourself by appending &qid=XXX. This can be useful for setting up Javascript callbacks; the hAudio demo does this.

Checking for results (first check)

/api/?method=get_results&qid=ccefa69c-0057-11de-a517-0018f32e506c

{
    "qid" : "ccefa69c-0057-11de-a517-0018f32e506c",
    "refresh_interval" : 1000,
    "query" : {
        "qid" : "ccefa69c-0057-11de-a517-0018f32e506c",
        "artist" : "Joe Satriani",
        "album" : "",
        "track" : "Surfing with the Alien",
        "mode" : "normal",
        "solved" : false
    },
    "results" : [
        {
            "sid" : "ccf63584-0057-11de-900d-0018f32e506c",
            "artist" : "Joe Satriani",
            "album" : "",
            "track" : "Surfing with an alien",
            "source" : "rjhome",
            "size" : 12226688,
            "mimetype" : "audio/mpeg",
            "bitrate" : 213,
            "duration" : 459,
            "score" : 0.91
        },
        {
            "sid" : "ccf636ec-0057-11de-910d-0018f32e506c",
            "artist" : "Joe Satriani",
            "album" : "",
            "track" : "Surfing with the Alien (live)",
            "source" : "rjhome",
            "size" : 7905443,
            "mimetype" : "audio/mpeg",
            "bitrate" : 190,
            "duration" : 331,
            "score" : 0.84
        }
    ]
}
You can see two potential matches were found on my local machine, 'rjhome'. The query object has a "solved" property set to false. This means Playdar hasn't found a perfect match. The refresh_interval is the suggested number of milliseconds to wait before polling for results again.

Checking for results (a second time)

After waiting a a second, you hit the same URL again. You'll receive the same results as before, possibly with new results listed too.

/api/?method=get_results&qid=0b76e87c-0057-11de-b669-0018f32e506c

{
    "qid" : "ccefa69c-0057-11de-a517-0018f32e506c",
    "refresh_interval" : 1000,
    "query" : {
        "qid" : "ccefa69c-0057-11de-a517-0018f32e506c",
        "artist" : "Joe Satriani",
        "album" : "",
        "track" : "Surfing with the Alien",
        "mode" : "normal",
        "solved" : true
    },
    "results" : [
        {
            "sid" : "ccf63584-0057-11de-900d-0018f32e506c",
            "artist" : "Joe Satriani",
            "album" : "",
            "track" : "Surfing with the Alien",
            "source" : "rjlaptop",
            "size" : 10164410,
            "mimetype" : "audio/mpeg",
            "bitrate" : 196,
            "duration" : 312,
            "score" : 1.0
        },
        {
            "sid" : "qwkk3584-0057-99de-900d-0018f32e506c",
            "artist" : "Joe Satriani",
            "album" : "",
            "track" : "Surfing with an alien",
            "source" : "rjhome",
            "size" : 12226688,
            "mimetype" : "audio/mpeg",
            "bitrate" : 213,
            "duration" : 459,
            "score" : 0.91
        },
        {
            "sid" : "oob636ec-0157-00de-910d-0018f32e506c",
            "artist" : "Joe Satriani",
            "album" : "",
            "track" : "Surfing with the Alien (live)",
            "source" : "rjhome",
            "size" : 7905443,
            "mimetype" : "audio/mpeg",
            "bitrate" : 190,
            "duration" : 331,
            "score" : 0.84
        }
    ]
}
This time query.solved is true, because an exact match was found on the machine 'rjlaptop'. Don't bother polling again, once a query is solved Playdar stops trying to find alternative sources.

So what actually happened?

When the search was started, the Local Library resolver immediately found 2 matches on my local machine (rjhome). The first check_results request lists those 2 matches.

Playdar recognized the query wasn't yet solved, because neither match was a perfect 1.0, so the query was dispatched to other resolver plugins.

In this case, my laptop (rjlaptop) was on the same wifi network, and received a UDP broadcast message. It found a match in its Local Library, and responded (it replied over UDP, actually by sending a JSON object). By the time check_results was called a second time, results from the Laptop had arrived, and the query was deemed to be solved.

Streaming the file you just found

To stream the result, you need the sid from the result object. You always receive the result by making an HTTP request to the Playdar service it came from. Playdar takes care of fetching and serving the file to you - it might be coming from your local disk, maybe over the network from your laptop, or something else entirely. Finding and accessing songs is all taken care of by induvidual resolver plugins. The important thing is you don't need to worry - it's just a local HTTP request using the sid from the result you want, which is almost always the result with the highest score.

/sid/ccf63584-0057-11de-900d-0018f32e506c

This will send the correct HTTP headers for mimetype and content-length, and appear like a traditional file download. These URLs can be passed directly to any media player and streamed, or to a flash swf provided it's flash compatible (ie, mp3).