Whamb Share Protocol Description Documentation
WHSP is a simple protocol to share music file over network between music player, for now only Whamb itself and WSD which is only a daemon implementing WHSP.
Whamb uses RendezVous from apple http://developer.apple.com/darwin/projects/rendezvous/ to automatically find other WHSP system on the local network subnet. WHSP uses a XML query/answer system based on Apple plist DTDs (http://www.apple.com/DTDs/PropertyList-1.0.dtd)
All line and with a \n, another \n should be added at the end of your query like in a HTTP request
There is 4 query type:
Query uses this format: COMMAND WHSP major_version.middle_version
- First query type is: “WINK WHSP 1.0\n\n”
This query is a hello and should be answred by:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <key>build</key> <string>Here is your app build number (AS STRING)</string> <key>playlists count</key> <integer>Here is the number of playlist you share (AS INTEGER)</integer> <key>user</key> <string>Here is the process user (could be fake for security, like 'WHSP') (AS STRING)</string> <key>version</key> <string>Here is your app version (AS STRING)</string> <key>computername</key> <string>Here is the computer Hostname (AS STRING)</string> </dict> </plist>
- Second query type is: “LIST WHSP 1.0\n\n”
This query list avalaible playlist and should be answred by:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>playlists</key> <array> <string>PLAYLIST_1_NAME</string> <string>PLAYLIST_2_NAME</string> <string>PLAYLIST_n_NAME</string> </array> </dict> </plist>
- Third query type is: “GET FILE_NAME_OR_FILE_ID_AS_UNICODE_STRING OFFSET_AS_INTGER WHSP 1.0\n\n”
This query should be answred by the file requested starting at the requested offset.
- fourth query type is: “PLAYLIST PLAYLIST_NAME_AS_UNICODE_STRING WHSP 1.0\n\n”
This query list the content of the playlist requested and should be answred by:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Version</key> <string>1.1</string> <key>Playlist</key> <array> HERE_IS_THE_FILE_LIST_SEE_BELLOW </array> </dict> </plist>
i will explain what should be listed for “HERE_IS_THE_FILE_LIST_SEE_BELLOW”, in it you list AUDIO_FILE_DESCRIPTION and FOLDER_DESCRIPTION .
an AUDIO_FILE_DESCRIPTION is defined with theses keys:
<dict> <key>Album</key> <string>THE_ALBUM_NAME</string> <key>Artist</key> <string>THE_ARTIST_NAME</string> <key>BitRate</key> <integer>THE_FILE_BITRATE</integer> <key>Current</key> <real>-1.0</real> <key>File Size</key> <integer>THE_FILE_SIZE</integer> <key>File Type</key> <string>FILE_TYPE_SEE_BELLOW</string> <key>Genre</key> <string>THE_GENRE</string> <key>Mod. Date</key> <date>LAST_MODIFICATION_TIME</date> <key>Path</key> <string>PATH_OR_ID_(SEE_BELLOW...)</string> <key>Time</key> <string>THE_MUSIC_TIME</string> <key>Time#</key> <integer>THE_MUSIC_TIME_IN_SECOND</integer> <key>Title</key> <string>THE_TITLE</string> <key>TrackCount</key> <integer>THE_NUMBER_OF_TRACK</integer> <key>TrackNum</key> <integer>THE_TRACK_NUMBER </integer> <key>Year</key> <string>THE_YEAR</string> <key>Year#</key> <integer>THE_YEAR_AS_INTEGER</integer> </dict>
FILE_TYPE can be : MP3F for a MP3 file, MP3S for a MP3 stream, OGGF for a ogg file, OGGS for a ogg stream
PATH_OR_ID this is used to make the GET request, it can be a real path (like Whamb uses) or an id (like WSD uses)
When you haven’t a value (if there is no Tag for example) use an empty string for string key and -1 for integer key
a FOLDER_DESCRIPTION is defined with theses keys:
<dict> <key>Name</key> <string>MY_BEST_MUSIC</string> <key>Open</key> <true/> <key>Path</key> <string>THE_FOLDER_PATH_(OPTIONAL)</string> <key>Sync</key> <true/> </dict>
Now let’s back to HERE_IS_THE_FILE_LIST_SEE_BELLOW, it should use this format:
AUDIO_FILE_DESCRIPTION_1
AUDIO_FILE_DESCRIPTION_2
AUDIO_FILE_DESCRIPTION_3<array>
FOLDER_DESCRIPTION_1
AUDIO_FILE_DESCRIPTION_4
AUDIO_FILE_DESCRIPTION_5
AUDIO_FILE_DESCRIPTION_6</array>
AUDIO_FILE_DESCRIPTION_7
AUDIO_FILE_DESCRIPTION_8<array>
FOLDER_DESCRIPTION_2
<array>FOLDER_DESCRIPTION_3 <– this a subfolder of FOLDER_DESCRIPTION_2
AUDIO_FILE_DESCRIPTION_9
AUDIO_FILE_DESCRIPTION_10
AUDIO_FILE_DESCRIPTION_11</array>
</array>
Ok now i will put a complet example, it describe a file named “Dionysos – Coccinelle” and a folder named “Daft Punk” in the “/” of the playlist, then into the “Daft Punk” folder there is a “Daft Punk – Around the World.mp3” file and a sub folder named “CD (one more time)” in this subfolder i have “Daft Punk 01.mp3” to “Daft Punk 14.mp3”
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Version</key> <string>1.1</string> <key>Playlist</key> <array> <array> <dict> <key>Name</key> <string>Daft Punk</string> <key>Open</key> <true/> <key>Path</key> <string>/Volumes/FW - Music & Video/MP3/Daft Punk</string> <key>Sync</key> <true/> </dict> <array> <dict> <key>Name</key> <string>CD (one more time)</string> <key>Open</key> <false/> <key>Path</key> <string>/Volumes/FW - Music & Video/MP3/Daft Punk/CD (one more time)</string> <key>Sync</key> <true/> </dict> <dict> <key>Album</key> <string></string> <key>Artist</key> <string></string> <key>BitRate</key> <integer>175</integer> <key>Current</key> <real>0.0</real> <key>File Size</key> <integer>7084887</integer> <key>File Type</key> <string>MP3F</string> <key>Genre</key> <string></string> <key>Mod. Date</key> <date>2002-07-23T16:16:46Z</date> <key>Path</key> <string>/Volumes/FW - Music & Video/MP3/Daft Punk/CD (one more time)/Daft Punk 01.mp3</string> <key>Time</key> <string>5:23</string> <key>Time#</key> <integer>323</integer> <key>Title</key> <string>Daft Punk 01.mp3</string> <key>TrackCount</key> <integer>0</integer> <key>TrackNum</key> <integer>0</integer> <key>Year</key> <string></string> <key>Year#</key> <integer>-1</integer> </dict> <dict> <key>Album</key> <string></string> <key>Artist</key> <string></string> <key>BitRate</key> <integer>169</integer> <key>Current</key> <real>-1</real> <key>File Size</key> <integer>4428386</integer> <key>File Type</key> <string>MP3F</string> <key>Genre</key> <string></string> <key>Mod. Date</key> <date>2002-07-23T16:14:48Z</date> <key>Path</key> <string>/Volumes/FW - Music & Video/MP3/Daft Punk/CD (one more time)/Daft Punk 02.mp3</string> <key>Time</key> <string>3:29</string> <key>Time#</key> <integer>209</integer> <key>Title</key> <string>Daft Punk 02.mp3</string> <key>TrackCount</key> <integer>0</integer> <key>TrackNum</key> <integer>0</integer> <key>Year</key> <string></string> <key>Year#</key> <integer>-1</integer> </dict> <dict> <key>Album</key> <string></string> <key>Artist</key> <string></string> <key>BitRate</key> <integer>192</integer> <key>Current</key> <real>-1</real> <key>File Size</key> <integer>7162702</integer> <key>File Type</key> <string>MP3F</string> <key>Genre</key> <string></string> <key>Mod. Date</key> <date>2002-07-23T16:14:56Z</date> <key>Path</key> <string>/Volumes/FW - Music & Video/MP3/Daft Punk/CD (one more time)/Daft Punk 03.mp3</string> <key>Time</key> <string>4:58</string> <key>Time#</key> <integer>298</integer> <key>Title</key> <string>Daft Punk 03.mp3</string> <key>TrackCount</key> <integer>0</integer> <key>TrackNum</key> <integer>0</integer> <key>Year</key> <string></string> <key>Year#</key> <integer>-1</integer> </dict> <dict> <key>Album</key> <string></string> <key>Artist</key> <string></string> <key>BitRate</key> <integer>170</integer> <key>Current</key> <real>-1</real> <key>File Size</key> <integer>4802110</integer> <key>File Type</key> <string>MP3F</string> <key>Genre</key> <string></string> <key>Mod. Date</key> <date>2002-07-23T16:15:01Z</date> <key>Path</key> <string>/Volumes/FW - Music & Video/MP3/Daft Punk/CD (one more time)/Daft Punk 04.mp3</string> <key>Time</key> <string>3:45</string> <key>Time#</key> <integer>225</integer> <key>Title</key> <string>Daft Punk 04.mp3</string> <key>TrackCount</key> <integer>0</integer> <key>TrackNum</key> <integer>0</integer> <key>Year</key> <string></string> <key>Year#</key> <integer>-1</integer> </dict> <dict> <key>Album</key> <string></string> <key>Artist</key> <string></string> <key>BitRate</key> <integer>194</integer> <key>Current</key> <real>-1</real> <key>File Size</key> <integer>5119446</integer> <key>File Type</key> <string>MP3F</string> <key>Genre</key> <string></string> <key>Mod. Date</key> <date>2002-07-23T16:15:06Z</date> <key>Path</key> <string>/Volumes/FW - Music & Video/MP3/Daft Punk/CD (one more time)/Daft Punk 05.mp3</string> <key>Time</key> <string>3:31</string> <key>Time#</key> <integer>211</integer> <key>Title</key> <string>Daft Punk 05.mp3</string> <key>TrackCount</key> <integer>0</integer> <key>TrackNum</key> <integer>0</integer> <key>Year</key> <string></string> <key>Year#</key> <integer>-1</integer> </dict> <dict> <key>Album</key> <string></string> <key>Artist</key> <string></string> <key>BitRate</key> <integer>170</integer> <key>Current</key> <real>-1</real> <key>File Size</key> <integer>2206165</integer> <key>File Type</key> <string>MP3F</string> <key>Genre</key> <string></string> <key>Mod. Date</key> <date>2002-07-23T16:15:09Z</date> <key>Path</key> <string>/Volumes/FW - Music & Video/MP3/Daft Punk/CD (one more time)/Daft Punk 06.mp3</string> <key>Time</key> <string>1:43</string> <key>Time#</key> <integer>103</integer> <key>Title</key> <string>Daft Punk 06.mp3</string> <key>TrackCount</key> <integer>0</integer> <key>TrackNum</key> <integer>0</integer> <key>Year</key> <string></string> <key>Year#</key> <integer>-1</integer> </dict> <dict> <key>Album</key> <string></string> <key>Artist</key> <string></string> <key>BitRate</key> <integer>194</integer> <key>Current</key> <real>-1</real> <key>File Size</key> <integer>5766452</integer> <key>File Type</key> <string>MP3F</string> <key>Genre</key> <string></string> <key>Mod. Date</key> <date>2002-07-23T16:15:15Z</date> <key>Path</key> <string>/Volumes/FW - Music & Video/MP3/Daft Punk/CD (one more time)/Daft Punk 07.mp3</string> <key>Time</key> <string>3:57</string> <key>Time#</key> <integer>237</integer> <key>Title</key> <string>Daft Punk 07.mp3</string> <key>TrackCount</key> <integer>0</integer> <key>TrackNum</key> <integer>0</integer> <key>Year</key> <string></string> <key>Year#</key> <integer>-1</integer> </dict> <dict> <key>Album</key> <string></string> <key>Artist</key> <string></string> <key>BitRate</key> <integer>199</integer> <key>Current</key> <real>-1</real> <key>File Size</key> <integer>4963280</integer> <key>File Type</key> <string>MP3F</string> <key>Genre</key> <string></string> <key>Mod. Date</key> <date>2002-07-23T16:15:20Z</date> <key>Path</key> <string>/Volumes/FW - Music & Video/MP3/Daft Punk/CD (one more time)/Daft Punk 08.mp3</string> <key>Time</key> <string>3:19</string> <key>Time#</key> <integer>199</integer> <key>Title</key> <string>Daft Punk 08.mp3</string> <key>TrackCount</key> <integer>0</integer> <key>TrackNum</key> <integer>0</integer> <key>Year</key> <string></string> <key>Year#</key> <integer>-1</integer> </dict> <dict> <key>Album</key> <string></string> <key>Artist</key> <string></string> <key>BitRate</key> <integer>174</integer> <key>Current</key> <real>-1</real> <key>File Size</key> <integer>4995810</integer> <key>File Type</key> <string>MP3F</string> <key>Genre</key> <string></string> <key>Mod. Date</key> <date>2002-07-23T16:15:35Z</date> <key>Path</key> <string>/Volumes/FW - Music & Video/MP3/Daft Punk/CD (one more time)/Daft Punk 09.mp3</string> <key>Time</key> <string>3:49</string> <key>Time#</key> <integer>229</integer> <key>Title</key> <string>Daft Punk 09.mp3</string> <key>TrackCount</key> <integer>0</integer> <key>TrackNum</key> <integer>0</integer> <key>Year</key> <string></string> <key>Year#</key> <integer>-1</integer> </dict> <dict> <key>Album</key> <string></string> <key>Artist</key> <string></string> <key>BitRate</key> <integer>183</integer> <key>Current</key> <real>-1</real> <key>File Size</key> <integer>5184286</integer> <key>File Type</key> <string>MP3F</string> <key>Genre</key> <string></string> <key>Mod. Date</key> <date>2002-07-23T16:15:41Z</date> <key>Path</key> <string>/Volumes/FW - Music & Video/MP3/Daft Punk/CD (one more time)/Daft Punk 10.mp3</string> <key>Time</key> <string>3:46</string> <key>Time#</key> <integer>226</integer> <key>Title</key> <string>Daft Punk 10.mp3</string> <key>TrackCount</key> <integer>0</integer> <key>TrackNum</key> <integer>0</integer> <key>Year</key> <string></string> <key>Year#</key> <integer>-1</integer> </dict> <dict> <key>Album</key> <string></string> <key>Artist</key> <string></string> <key>BitRate</key> <integer>151</integer> <key>Current</key> <real>-1</real> <key>File Size</key> <integer>6520957</integer> <key>File Type</key> <string>MP3F</string> <key>Genre</key> <string></string> <key>Mod. Date</key> <date>2002-07-23T16:15:48Z</date> <key>Path</key> <string>/Volumes/FW - Music & Video/MP3/Daft Punk/CD (one more time)/Daft Punk 11.mp3</string> <key>Time</key> <string>5:45</string> <key>Time#</key> <integer>345</integer> <key>Title</key> <string>Daft Punk 11.mp3</string> <key>TrackCount</key> <integer>0</integer> <key>TrackNum</key> <integer>0</integer> <key>Year</key> <string></string> <key>Year#</key> <integer>-1</integer> </dict> <dict> <key>Album</key> <string></string> <key>Artist</key> <string></string> <key>BitRate</key> <integer>154</integer> <key>Current</key> <real>-1</real> <key>File Size</key> <integer>3980038</integer> <key>File Type</key> <string>MP3F</string> <key>Genre</key> <string></string> <key>Mod. Date</key> <date>2002-07-23T16:15:53Z</date> <key>Path</key> <string>/Volumes/FW - Music & Video/MP3/Daft Punk/CD (one more time)/Daft Punk 12.mp3</string> <key>Time</key> <string>3:26</string> <key>Time#</key> <integer>206</integer> <key>Title</key> <string>Daft Punk 12.mp3</string> <key>TrackCount</key> <integer>0</integer> <key>TrackNum</key> <integer>0</integer> <key>Year</key> <string></string> <key>Year#</key> <integer>-1</integer> </dict> <dict> <key>Album</key> <string></string> <key>Artist</key> <string></string> <key>BitRate</key> <integer>177</integer> <key>Current</key> <real>-1</real> <key>File Size</key> <integer>5305451</integer> <key>File Type</key> <string>MP3F</string> <key>Genre</key> <string></string> <key>Mod. Date</key> <date>2002-07-23T16:15:59Z</date> <key>Path</key> <string>/Volumes/FW - Music & Video/MP3/Daft Punk/CD (one more time)/Daft Punk 13.mp3</string> <key>Time</key> <string>3:59</string> <key>Time#</key> <integer>239</integer> <key>Title</key> <string>Daft Punk 13.mp3</string> <key>TrackCount</key> <integer>0</integer> <key>TrackNum</key> <integer>0</integer> <key>Year</key> <string></string> <key>Year#</key> <integer>-1</integer> </dict> <dict> <key>Album</key> <string></string> <key>Artist</key> <string></string> <key>BitRate</key> <integer>184</integer> <key>Current</key> <real>-1</real> <key>File Size</key> <integer>13764466</integer> <key>File Type</key> <string>MP3F</string> <key>Genre</key> <string></string> <key>Mod. Date</key> <date>2002-07-23T16:16:14Z</date> <key>Path</key> <string>/Volumes/FW - Music & Video/MP3/Daft Punk/CD (one more time)/Daft Punk 14.mp3</string> <key>Time</key> <string>9:58</string> <key>Time#</key> <integer>598</integer> <key>Title</key> <string>Daft Punk 14.mp3</string> <key>TrackCount</key> <integer>0</integer> <key>TrackNum</key> <integer>0</integer> <key>Year</key> <string></string> <key>Year#</key> <integer>-1</integer> </dict> </array> <dict> <key>Album</key> <string>Da Funk</string> <key>Artist</key> <string>Daft Punk</string> <key>BitRate</key> <integer>112</integer> <key>Current</key> <real>-1</real> <key>File Size</key> <integer>5978112</integer> <key>File Type</key> <string>MP3F</string> <key>Genre</key> <string></string> <key>Mod. Date</key> <date>2002-04-07T22:14:28Z</date> <key>Path</key> <string>/Volumes/FW - Music & Video/MP3/Daft Punk/Daft Punk - Around the World.mp3</string> <key>Time</key> <string>7:07</string> <key>Time#</key> <integer>427</integer> <key>Title</key> <string>Around the World</string> <key>TrackCount</key> <integer>2</integer> <key>TrackNum</key> <integer>2</integer> <key>Year</key> <string>1998</string> <key>Year#</key> <integer>1998</integer> </dict> </array> <dict> <key>Album</key> <string></string> <key>Artist</key> <string>Dionysos</string> <key>BitRate</key> <integer>128</integer> <key>Current</key> <real>-1</real> <key>File Size</key> <integer>3518508</integer> <key>File Type</key> <string>MP3F</string> <key>Genre</key> <string></string> <key>Mod. Date</key> <date>2001-11-24T18:04:33Z</date> <key>Path</key> <string>/Volumes/FW - Music & Video/MP3/Dionysos - Coccinelle</string> <key>Time</key> <string>3:39</string> <key>Time#</key> <integer>219</integer> <key>Title</key> <string>Coccinelle</string> <key>TrackCount</key> <integer>0</integer> <key>TrackNum</key> <integer>0</integer> <key>Year</key> <string></string> <key>Year#</key> <integer>-1</integer> </dict> </array> </dict> </plist>
Ok it’s long and not easy to read, here is a short resume:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Version</key> <string>1.1</string> <key>Playlist</key> <array> <array> <dict> Daft Punk folder info </dict> <array> <dict> CD (one more time) folder info </dict> <dict> Daft Punk 01.mp3 info </dict> <dict> Daft Punk 02.mp3 info </dict> <dict> Daft Punk 04.mp3 info </dict> <dict> Daft Punk 05.mp3 info </dict> <dict> Daft Punk 06.mp3 info </dict> <dict> Daft Punk 07.mp3 info </dict> <dict> Daft Punk 08.mp3 info </dict> <dict> Daft Punk 09.mp3 info </dict> <dict> Daft Punk 10.mp3 info </dict> <dict> Daft Punk 11.mp3 info </dict> <dict> Daft Punk 12.mp3 info </dict> <dict> Daft Punk 13.mp3 info </dict> <dict> Daft Punk 14.mp3 info </dict> </array> <dict> Daft Punk - Around the World.mp3 info </dict> </array> <dict> Dionysos - Coccinelle info </dict> </array> </dict> </plist>
Ok That all, if you have any question or if you write a software that uses WHSP write me 🙂
Recent Comments