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