Хабрахабр

Apple Music для разработчика

Вводные слова

На рынке много стриминговых сервисов, но предоставляющих полноценный SDK для стриминга в сторонних продуктах крайне мало, для российского рынка список официально доступных SDK ограничивается Deezer и Apple Music. Как бы ни ругали Apple за закрытость платформы и самой экосистемы, некоторые их решения являются исключением. Конечно, когда на наш рынок придёт Spotify, на один доступный SDK станет больше, но пока есть два игрока и только один из них имеет широкую пользовательскую базу.

И главное отличие от опыта с Deezer состоит в том, что MusicKit — это верхушка айсберга, она же публично доступный API. Так получилось, что я имел опыт работы с Deezer SDK под Android и прямо сейчас активно работаю с SDK Apple Music (MusicKit) под iOS. Даже если Apple использует MusicKit в своих решениях, то кроме него она использует ещё массу недокументированных API запросов и приватных API, которые простым смертным использовать запрещено. В отличие от Deezer, где повторить большую часть функциональности официального приложения — это просто длительный процесс, повторить функциональность даже веб-страницы Apple Music, используя только публичный API, невозможно.

Забегая вперёд скажу, что многое из рассказанного будет справедливо и для работы с Apple Music в Android и Javascript. В статье я расскажу про работу с MusicKit с точки зрения разработчика в контексте реализации достаточно "простых задач": поискать в каталоге, показать картинки в результатах поиска, получить песни, рекомендации и даже проиграть какую-то музыку.

Если понадобится, готов дать детальные ответы с кодом на вопросы в комментариях.

Отделим мух от котлет

При работе с MusicKit под iOS придётся взаимодействовать со следующими сущностями:

  • StoreKit для авторизации в Apple Music и предложения подписки на сервис (реферальной, если получится подписаться на Affiliate программу)
  • HTTP API для поиска и получения различной информации из каталога
  • iTunes Search API для поиска в каталоге iTunes (очень полезная альтернатива HTTP API). Apple обозначает лимит на максимум 20 запросов в минуту, этого чаще всего достаточно при осуществлении запросов с устройств пользователей
  • Media Player для проигрывания и управления очередью

Так же при подключении к Affiliate программе можно запросить доступ к дампу метаданных Enterprise Partner Feed, который Apple советует использовать вместо частых запросов к iTunes Search API.

И, на всякий случай, Music.app — это приложение "Музыка" на iOS устройствах, которое является официальным плеером Apple Music.

Источники сведений, в порядке убывания их полезности:

  • Официальная документация
  • Поиск по всей документации Apple
  • Метод научного эксперимента 1 с HTTP API
  • Developer Console в любимом браузере, натравленная на веб-страницу интересующей сущности в Apple Music
  • Форумы разработчиков на сайте Apple
  • StackOverflow

Поиск. Картинки

Вот возьмём, например, поиск. Самым очевидным способом проверить можно ли что-то сделать в своём приложении является факт того, что что-то подобное имеется в официальном приложении. Ищем группу "The Police" и имеем в выдаче Music.app фотографию группы с улыбающимся Стингом:

police search

В выдаче имеем ключ artwork с вложенной ссылкой url для всего, кроме артистов. Прекрасно, воспользуемся API поиска. Проверяем ещё раз, в Music.app всё есть. Странно. Более того, в веб-интерфейсе фотография тоже есть, а ссылка на веб-страницу имеется в json-выдаче API поиска.

iTunes Search API картинку так же не отдаёт, но так же включает в выдачу адрес веб-странице по ключу artistLinkUrl.

Ну что поделать, придётся скачивать web-страницу и доставать из неё адрес картинки, благо разработчики позаботились и прописали адрес картинки в мета-информацию:

<meta property="og:image" content="https://is5-ssl.mzstatic.com/image/thumb/Features113/v4/bb/a2/66/bba266dd-570b-bff7-d7c6-777982582964/mzl.tdrwskof.jpg/1200x630cw.png" id="ember52310559" class="ember-view">

Фактически, так делают все сторонние приложения за исключением тех, что ищут картинки с использованием сторонних сервисов. Формально говоря, мы уже нарушили правила Apple, которые запрещают "scraping" их веб-страниц.

Для приложения и без того гоняющего большие объёмы данных (проигрывающего музыку), терпимо (особенно при учёте, что данные передаются в сжатом виде), но в общем случае не очень. Есть и ещё один минус: мы запрашиваем страницу размером в несколько сотен килобайт.

Если хочется получить закруглённую картинку, то нужно добавить cw перед расширением. Размеры картинок можно подгонять под свои нужды: в url имеются шаблоны для замены (, {h}), а на веб-странице ссылка на картинку имеет тот же формат, так что сложностей получить картинку нужного размера нет.

Бонус про картинки для отображения в плеере

Очень удобно для отображения картинки трека в плеере. Во время проигрывания плеер из Media Player оперирует конструкцией MPMediaItem, которая, в частности, предоставляет объект Artwork. Проблема лишь в том, что на практике данный объект, как его ни крути, не даёт картинки для "стримящейся" музыки (а это любая музыка из Apple Music), поэтому приходится "матчить" проигрываемый MPMediaItem c песнями, которые добавлялись в очередь и скачивать изображение аналогично альбомам.

Поиск по жанрам

Найти жанр не должно составить труда, ведь мы можем искать по всему чему угодно? В iTunes и приложении Apple Music имеются списки жанров и топы песен в оных.

API не даёт искать по жанрам и не даёт списка жанров. Это далеко не так. Есть возможность запросить информацию (из полезного — название) жанра по его идентификатору,
но большая часть сведений в API содержит как раз имя жанра, а не идентификатор.

Идентификаторы жанров (как и прочие идентификаторы из iTunes) полностью соответствуют идентификаторам в Apple Music. Благо для iTunes предоставляется выгрузка всех жанров (совсем всех, включая "жанры" мобильных приложений). Структура жанров иерархична и имеются повторения названий жанров. Выгрузка доступна для всех регионов (регион указывается в ключе cc, а не storefront как в Apple Music API), но фактически отличаются лишь названия (они переведены).

Не сложно, но и не так просто, как попросить API поиска искать по жанрам. В общем, поиск по жанрам необходимо делать локально, причём учитывать, что "фанк джаз", "джаз-фанк" и "jazz funk" — это одно и тоже.

Для редких жанров вполне можно получить в выдаче всего 3 песни. Найдя жанр, можно запросить чарт (список самых популярных песен) для данного жанра.

Если хочется делать рекомендации на базе жанров, то данный жанр стоит игнорировать. Забавный факт: для некоторых альбомов и артистов (Ed Sheeran из известных) в качестве одного из жанров указывается просто верхнеуровневый жанр "Музыка".

Песни артистов

Apple Music даёт возможность запросить песни как связь типа "songs" 2 для артиста. Когда приложению необходимо проиграть песни артиста (музыкальной группы) чаще всего это означает, что необходимо проиграть популярные песни данной группы. На выходе имеем максимум 20 песен 3, явно отсортированных по популярности.

С очень популярными группами пройдёт вариант получения плейлистов, типа "[Artist Name]: главное" ("[Artist Name] Essentials") и "[Artist Name]: в деталях" ("[Artist Name]: Next Steps"), но в общем случае такой вариант не подходит. Иногда всё же хочется получить чуть больше композиций. Другой вариант: взять 20 популярных песен, а остальное добить из альбомов, благо Apple Music даёт возможность получить сразу все альбомы артиста (связи типа albums) и все песни в них (include="tracks") за один запрос.

К сожалению, API информации о популярности не предоставляет 4. Но если получить все песни артиста, то возникает другая проблема: необходимо из всех этих песен отобрать популярные. Брать случайные песни из всего списка можно, но на практике такой подход приводит к частому проигрыванию совсем неинтересных записей (проходных лайвов, записей репетиций, скитов и прочего), что особо заметно на очень популярных группах 5.

Ещё до появления MusicKit компания Apple начала предоставлять API поиска в iTunes Store. Попробуем получить популярные песни другим образом. Данный API возвращает по умолчанию 50 песен, но допустимо запросить до 200 песен. Как уже говорилось, каталог в Apple Music и iTunes Store одинаков 6 и, соответственно, идентификаторы песен тоже одинаковы. Результаты в выдаче так же отсортированы по популярности.

Они используют недокументированный (читай, приватный) API 7, в выдаче которого есть всё то, чего не хватает, включая идентификатор (а не только название) жанра и индекс популярности. Интересно, что сама компания Apple не использует ни один из этих вариантов в собственном веб-интерфейсе. Использовать данный API на практике я не решился 8, поскольку идентификаторы жанров можно получить обратным поиском по именам жанров 9, а численный индекс популярности не так уж и важен, когда получаешь отсортированный по популярности список композиций.

В частности, различные компиляции из комедийных шоу и стэндапы. Забавный факт, который я называю "проблемой Хью Лори" заключается в том, что в каталоге Apple Music имеется масса немузыкального контента. Соответственно, когда контекст работы приложения прямо говорит о том, что пользователь хочет слушать музыку, приходится самостоятельно убирать из полученного списка "песен" те, чьи жанры обозначены как "spoken word" и "comedy". Это с одной стороны прекрасно (мы платили за музыку, а получили ещё и смешные диалоги со Стивеном Фраем, которые можно послушать перед сном), а с другой приводит к прослушиванию какой-то болтовни, когда просил включить музыку.

Рекомендации

Условно рекомендации можно разделить на два вида 10: для пользователя (на базе истории прослушивания, покупок и лайков) и для музыкального объекта (артиста, трека, реже альбома и плейлиста). Проигрывание рекомендаций (они же "похожие песни", "радиостанции", "вам понравится" и т.д.) стало базовой функциональностью стриминговых плееров.

Из альбомов список песен можно получить, используя API запроса треков (связь tracks), для плейлистов аналогично. С предпочтениями пользователя в Apple Music формально 11 всё в порядке: можно запросить список персональных рекомендаций, в который включаются "персональные миксы" (плейлисты) и рекомендуемые альбомы. Следует учитывать, что треки могут включать не только песни (type = "songs"), но и видео-клипы, потому дополнительная фильтрация полученных данных не повредит.

Если посмотреть в Music.app, то там отображаются "похожие артисты" и можно включить "радиостанцию" для данного артиста. С другими же рекомендациями всё чуть сложнее. Последняя проигрывает микс из артиста и рекомендаций к нему.

police similar

Спешу расстроить, такой связи нет. Кажется, всё просто: наверняка для артистов есть связь "похожие артисты". В схеме данных Enterprise Partner Feed сведения о похожести так же отсутствуют.

И снова нет, радиостанцию запросить мы действительно можем, её идентификатор находится в выдаче связей артиста. Хорошо, значит мы можем запросить "радиостанцию" для артиста и получить список песен? Идея с playParams простая: скармливаем данный словарь 12 в очередь проигрывания и слушаем. Но в сведениях о станции нет сведений о проигрываемых песнях, альбомах или артистах, есть только служебный объект с информацией для проигрывания playParams.

Очевидно, мы каким-то образом должны получить список похожих артистов. Это всё хорошо, если хочется играть только радиостанцию (как делает Music.app), но что если хочется смешать песни из радиостанции 13 с чем-то ещё?

Очередь позволяет: вставить дескрипторы после определённого проигрываемого объекта, удалить указанные объекты, а так же получить список всеъ объектов в очереди. В Media Player важную роль играют очереди проигрывания, в частности MPMusicPlayerControllerMutableQueue. А MPMediaItem, в частности включает идентификатор песни. При запросе объектов на выходе мы должны получить массив из MPMediaItem. Вот есть только одна проблема: конструкторы очередей не являются публичным API, переведу: Media Player может дать готовую очередь (иногда редактируемую), а самому создать её невозможно 14.

Если Media Player может дать мне изменяемую очередь, то её нужно взять. Хорошо, немного копнуть в сторону костылестроения может быть полезно. Изменяем текущую очередь проигрывания (добавляем дескриптор станции), смотрим что получилось, откатываем измения в очереди новой транзакцией (удаляем то, что фактически добавилось в очередь). Для этого придётся работать с текущим (синглтон) плеером, так что действовать нужно быстро, иначе пользователю может проиграться что-то не то, а плеер успеет ещё и предзагрузить ненужные пока песни.

Оба выглядят как песни (есть имя артиста, название трека, длина трека), но не включают идентификатор песни. К сожалению обнаруживаем добавление только двух объектов MPMediaItem в очередь. При переходе к следующей песне очередь обновляется. Если посмотреть в Music.app, то обнаружим, что там всё сходится: включив радиостанцию будет проигрываться песня, а в очереди будет только одна песня к проигрыванию.

Дальше пытаться строить костыли с радиостанциями смысла нет, приходится использовать другие варианты.

Похожие артисты доступны только для самых популярных групп 15. Вспомним, что, в Music.app и веб-интерфейсе отображаются похожие артисты. Из плюсов: мы уже скачиваем веб-страницу для получения картинки, значит мы можем получить из неё сразу и похожих артистов. Опять приходится прибегать к запрещённому приёму парсинга веб-страницы.

В коде html странице видим большой json-объект, из которого забираем сначала идентификаторы похожих артистов (["data"]["relationships"]["artistContemporaries"]):

web page data

а потом по этим идентификаторам получаем данные артистов из того же json (["included"] с типом lockup/artist):

web page included

API позволяет запросить несколько артистов по их идентификаторам за один запрос с включёнными связями. Имея идентификаторы артистов мы можем запросить их треки. Так можно делать только при запросе артистов по одному или при прямом запросе песен для отдельно взятого артиста. Увы, на практике API возвращает ошибку, сообщающую о невозможности добавления списка треков к результату. В этом случае можно воспользоваться уже упомянутым iTunes Search API, который отдаст чуть больше полезной информации.

В ситуации пустого списка рекомендаций приходится использовать сторонние сервисы. Списки "похожих артистов" в Apple Music достаточно хороши, однако на практике часто оказываются пустыми. Результаты обоих нужно матчить с объектами в каталоге Apple Music. Классика — Last.fm, чуть изощерённее — Spotify. Решения чуть интереснее, но накладнее состоят в использовании musicbrainz для матчинга. Решение "в лоб" заключается в поиске каждого артиста по имени с получением ровно одного результата с последующим получением песен как описано выше. можно связать идентификатор в Spotify с идентификатором в Apple Music. Musicbrainz предоставляет информацию о идентификаторах 16 в других сервисах, т.е. Накладность заключается в лимитах на использование musicbrainz, при большом трафике придётся поднимать собственный клон musicbrainz (благо, это возможно) или разрабатывать собственный API вокруг базы данных, дампы которой можно спокойно скачать. В ситуации с Last.fm всё ещё лучше: Last.fm возвращает в списке рекомендаций идентификаторы из musicbrainz.

Берём жанры артиста (на базе названия получаем идентификаторы из уже загруженного списка всех жанров), получаем для каждого жанра по чарту, смешиваем полученные песни. Для новых групп даже Last.fm не даст рекомендаций, запасным вариантом будут "жанровые" рекомендации. Это лучше, чем ничего.

Две вещи неразлучные: плеер и очередь

Фреймворк высокоуровневый и в ситуации работы со стриминговым контентом спуститься на уровень ниже 18 не получится. За проигрывание в iOS из Apple Music отвечает Media Player, он позволяет работать с музыкой из Apple Music и персональным каталогом пользователя 17.

Использовать первый для чего-то серьёзного бессмысленно 19. Фреймворк предоставляет два плеера с общим программным интерфейсом: один играет музыку непосредственно в приложении Music.app, а другой работает более-менее независимо. А документация нагло лжёт 20, что второй плеер не работает в фоновом режиме

С архитектурной стороны работать с этим делом просто: говорим плееру что играть (например, заполняя очередь, на основе массива идентификаторов песен) и управляем проигрыванием (играть, пауза, следующий, предыдущий).

При этом достаточно часто обработчик completionHandler вызывается с ошибкой-таймаутом, которая переводится как "я не знаю смог ли я что-то сделать или делаю я ли ещё что-то, но мне надоело самого себя ждать". Прямого управления очередью проигрывания нет, нужно выполнять транзакционное изменение, которое занимает время. Часть изменений можно вносить и чуть более высокоуровнего, однако если уже пришлось использовать транзакционные изменения, то лучше использовать их для всего. Чаще всего транзакция проходит нормально, а ошибки, приходящие в обработчик приходится игнорировать.

Вообще очереди достаточно гибкие и, если нет вероятности, что ваше приложение будет когда-то работать и с другими стриминговыми сервисами 21, то с очередями можно делать много интересного, в частности указывать в какое время какой элемент начинает играть и как долго.

Нажатие пользователя на гарнитуре кнопки "следующий трек" не приведёт к запросу программы "что мне делать", плеер лучше знает что делать и сам переключит песню. Из других "минусов" такого высокоуровнего подхода стоит отметить невозможность обработки действий пользователя. Так что можно только отлавливать фактически свершившиеся изменения в состоянии плеера и принимать какие-то решения постфактум.

С другой стороны, много всего делать не нужно: информация о проигрывании на экране блокировки просто есть и все кнопки в ней работают, Apple Watch и Siri умеют управлять проигрыванием, а стриминг через AirPlay на Apple TV работает из коробки 22.

Повторить функциональность и интерфейс очереди Music.app в своём приложении возможно, но кажущаяся простота drag'n'drop-а элементов очереди на деле оказывается жонглированием транзакциями изменения очереди и синхронизацией желаемой очереди и реальной очереди 23 плеера.

Пара слов про SDK для других платформ

Фактически, работа с API ничем не отличается на других платформах, а вот SDK сделаны не совсем под копирку с iOS и, местами, более удобны 24, хотя общая идея тандема очереди и плеера сохраняется.

Так, под Android можно получить актуальную очередь и двигать элементы очереди без ухищрений с транзакционным изменением оной (удаления из очереди и добавления в нужное место, скрестив пальцы).

Работа с очередью и плеером не удобнее iOS SDK, но с небольшими надстройками может стать терпимой . MusicKit JS же предоставляет специальные методы-обёртки для работы с API Apple Music,
но при использовании обёрток без чтения документации по самому API не обойтись.

Пара слов о симуляторе

Проигрывать музыку из Apple Music в симуляторе вовсе невозможно, ибо отсутствует приложение Music.app. Работать в симуляторе с MusicKit можно только в разрезе общения с HTTP API, но даже в этом случае придётся стабить токен пользователя для проведения запросов, а не получать его через StoreKit.

Фактически, при разработке симулятор оказывается полезен только для работы над пользовательским интерфейсом. На деле приходится разрабатывать собственные надстройки над SDK и при запуске в симуляторе использовать альтернативные (mock) реализации. Собственная абстракция будет полезна и при автоматизированном создании скриншотов для приложения (да и вообще при создании скриншотов с помощью симулятора), поскольку иметь в арсенале оба поколения "больших" iPad Pro только для того, чтобы сделать на обоих скриншоты своего плеера, крайне накладно и глупо.

В качестве интересного, но не очень полезного, эксперимента можно сделать альтернативную реализацию собственного высокоуровневого плеера на базе MusicKit JS.

Про Enterprise Partner Feed

С другой стороны, мы имеем явную проблему курицы и яйца: доступ к Affiliate программе предоставляется при указании ссылки на приложение. С одной стороны Apple предоставляет по запросу дамп метаданных и говорит использовать его, дабы снизить нагрузку на API и получить сведения, которых в API нет. Достаточно сложно разрабатывать приложение, используя данные, которые можно получить, только имея опубликованное в App Store приложение.

Каждое заявление проверяют в течение пяти рабочих дней. И, конечно, данные не дают первому встречному. Apple завернуло моё заявление, не указав точных причин. На момент написания данной статьи получить дамп метаданных в свои руки мне так и не удалось. Или они где-то увидели, что я использую сведения с веб-страниц, хотя при проверке приложения это проблем не вызывало. Скорее всего, на промо-сайте приложения они увидели словосочетание "Apple Music" без упоминания о том, что я к Apple не имею отношения. Конечно, попытки мои не закончились и сама Apple поощряет повторную подачу заявления, но факт в том, что дампа на руках нет.

Разрабатывать свой бэкенд и отправлять все запросы из приложения к нему вместо Apple Music не только затратно (как с точки зрения времени на разработку, так и на финансирование инфраструктуры серверной части), но и имеет скрытые проблемы. Можно пофантазировать и даже сделать тестовую базу, поскольку секрета из схемы данных никто не делает, однако само наличие дампа на руках жизнь не упростит. Как участнику одного из музыкальных коллективов мне бы хотелось, чтобы свежий релиз появился сразу везде, а не только в официальных приложениях. Так, фид обновляется раз в неделю, а новая музыка в Apple Music появляется ежедневно.

Вообще использование Enterprise Partner Feed видится полезным в следующих случаях:

  • большое количество активных пользователей и проявление ограничений со стороны Apple Music API или iTunes Search API
  • необходимо обработать большой объём данных ("пережувать данные"), чтобы предоставить какую-то интересную функциональность
  • есть много денег и много свободного времени

Очевидные советы

Приведу несколько банальных советов, которые кому-то могут пригодиться:

  1. Кешируйте по максимуму. Жанры можно кешировать на годы, песни на недели, а результаты поиска на дни. Картинки можно
    так же кешировать на годы, если они есть. В ситуации картинок крайне рекомендую кешировать факт их отсутствия, дабы не запрашивать веб-страницу вновь в ложной надежде
  2. Экспериментируйте в дебаг-режиме на устройстве, но не забывайте, что дебаг может неочевидным образом изменять поведение программы и замедлять её работу. Скажем, получить таймаут при изменении очереди в дебаг-режиме крайне просто, даже если просто автоматически выводишь информацию в консоль без фактической остановки на дебаг-точке.
  3. Учитывайте, что SDK покрывает самые очевидные и простые сценарии в настоящий момент, в остальных ситуациях нужно подключать смекалку. Поскольку Apple 25 делает медиа SDK максимально стабильными и расширяемыми 26, ожидать появления всего нужного в ближайшее время не приходится, но вполне вероятно, что часть текущих приватных API станет публичными, когда разработчики SDK посчитают их достаточно стабильными.
  4. Если вы платите за аккаунт разработчика, то можете задать два технических "code level" вопроса в год без дополнительной платы. Так же полезными являются официальные "Q&A" и "Tech Notes", поискать по ним можно в разделе для разработчиков, а общий список доступен на легаси-сайте документации.
  5. Не бросайтесь сразу делать свой бэкенд. Понимаю, сильно хочется, но это излишне и даже может навредить. Часто API (Last.fm, musicbrainz, iTunes Search API из упоминаемых в статье) делают ограничение по IP адресу источника запроса. Передача пользовательского токена для доступа к Apple Music на бэкенд не выглядит хорошей идеей. А переносить все данные из открытых источников "себе" не всегда возможно и далеко не дёшево, не смотря на бесплатность и открытость самих данных 27.
  6. Изображения, получаемые из Apple Music API, ровно как и превью песен являются материалами, охраняемыми авторским правом. Ревью-команда App Store отклонит ваше приложение, если в превью играется музыка (на которую нет специального соглашения) и на скриншоте отображаются картинки, например, альбомов (на которые так же нет специального разрешения от правообладателя). Предыдущее моё музыкальное приложение 28 спокойно проходило ревью, не смотря на то, что на скриншотах содержало массу картинок альбомов и фотографий артистов, которые получались не самым лучшим с точки зрения авторского права образом 29. Сейчас же Apple за этим следит чуть строже 30.
  7. Учитывайте, что веб-интерфейс Apple Music — приложение на Ember. Если собираетесь парсить сведения, то нужно убедиться, что они имеются в html странице до того как в дело вступают модификации DOM со стороны Javascript.
  8. Если парсите веб-страницы, то сделайте так, чтобы приложение не показывало ошибок при изменении структуры этих страниц. Лучше не отобразить картинку или воспользоваться запасным вариантом получения данных, если парсинг не удался.

Послесловие

Хочется верить, что и другие игроки рынка, включая Яндекс и Гугл начнут предоставлять публичные SDK для музыкальных сервисов. Не смотря на шероховатости SDK, недостаточность сведений и отсутствие по настоящему полезных batch запросов в API, имеющихся в арсенале средств достаточно для разработки интересных программных продуктов, выходящих за рамки «альтернативных плееров» для Apple Music. Будем надеяться на светлое будущее с большим выбором музыкальных SDK, а пока закатаем рукава и будем делать интересные вещи в рамках имеющихся ограничений.

Говорят, ограничения даже помогают.

Бесполезные примечания

1 Он же метод (научного тыка)

2 Заметьте, что документация о такой связи умалчивает

3 Конечно, в Music.app и веб-интерфейсе при просмотре альбомов есть индикация популярности песен (популярные песни отмечены звёздочками), но в публичном API эта информация (даже простой флаг "популярно") отсутствует

4 Играться с параметром limit не получится: Specified limit for relationship 'songs' exceeds maximum of 20

5 The Beatles

В выдаче API iTunes Store присутствует флаг `isStreamablez, по которому можно понять есть объект в Apple Music или нет. 6 Если быть более точным, то всё что есть в Apple Music есть в iTunes Store.

7 Пример запроса: https://itunes.apple.com/WebObjects/MZStore.woa/wa/viewArtistSeeAll?cc=ru&ids=424279384&section=0

8 Хотя уверен, что он достаточно стабилен и, скорее всего, используется в декстопных приложениях iTunes и на устаревших (необновляемых) устройствах с iTunes Store

9 А список жанров нам в любом случае нужен для поиска по ним

10 Классифицируем классификаторы, всё как в лучших университетах нашей страны!

11 Формально, поскольку рекомендации в Apple Music среди пользовательской базы часто воспринимаются негативно: они игнорируют дизлайки, пропуски песен и не всегда похожи на то, что хотел бы услышать пользователь

12 Естественно, предварительно обернув в MPMusicPlayerPlayParametersQueueDescriptor

Такие нас не очень интересуют в контексте рекомендаций. 13 Станции в Apple Music бывают разных типов, в том числе (живые) с настоящими ведущими.

14 Если, конечно, хочется попасть в App Store

Вообще не ожидайте увидеть для них рекомендации. 15 Не ожидайте увидеть (Триаду) в рекомендациях для (Нигатива) и (Сансару) в рекомендациях для (Курары).

16 Чаще всего это просто ссылки на веб-страницы, но из них достаточно просто достать настоящие идентификаторы

17 Персональный каталог состоит из того, что пользователь купил в iTunes Store и загрузил в iTunes Match

18 И тем более получить с помощью публичного API URL для стриминга

Делегировать, так делегировать. 19 Исключение — игры или программы-утилиты, где проигрывание музыки не является основной задачей.

В действительности под капотом плеер использует AVPlayer, который может работать в фоне, достаточно только указать необходимые флаги в Info.plist или просто поставить галочку в нужном месте и всё будет сделано автоматически. 20 Документация говорит: (When your app moves to the background, the music player stops playing the current media.).

21 Тогда всё же хочется делать чуть более общую реализацию и свою надстройку над очередью.

22 При этом везде отображаются правильные обложки, которые самому из MPMediaItem получить не удаётся

23 Которую так же приходится получать с помощью транзакции изменения очереди

В ситуации с iOS Media Player является частью операционной системы, соответственно требования по стабильности API более высокие. 24 Скорее всего это вызвано тем, что данные SDK подключаются как внешние библиотеки, что несколько развязывает руки разработчикам, позволяя сильно не заботиться об обратной совместимости.

25 Не буду тыкать пальцами в конкретные конкурирующие операционные системы, в которых работа с медиа — это игра в прятки с демонами, а с каждой версией правила игры меняются.

Apple не создала новый фреймворк, а улучшила существующий. 26 Фактически раньше тем же SDK можно было управлять только локальной библиотекой пользователя, теперь добавилась поддержка Apple Music.

Конечно, можно взять сведения из Enterprise Partner Feed, musicbrainz, всё это обработать и на каждый случай предоставлять свой API. 27 Дорого не только с точки зрения железа, но и самой дорогой части — стоимости труда программиста. Однако стоит подождать до того момента, когда наберётся критическая масса пользователей и реальных их проблем. Вполне вероятно, что это будет экономить трафик пользователя (хотя в музыкальном приложении это вопрос не первостепенный) и вообще работать быстрее.

I. 28 R. P.

29 С помощью API поиска Bing

30 Оберегая нас от исков со стороны правообладателей

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть