Entries:
Comments:
Posts:

Loading User Information from Channel 9

Something went wrong getting user information from Channel 9

Latest Achievement:

Loading User Information from MSDN

Something went wrong getting user information from MSDN

Visual Studio Achievements

Latest Achievement:

Loading Visual Studio Achievements

Something went wrong getting the Visual Studio Achievements

Using the Zune Web API on Windows Phone 7

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.

Introduction

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.

Existing endpoints

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:

  • User ID
  • Name
  • Status
  • Big tile image
  • Small tile image
  • Location
  • Large background image
  • Small background image
  • Number of plays
  • Badges
  • Card destinations (e.g. share)
  • Playlists (with artist names and album art references)

 

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.

image

(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.

Discovering new endpoints

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:

image

(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:

image

(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” />

Getting data from custom endpoints

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:

image

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:

image

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:

image

The necessary metadata is behind the curtain:

image

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:

image

(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):

image

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.

dataviewerdataviewer2dataviewer4

dataviewer5dataviewer6

(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.

Conclusion

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.

Tags:

Follow the Discussion

  • Jeffrey SantosJeffrey Santos

    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.

    :(

  • IRBIRB

    Excellent article, thanks Smiley

  • Den DelimarskyDennisDel I ate a watermelon

    @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!

  • Jeffrey SantosJeffrey Santos

    i meant uploading to the ms servers so my zune social card play count moves forward.

  • Den DelimarskyDennisDel I ate a watermelon

    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.

  • Golnazgolnazal HEY HEY HEY

    opening thread.

Remove this comment

Remove this thread

close

Comments Closed

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.