Использование веб-API Zune на платформе Windows Phone 7
Денис Делимарский (Dennis Delimarsky)
Предупреждение. Данная предметная область не документирована. Microsoft не поддерживает конечные точки, упомянутые в этой публикации. Microsoft может в любое время изменить любую из этих конечных точек без предварительного уведомления, поэтому учитывайте это в своей работе.
Введение
Я много использую Zune, начиная с 4 Гб-плеера, а теперь Zune доступен и на платформе Windows Phone 7. И хотя плеер WP7 поддерживает Music Hub, он имеет эмблему Zune и обеспечивает многие из возможностей Zune для настольных клиентов.
Существующие конечные точки
В течение довольно долгого времени две общедоступные (public) конечные точки Zune позволяли получать только самые базовые данные (сведения профиля и недавно прослушанные записи):
- https://social.zune.net/zcard/usercardservice.ashx?zunetag=TAG
- https://origin-social.zune.net/zcard/usercardservice.ashx?zunetag=TAG
Обе конечные точки возвращали данные в обычном формате XML, и предоставляемые ими сведения носили весьма скромный характер:
- Идентификатор пользователя.
- Имя.
- Статус.
- Изображение Big tile.
- Изображение Small tile.
- Местоположение.
- Большое фоновое изображение.
- Маленькое фоновое изображение.
- Количество воспроизведений.
- Значки.
- Назначение карты (например, совместное использование).
- Списки воспроизведения (с именами исполнителей и обложками альбомов).
Нужно отметить, что счетчик воспроизведения Zune не обновляется автоматически при проигрывании записей на телефоне – для обновления счетчика его необходимо подключить к настольному клиенту Zune.
Вот, в общем-то, и все. Теперь посмотрим на результат в формате XML по умолчанию, возвращаемый упомянутыми конечными точками.
Обратите внимание, что я выделил идентификатор пользователя. По какой-то непонятной причине возвращаемый идентификатор не совместим с конечными точками API, речь о которых пойдет ниже, поэтому его получение для использования в будущем не является сколь-нибудь надежным.
Стандартные конечные точки не позволяют получить полную информацию о том, какие записи были воспроизведены (не учитывают метаданные) и не предоставляют абсолютно никакой информации об имеющихся друзьях.
ПРИМЕЧАНИЕ. Если ваша учетная запись Zune имеет привязку к Xbox Live, ваши друзья в Xbox Live будут отображаться в списке Zune.
Обнаружение новых конечных точек
Запустив WireShark, в то время как настольный клиент Zune загружает сведения профиля, и тщательно проанализировав результаты, я заметил, что Microsoft использует ряд дополнительных конечных точек, а карта Zune, создаваемая локально, не использует для извлечения данных ни один из двух общедоступных URL-адресов.
Меня особенно заинтересовала загрузка списка друзей:
Обратите внимание, что с пользователем ассоциируется GUID. Этот идентификатор немного отличается от того, который возвращают стандартные вызовы. Поэтому структура сведений профиля в конечной точке имеет следующий вид:
https://socialapi.zune.net/en-US/members/MEMBER_GUID
Не совсем ясно, откуда берется этот идентификатор, но возвращаемый XML сильно похож на исходный, хотя он отформатирован как веб-канал Atom (который не воспринимается браузерами как собственный канал, поэтому разработчикам приходится загружать текстовое содержимое и анализировать его).
Если GUID пользователя не известен, можно передать Zune Tag (как отмечает RoguePlanetoid), но в некоторых случаях это проблематично из-за случайного перенаправления на страницу проверки подлинности.
Вот снимок экрана с его содержимым:
При изучении кода меня больше всего заинтересовала следующая строка:
<a:link rel=”related” type=”application/atom+xml”
href=”https://socialapi.zune.net/en-US/members/509cd2cf-9400-4e4c-b3d8-07aa46ce464d/friends” title=”friends” />
Получение данных из настраиваемых конечных точек
И вот он – список друзей, не доступный в базовых каналах. Этот канал представляет собой корректный канал Atom, который может быть открыт в браузере. Меня удивило то, что для его просмотра мне не пришлось вводить свои данные для проверки подлинности, и это очень удобно.
Идем дальше: исходный код страницы содержит дополнительную информацию, которая не отображается в канале при его открытии совместимым веб-браузером. Снимок экрана приведен ниже.
В этом канале отображаются GUID (и соответствующие URL) моих друзей, таким образом я могу получить их сведения профиля так же, как и свои. Кроме того, можно выполнять поиск друзей вплоть до ограничений базы пользователей Zune.
В моем исходном канале профиля есть ссылки на недавно воспроизведенные композиции. Хотя базовый канал предоставлял только сведения об именах исполнителей и названиях композиций, используя недокументированный канал, я смог получить дополнительные метаданные, связанные с медиаконтентом. И этот канал можно просмотреть в браузере.
Нужные метаданные скрыты за кулисами:
Дополнительная доступная информация включает рейтинг воспроизведения, номер диска, номер композиции и индикатор того, является ли эта композиция явной (explicit). Для некоторых композиций указывается больше метаданных, чем для других.
Ниже приведен пример записи с большим объемом метаданных:
Обратите внимание на то, что теперь появились сведения о продолжительности композиции, рейтинг воспроизведения не пустой, а также указываются номера дисков и записи. Взгляните внимательнее на тег rights – здесь можно ознакомиться с текущим предложением этой композиции на Zune Marketplace, включая формат кодировки композиции (в данном случае WMA 192 Кбит/с), тип покупки (Album) и размер файла. Для некоторых предложений также указывается цена (в долл. США и баллах Microsoft Points):
Если композиция зарегистрирована с достаточным объемом метаданных, то во время ее воспроизведения в окне Zune можно увидеть фото исполнителя (в режиме воспроизведения, а не списка воспроизведения).
В конечном счете, эти данные существенно расширяют мои возможности работы с Zune на платформе Windows Phone 7. Я создал пример приложения, которое позволяет просматривать список моих друзей и общую статистику Zune.
Ниже приведен фрагмент кода, демонстрирующий то, как я получаю данные:
private void ParseXml(stringxmlDoc)
{
XDocument doc = XDocument.Parse(xmlDoc);
txtZuneName.Text = doc.Root.Element("{https://schemas.zune.net/profiles/2008/01}zunetag").Value.ToString();
txtRealName.Text = doc.Root.Element("{https://schemas.zune.net/profiles/2008/01}displayname").Value.ToString();
txtLocation.Text = doc.Root.Element("{https://schemas.zune.net/profiles/2008/01}location").Value.ToString();
txtPlayCount.Text = doc.Root.Element("{https://schemas.zune.net/profiles/2008/01}playcount").Value.ToString();
txtLastUpdate.Text = doc.Root.Element("{https://www.w3.org/2005/Atom}updated").Value.ToString();
XElement images = doc.Root.Element("{https://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("{https://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();
}
Обратите внимание, что я напрямую передаю пространство имен. Этого можно избежать, используя стандартный модуль форматирования канала Atom, но я решил упростить задачу и выбрал формат XML.
Хотелось бы, чтобы эти возможности были интегрированы в мобильный клиент Zune на платформе Windows Phone 7. А сейчас у меня есть собственное приложение, которое позволяет мне просматривать эту информацию.
Заключение
Я уверен в том, что это лишь поверхностные возможности Zune API, который также позволяет обмениваться сообщениями, присваивать значки при воспроизведении различных композиций и многое другое. Доступ к некоторым более сложным функциям затруднен из-за существующих механизмов защиты, например, сообщения отправляются не напрямую через HTTP, а через TCP в зашифрованном виде. Но над этим я работаю.
А пока вы можете ознакомиться с подробностями этого проекта на странице Zune Data Viewer в CodePlex.