Заказчик хотел сделать музыкальную библиотеку, которая бы давала возможность искать музыку и одновременно получать информацию о музыкантах. Результат поиска должен быть не просто линейным набором результатов, а группами песен для разных артистов, так чтоб можно было почитать их биографии и посмотреть концертное расписание.

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

Самым очевидным способом организовать поиск было создать источник структурированной информации об исполнителях и их произведениях. То есть семантическую базу данных, которая содержит всех исполнителей, их альбомы, названия треков и связи между ними. Делая поиск по этой базе, мы сможем получить сами названия песен, чтоб потом поискать их вконтакте. Такую базу нужно поддерживать, например, постоянно делать репликацию с серверов MusicBrains или аналогом.

Однако затем пришла мысль, что все можно сделать проще. Мы попробовали использовать АПИ вконтакте для поиска и фильтровать данные с помощью lastFM. Вконтакте возвращает название трека и автора,  и далее система  пытается найти исполнителей в lastFM. Если находит, то  добавляет биографию и афишу, поднимая результат в выдаче.  Если автор трека не найден, такой трек выводится внизу списка в категории «Другое». Таким образом, мы получаем группировку без семантического запроса. Оставался вопрос, насколько будет хороша такая группировка и можно ли будет легко исключить ошибки и опечатки, ведь музыку вконтакте загружают обычные люди, и одна и та же группа может называться по-разному.

схема работы со своей базой

в итоге сделали проще

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

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

результаты поиска

создаем новый плейлист

загруженный плейлист

Когда на сайт пошел траффик, оказалось, что написать подобный сервис через АПИ вконтакте невозможно. Когда запрашиваешь музыку через АПИ, оно достаточно быстро начинает требовать ввод каптчи гораздо раньше лимитов описанных в документации. . Это стало для всех неприятным сюрпризом, ведь сайт был уже передан заказчику и запущен. Нам нужно было найти способ с минимальными усилиями переделать сайт так, чтобы обойти вызов программного интерфейса вконтакте. Тут нам сильно пригодилась модульная архитектура, которая позволила переписать модуль поиска, не затрагивая весь остальной код. Мы заменили вызовы АПИ парсингом поисковой страницы. И таким образом сохранили всю первоначальную схему, сделав сервис снова полностью рабочим.

общий вид сайта

В итоге мы написали быстрый и удобный  музыкальный поисковик, который ищет   материал, как на сторонних сервисах, так и  во внутренней базе, которая пополняется за счет популярных запросов. С помощью АПИ lastFM система фильтрует и группирует результаты вконтакте, показывая в первую очередь произведения известных артистов вместе с их биографией и афишей. Музыку можно скачивать как в виде отдельных файлов, так и целыми списками в виде архивов.

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