Создайте веб-плеер музыки с использованием API Spotify
Когда вы изучаете новые концепции, всегда полезно иметь практические примеры и проекты, над которыми можно работать. API Spotify является отличным введением в веб-API в целом. С его помощью вы можете легко создавать простые утилиты, которые выполняют различные задачи, связанные с музыкой.
Об API
Все API ограничены функциями и данными, которые их владелец решает сделать доступными. Но что угодно лучше, чем ничего, и API Spotify, возможно, удивительно открыт и прост в использовании.
У API есть две основные компоненты:
- Веб-API, который предоставляет метаданные о исполнителях, треках и плейлистах.
- SDK для веб-воспроизведения, который позволяет встраивать плеер Spotify на веб-страницу.
В общем, они довольно ограничены; например, Spotify утверждает, что вы не должны использовать Playback SDK для разработки коммерческих потоковых приложений. Но все же есть несколько интересных проектов, которые вы можете создать для собственного использования, и API Spotify является хорошим примером веб-API в целом, идеально подходящим для обучения и практики.
Настройка вещей
Два демонстрационных проекта, о которых я буду говорить, находятся в репозитории GitHub.
Самое очевидное, что вам потребуется для создания этих образцовых приложений, это учетная запись Spotify. С помощью нее вы можете войти в панель управления Spotify для разработчиков и начать создание приложения.
Вам также понадобится локальный веб-сервер, который вы, возможно, уже настроили. Если нет, сделать это довольно просто. Выберите подходящее место для вашей разработки Spotify, например, localhost/spotify или localhost:8080.
Тем временем, вернувшись на сайт Spotify, заполните форму “Создать приложение”. Убедитесь, что вы выбрали оба варианта: “Web API” и “Web Playback SDK”, и выберите URI перенаправления. Например, я размещаю демонстрацию “top” в файле с именем top.html, который доступен по адресу http://localhost:8080/top.html, так что это один из моих URI перенаправления. Если вы используете аналогичную архитектуру для своих демонстраций, не забудьте добавить каждый новый файл как URI перенаправления.
После того, как вы создали свое приложение, запишите идентификатор клиента и секрет клиента, оба из которых отображаются на странице «Основная информация» вашего приложения.
Для производственных приложений вам необходимо предпринять меры для скрытия вашего клиентского секрета. Для этой локальной демонстрации я просто встраиваю значение в свой файл JavaScript, но вы не должны раскрывать свой клиентский секрет никому.
На этом этапе вы можете скачать образцы файлов, переместить их в корневую папку ваших локальных документов и начать эксперименты. Я могу охватить лишь небольшую часть кода в этой статье, поэтому это позволит вам следовать за процессом.
Авторизация с помощью API
Первый шаг в создании вашего приложения — это авторизация с использованием OAuth. Это популярный стандарт для авторизации веб-приложений, поэтому полезно ознакомиться с ним.
OAuth работает, отправляя токен доступа по протоколу HTTP, и процесс достаточно разработан, чтобы были доступны вспомогательные библиотеки. Тем не менее, для наших базовых целей легко справиться со всем самостоятельно.
Я изолировал этот код в файле access.js. Первый шаг — перенаправить на URL-адрес авторизации Spotify, который выглядит так: https://accounts.spotify.com/authorize. Вам нужно предоставить несколько параметров, чтобы запросить разрешение пользователя на использование вашего приложения:
- тип_ответа: для типов образца приложения, которое мы создаем, просто используйте код.
- client_id: это идентификатор клиента, который вы отметили во время настройки приложения.
- область: строка с разделенными пробелами областями для предоставления разрешений. Для двух демонстраций, которые я здесь рассмотрю, "streaming user-top-read" вполне достаточно, но обязательно ознакомьтесь с полным набором областей, если вы пробуете другие конечные точки.
- redirect_uri: действительный URI перенаправления, который вы добавили к своему приложению.
Вы также должны использовать параметр state по соображениям безопасности, но во время этих демонстраций можно обойтись без него.
В access.js функция authorize выглядит следующим образом:
function authorize() { let base = "https://accounts.spotify.com/authorize", params = { response_type: "code", client_id: CLIENT_ID, scope: "streaming ...", redirect_uri: REDIRECT_URI, }; window.location.assign(base + "?" + new URLSearchParams(params)); }
Это перенаправляет браузер на URL-адрес Spotify с соответствующими параметрами. Когда вы открываете этот URL, вы увидите что-то вроде следующего:
Пользователю нужно будет предоставить разрешения только один раз, если вы не измените область. С предоставленным разрешением они будут отправлены на redirect_uri с параметром code. Таким образом, они окажутся на чем-то вроде http://localhost:8080/top.html?code=… Ваш скрипт должен проверить наличие этого параметра и продолжить к следующему шагу, если он присутствует:
let p = new URLSearchParams(window.location.search); if (p.has("code")) { get_access_token(p.get("code")); }
Этот второй шаг включает в себя отправку кода, который вы только что получили, обратно в Spotify в обмен на токен доступа. Затем вы будете использовать токен доступа во всех дальнейших запросах к API.
Код в этой статье упрощен, чтобы сократить длину. Обратитесь к полному коду в репозитории GitHub для получения дополнительных деталей. В частности, вам также нужно будет обновить токен, когда он истечет.
async function get_access_token(code) { let url = "https://accounts.spotify.com/api/token", data = { grant_type: "authorization_code", code: code, redirect_uri: REDIRECT_URI, }, headers = { "content-type": "application/x-www-form-urlencoded", Authorization: "Basic " + btoa(CLIENT_ID + ":" + CLIENT_SECRET), }; let opts = { method: "post", headers: headers, body: get_post_data(data), }; const response = await fetch(url, opts), token = await response.json(); if (token.access_token) { localStorage.setItem("access-token", token.access_token); } else { console.error("Some kind of error getting access token", token); } }
Вы можете использовать API локального хранилища для сохранения записи о токене доступа и извлекать его в будущем:
let token = localStorage.getItem("access-token");
Теперь вы должны отправлять токен доступа в заголовке Authorization для всех запросов к API Spotify:
async function spotify_api_get(url) { let headers = { Authorization: "Bearer " + at.access_token, }; let opts = { headers: headers, method: "GET" }; const response = await fetch(url, opts); return await response.json(); }
Эта функция занимает весь файл spotify.js и обрабатывает только GET-запросы. Вы можете расширить этот файл и написать аналогичные функции для методов, таких как PUT и POST, когда конечная точка, которую вы хотите использовать, их требует.
OAuth — это довольно сложная тема, выходящая за пределы данной статьи. Вы можете использовать простую версию для экспериментов; просто помните, что вам нужно будет вручную сбросить токен, если он истечет (см. localStorage.removeItem).
Получение информации о метаданных
С учётом того, что всё настроено и клиент авторизован, вы наконец готовы начать использовать API. Получение метаданных немного проще, поэтому я начну с примера «топ» (top.html), который показывает ваших лучших артистов вместе с некоторой информацией о них.
Начните с ознакомления с документацией API Spotify, которая объясняет, как использовать конечную точку /me/top/artists. Вы можете сделать это проще, избегая дополнительных параметров и сосредоточившись на объекте ответа, который содержит детали ваших лучших артистов в его свойстве items.
В top.js функция run() содержит код для получения и отображения этих данных. Это очень просто: сначала она вызывает API-эндпойнт и сохраняет возвращенный объект:
let top_artists = await spotify_api_get( "https://api.spotify.com/v1/me/top/artists", at.access_token, );
Затем он перебирает элементы в ответе:
top_artists.items.forEach(function (artist) { // ... });
А внутри этого цикла он добавляет строку таблицы, содержащую данные для каждого элемента:
tr = tbody.appendChild(document.createElement("tr")); td = tr.appendChild(document.createElement("td")); td.appendChild(document.createTextNode(artist.name)); // ...
Результат представляет собой простую таблицу с вашими любимыми исполнителями и связанными с ними жанрами; моя выглядит так:
Использование плеера Spotify
Метаданные интересны, но работающий плеер Spotify, возможно, более полезен. Хотя есть ограничения, API фактически дает вам полный контроль над воспроизведением, так что, с небольшими усилиями, вы можете создать свой собственный клиент.
Самая большая проблема заключается в том, что API требует, чтобы вы запускали Spotify одновременно с вашим собственным клиентом. Это не должно стать большой проблемой для вашей разработки, но может ограничить потенциальные приложения, которые вы сможете разработать. Вам нужно будет явно подключить приложение Spotify к вашему API-клиенту, как к устройству:
Более того, вам нужно будет делать это каждый раз, когда вы обновляете своё веб-приложение, что может быть неприятно. Я добавил сообщение об ошибке в демонстрацию, которое напоминает вам о необходимости это делать; это немного облегчает ситуацию!
Файл player.html представляет собой простой клиент с обложкой альбома, элементами управления воспроизведением и индикатором прогресса, который позволяет вам перематывать. Большая часть соответствующего функционала находится в файле player.js.
Первое, что нужно сделать, это вставить скрипт SDK Spotify:
<script src="https://sdk.scdn.co/spotify-player.js"></script>
В демонстрации я внедряю это динамически. Это гарантирует, что скрипт может сначала проверить наличие токена доступа, получая его при необходимости. Без действительного токена доступа скрипт SDK может генерировать ошибки.
Затем скрипт создает новый экземпляр игрока и пытается подключиться к нему:
window.onSpotifyWebPlaybackSDKReady = () => { player = new Spotify.Player({ name: "bobbykjack spotify client", getOAuthToken: (cb) => { cb(at.access_token); }, volume: 0.5, }); setup_player_state_event(); player.connect().then((success) => { if (success) { check_device_connected(); } else { console.error("Oops, failed to connect to spotify"); } }); };
Обратите внимание, что игроку необходимо предоставить действительный токен доступа, а также имя, которое будет отображаться в приложении Spotify в качестве устройства для подключения. Методы check_device_connected и check_player_state опрашивают состояние подключения устройства; без него скрипт будет отображать ошибку «Пожалуйста, подключите».
Когда объект Player настроен и подключен, вы можете вызывать дополнительные методы для загрузки дорожек и управления воспроизведением. Эти методы подробно описаны в документации о Web Playback SDK. Пример плеера использует несколько из этих методов: pause, seek, resume, togglePlay и getCurrentState.
Некоторые функции просто требуют подключения кнопки на странице к соответствующему методу SDK. Например, вот код для кнопки воспроизведения:
play.addEventListener("click", function (ev) { player.resume().then(() => { play.setAttribute("disabled", "1"); pause.removeAttribute("disabled"); }); });
Когда на кнопку нажимают, она вызывает метод Player.resume, затем отключает саму себя и включает кнопку паузы.
Некоторая функциональность немного сложнее. Когда трек изменяется, событие player_state_changed вызывает метод с тем же именем, который обновляет отображение, изменяя, например, обложку альбома:
let src = get_image(arg.track_window.current_track.album.images, 300), //... set_attr("#currently_playing div.track-meta img", "src", src);
Чтобы показать текущее состояние воспроизведения трека, код опрашивает метод Player.getCurrentState. Этот метод возвращает объект, содержащий различные детали о воспроизведении, включая текущую позицию трека:
function check_player_state(state) { //... update_time(".position", state.position); //... }
Наконец, положение трека можно изменить, перетаскивая ползунок прогресса:
document .querySelector("#track-progress") .addEventListener("input", handle_seek_input); function handle_seek_input(ev) { if (seek_timer) { window.clearTimeout(seek_timer); } seek_timer = window.setTimeout(function () { seek_to_ms(ev.target.value); }, 200); } function seek_to_ms(position) { player.pause().then(function () { player.seek(position).then(function () { player.resume(); update_time(".position", position); }); }); }
Обратите внимание, что таймер используется для внедрения искусственной — но небольшой — задержки перед вызовом метода Player.seek. Без этой задержки перетаскивание ползунка прогресса на короткое время может привести к сотням вызовов API; этого лучше избегать.
Как и многие другие API, Spotify использует ограничения по количеству запросов, чтобы вы не перегружали сервис слишком большим количеством запросов. Однако это довольно терпимо, и вы не должны столкнуться с какими-либо проблемами с этими примерами; проверьте свою консоль на наличие ошибок 429, если что-то не работает так, как ожидалось.
Финальное приложение представляет собой базовый плеер, который синхронизируется с Spotify:
Надеюсь, вы сможете извлечь уроки из этих простых демонстраций и начать писать свой собственный код для работы с API Spotify. Это может показаться ограниченным, но вы можете внести множество изменений в простого клиента, чтобы улучшить свой опыт работы со Spotify.
Я всегда считал, что плейлисты должны иметь возможность содержать полные альбомы, так что это функция, над которой я определенно буду работать в ближайшее время. Вы также можете изучить другие API, такие как YouTube, чтобы объединить данные с плеером Spotify или метаданными и создать приложение, которое объединяет лучшее из обоих.







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