Using the Zune Web API on Windows Phone 7
- Posted: Apr 07, 2011 at 11:48 AM
- 19,313 Views
- 6 Comments
Loading User Information from Channel 9
Something went wrong getting user information from Channel 9
Loading User Information from MSDN
Something went wrong getting user information from MSDN
Loading Visual Studio Achievements
Something went wrong getting the Visual Studio Achievements
Fair Warning: You’re stepping in the undocumented land right now. Microsoft offers no support whatsoever for any of the endpoints mentioned below. Microsoft can also change any of these at any time without prior modification, so plan accordingly.
I use Zune a lot, having started with the 4GB player, and now it’s available on Windows Phone 7. Though the WP7 player is labeled as Music Hub, it appears under the Zune icon and incorporates Zune's organization, providing many of the same capabilities as the desktop client.
For quite a while, two public Zune endpoints have given out some very basic data (profile information and recent plays):
Both endpoints return plain XML-formatted data, and the information is pretty basic:
It is worth mentioning that Zune play count isn’t updated automatically as songs are played on the phone — it needs to be connected to the desktop Zune client to update the count.
That’s pretty much it. Now let’s look at the default XML result returned by the endpoints I mentioned above.
(Click to enlarge image)
Notice that I highlighted the user ID. For some strange reason, the ID returned isn’t compatible with the API endpoints I am going to describe below, so obtaining it for future reference is not something to rely on.
The default endpoints don’t give much information about the songs that were played (metadata-wise) and there is no information at all about existing friends.
NOTE: If your Zune account is linked to Xbox Live, your Xbox Live friends will be placed in the Zune list.
After taking a close look with WireShark when Zune desktop client was downloading profile information, I noticed that Microsoft uses a set of additional endpoints and the Zune card that is created locally does not use either of the two public URLs to retrieve data.
What triggered my curiosity was the fact that a friend list downloaded:
(Click to enlarge image)
Note that there is also a GUID associated with the user. This identifier is a bit different from what is returned by the default calls. So, the structure for the profile info endpoint appears as this:
http://socialapi.zune.net/en-US/members/MEMBER_GUID
I am not entirely sure exactly where this ID comes from, but the returned XML is pretty similar to the initial one, though it is formatted as an Atom feed (which is unrecognizable by browsers as a native feed—developers have to actually download the text contents and parse it).
If the user GUID is not known, it is possible to pass the Zune Tag (as pointed out by RoguePlanetoid), but for some reason in several cases it will be problematic because of a random redirect to the authentication page.
Here is a snapshot of its contents:
(Click to enlarge image)
Here's the line that most interested me when I reviewed the code:
<a:link rel=”related” type=”application/atom+xml”
href=”http://socialapi.zune.net/en-US/members/509cd2cf-9400-4e4c-b3d8-07aa46ce464d/friends” title=”friends” />
There it was—the list of friends that is not available in the basic feeds. This feed is a valid Atom entity, and can therefore be opened in a browser. What surprised me is the fact that I don’t have to send any authentication data in order to view it, and it is nice to have it that way:
Going even further, the source of the page reveals some bonus details that are not displayed in the feed when it is rendered by a compatible web browser. Here is a snapshot:
This feed exposes the user GUIDs (and associated URLs) of my friends, so I can get profile information about them the same way I did it for me. Ultimately, you can search for friends of friends and so on to infinity (or, to be exact—to the extent of the Zune user base).
In my initial profile feed, there are links that represent recent songs. Though the basic feed only provides the names of tracks and the artist, by using the undocumented feed I can get some additional metadata associated with media content. Once again, the feed is viewable in a browser:
The necessary metadata is behind the curtain:
Additional available information includes play rank, disc number, track number, and an indicator that shows whether the song is explicit. Some songs, however, have more metadata than others.
Here is an example of an entity with more metadata associated with it:
(Click to enlarge image)
Notice that there are now song length details, the play rank is not empty, and there are actually disc and track numbers. Take a closer look at the rights tag—that’s where it’s possible to track current song offers on the Zune Marketplace, including the song encoding format (in this case 192kbps WMA), the type of purchase (Album), and the file size. For some offers also provide the price (which can be shown in both USD and Microsoft Points):
If a song is registered with enough additional metadata, the artist picture displays in the Zune window (if in play mode and not playlist) as the song plays.
Ultimately, this data significantly enhances my Zune experience on Windows Phone 7. I built a sample application that allows me to see my friends and generally keep up-to-date with my Zune stats.
(Click to enlarge an image)
To show a simple code snippet, here is how I am obtaining the data:
private void ParseXml(stringxmlDoc)
{
XDocument doc = XDocument.Parse(xmlDoc);
txtZuneName.Text = doc.Root.Element("{http://schemas.zune.net/profiles/2008/01}zunetag").Value.ToString();
txtRealName.Text = doc.Root.Element("{http://schemas.zune.net/profiles/2008/01}displayname").Value.ToString();
txtLocation.Text = doc.Root.Element("{http://schemas.zune.net/profiles/2008/01}location").Value.ToString();
txtPlayCount.Text = doc.Root.Element("{http://schemas.zune.net/profiles/2008/01}playcount").Value.ToString();
txtLastUpdate.Text = doc.Root.Element("{http://www.w3.org/2005/Atom}updated").Value.ToString();
XElement images = doc.Root.Element("{http://schemas.zune.net/profiles/2008/01}images");
profileLocation = (from c in images.Elements() where c.Attribute("title").Value == "usertile" select c).First().Attribute("href").Value.ToString();
backgroundLocation = (from c in images.Elements() where c.Attribute("title").Value == "background" select c).First().Attribute("href").Value.ToString();
XElement playlists = doc.Root.Element("{http://schemas.zune.net/profiles/2008/01}playlists");
recentPlaylist = (from c in playlists.Elements() where c.Attribute("title").Value == "BuiltIn-RecentTracks" select c).First().Attribute("href").Value.ToString();
mostPlayed = (from c in playlists.Elements() where c.Attribute("title").Value == "BuiltIn-MostPlayedArtists" select c).First().Attribute("href").Value.ToString();
}Notice that I am directly passing the namespace. There is a way around this when using a regular Atom feed formatter, but I decided to go the simpler, XML way.
I’d love to see these features integrated with the mobile Zune client on Windows Phone 7. But for now, I have my own application that shows me the information.
I am pretty sure that this is just the surface of the actual Zune API – there is much more to it, like message exchange, badge assignment depending on the songs played and so on. Some of the more complex parts are less accessible due to existing protection mechanisms – for example, sending messages isn’t done directly through HTTP but rather through TCP in an encrypted manner. I am still looking into that.
In the meantime, the complete implementation of the project can be found on the Zune Data Viewer page on CodePlex.
Comments have been closed since this content was published more than 30 days ago, but if you'd like to continue the conversation,
please create a new thread in our Forums,
or
Contact Us and let us know.
Follow the Discussion
Oops, something didn't work.
What does this mean?
Following an item on Channel 9 allows you to watch for new content and comments that you are interested in. You need to be signed in to Channel 9 to use this feature.What does this mean?
Following an item on Channel 9 allows you to watch for new content and comments that you are interested in and view them all on your notifications page.sign up for email notifications?
Hi, would you code an app that would force upload device (wp7) play counts of songs from the music+videos hub?
because play counts in my phone never uploads/updates whatever/however much i tried.
:(
Excellent article, thanks
@Jeffrey
Unfortunately, users cannot access the Zune hub by default, therefore there is no way I can integrate the play counter with that.
@IRB
Thanks!
i meant uploading to the ms servers so my zune social card play count moves forward.
Well since there is no hook to Zune itself (on the phone), there is no way you can send the play count from the phone. Also, as far as I know, the data about the playcount is not sent via the HTTP pipe, so you would need support for sockets.
opening thread.
Remove this comment
Remove this thread
close