Статья о том, как Spotify Web API (SWA) и платформа Google Apps Script (GAS) позволили превратить библиотеку в гибкий конструктор плейлистов с бесплатным исполнением по расписанию.
Под конструктором плейлистов понимаем механизм сбора, фильтрации, сортировки и добавления треков.
Проблема
Наличие официального API породило для Spotify множество интересных инструментов. В нашем контексте рассмотрим Smarter Playlists. Графический интерфейс в виде графов, множество управляющих блоков делают его довольно дружелюбным для обычного пользователя.
Плотное использование сервиса выявило ряд недостатков:
отсутствие истории прослушиваний
лимитированное добавление треков
ограниченное количество запусков по расписанию
некорректная работа с кириллицей
С течением времени сюда добавляется желание новых источников получения треков; более сложных алгоритмов фильтрации. Сервис перестал развиваться с точки зрения новых функций.
В связи с чем появилось желание альтернативы, устраняющей данные недостатки.
Решение
В результате была разработана библиотека для GAS на JavaScript - Goofy. Конструктором её делает возможность запуска на платформе в редакторе или по расписанию (триггерам) без стороннего ПО.
GAS накладывает свои ограничения, но другого порядка. Например, время исполнения не более 6 минут; количество запросов к внешним API не более 20 тысяч в день. С другой стороны, круг возможностей существенно расширился. Реализованы все функции Smarter Playlists, устранены его недостатки. Появились новые функции.
Что можно сделать
Несколько простых примеров, которые можно реализовать с помощью Goofy
Объединять личные миксы дня с удалением ранее прослушанных треков
Собирать треки из найденных по ключевым словам плейлистам
Миксовать треклисты FM-радиостанций
Составлять рекомендации по жанрам, трекам, исполнителям
Выявлять давно не прослушиваемых треков
Собирать новинки отслеживаемых исполнителей
Накапливать треки обновляемого источника в плейлисте с удалением уже прослушанных
Получать рекомендации Last.fm любого пользователя, топ за период, соседи по музыкальным вкусам и многое другое
История прослушиваний
Частое прослушивание музыки без особо активных действий приводят стриминг платформы к повторам. Одни и те же треки приходят изо дня в день. Goofy позволяет удалить ранее прослушанные треки. Но это сложнее, чем казалось на первый взгляд.
SWA дает возможность получить только 50 последних прослушанных треков. Появление 51-ого делает недоступным 1-й.
GAS имеет выход к Google Drive. Библиотека создает повторяющийся триггер и опрашивает SWA на предмет новых прослушиваний. Если они есть, сохраняет в файл. Таким образом, появляется локальная полная история прослушиваний.
Есть другая проблема. Трек считается прослушанным только после 30 секунд. Причем зачастую недавние треки обновляются не сразу или вовсе теряются. Списываю это на "качество" SWA.
Решение есть и здесь - использовать Last.fm. Реализовано два подхода. Во первых, можно просто запросить недавние прослушивания и удалять совпадения по названию трека. Во вторых, можно выполнить поиск трека в Spotify и сохранить его в файл на Google Drive. Тем самым получая историю прослушиваний от Last.fm готовую к работе со Spotify.
Примеры
Нужно выполнить установку (копирование в GAS) и настройку (выдача разрешений, ключи доступа). Все подробно есть в документации.
1) Простой пример: получить любимые треки, взять пять случайных и добавить в плейлист.
Далее графическими средствами GAS создаем триггер. В результате, например, раз в минуту плейлист будет обновляться пятью случайными треками.
function createHelloPlaylist() {
let tracks = Source.getSavedTracks();
Selector.keepRandom(tracks, 5);
Playlist.saveWithReplace({
name: 'Hello, playlist',
tracks: tracks,
});
}
2) Выявить любимые треки, которые не были прослушаны более чем месяц.
function templateSavedAndForgot(){
let recentTracks = Source.getRecentTracks(2500);
let savedTracks = Source.getSavedTracks();
Filter.removeTracks(savedTracks, recentTracks);
let startDate = new Date('2006-01-01');
let endDate = Filter.getDateRel(30, 'endDay');
Filter.rangeDateAbs(savedTracks, startDate, endDate);
Selector.keepRandom(savedTracks, 20);
Order.sort(savedTracks, 'meta.added_at', 'asc');
Playlist.saveWithReplace({
name: 'Любимо и забыто',
tracks: savedTracks,
randomCover: 'update', // установить случайную обложку плейлиста
});
}
3) Получить треки альбомов и синглов отслеживаемых исполнителей за неделю.
function createNewRelease() {
const playlistId = 'abc';
let tracks = Source.getArtistsTracks({
artist: {
followed_include: true
},
album: {
groups: 'album,single',
release_date: { sinceDays: 7, beforeDays: 0 }
},
});
Order.shuffle(tracks);
Combiner.push(tracks, Source.getPlaylistTracks('name', playlistId));
Filter.removeTracks(tracks, RecentTracks.get(3000));
Filter.matchOriginalOnly(tracks);
Playlist.saveWithReplace({
id: playlistId,
name: 'Новые релизы',
tracks: tracks,
randomCover: 'update',
});
}
Ссылки
Документация писалась с ориентиром на пользователя, который не знаком с программированием. Чтобы дать возможность использовать Goofy через копипаст шаблонов и примеров.