Как это устроено
API демона
Как устроен локальный API, его транспорт, аутентификация, структура и группы маршрутов.
nuvo-core - HTTP-сервер (axum) на unix-сокете. Это внутренний интерфейс между окном Nuvo и его службой. Публичным API он не является и может меняться между версиями.
Транспорт
- Сокет находится по адресу
$XDG_RUNTIME_DIR/nuvo/core.sock, в каталоге с правами 0700, сам сокет с правами 0600. Путь можно переопределить переменнойNUVO_CORE_SOCKET. - Каждому запросу нужен заголовок
Authorization: Bearer <token>. Токен случайный, не короче 32 символов, создаётся при запуске и известен только основному процессу Electron и демону./healthтоже требует его. Неверный токен даёт401. - Второй демон не может занять сокет, пока на нём кто-то отвечает.
- Размер тела запроса ограничен. Загрузки в кэш ограничены 512 МиБ.
Состояние и проверка работоспособности
GET /health возвращает статус: starting, пока демон открывает медиатеку, затем ok. Пока медиатека заблокирована, её маршруты отвечают 423 с кодом LOCKED.
Ошибки
У каждой ошибки тело одной и той же формы:
{ "message": "...", "code": "NOT_FOUND", "reqId": "a1b2c3d4e5f6", "reason": "..." }
reason появляется только для невоспроизводимых треков SoundCloud. Коды: NOT_FOUND, INVALID_INPUT, FORBIDDEN_HOST, CONFLICT, LOCKED, CORE_STARTING, UNAUTHORIZED, UPSTREAM, UPSTREAM_TIMEOUT, RATE_LIMITED, SC_UNAVAILABLE, SC_UNPLAYABLE, UNSUPPORTED_FORMAT, INTERNAL. Внутренние ошибки возвращают короткое сообщение, а подробности пишутся в лог под reqId.
Логирование
В лог попадают метод, шаблон маршрута, статус и время. Сырые пути в нём не записываются, поэтому идентификаторы треков не превращаются в историю прослушиваний.
Группы маршрутов
| Префикс | Что делает |
|---|---|
/v1/me, /v1/users/me |
Профиль, любимые треки, сохранённые альбомы и исполнители, плейлисты и их элементы, флаги и порядок закрепления, история, события воспроизведения и «сейчас играет», история поиска, обрезки, ежедневные миксы |
/v1/cache |
Зашифрованное аудио: чтение с Range, запись, удаление, статус, настройки лимита, список недостающего, фоновые задачи загрузки |
/v1/covers |
Обложки в размере для показа |
/v1/tracks/{id}/lyrics |
Поток текста, собственные тексты пользователя, сдвиг времени |
/v1/lyrics |
Сдвиги, настройки переводчика и перевод |
/v1/recs |
Опорные треки, пул, ранжирование, стартовые исполнители, скрытие, «Не интересно», исключённые элементы |
/v1/tracks/{id}/radio, /alternative |
Радио и альтернативные источники |
/v1/match |
Сопоставление каталожных треков для импорта и ссылок |
/v1/imports |
Задачи импорта, строки, кандидаты, массовые действия, отчёты CSV |
/v1/sc |
Поиск SoundCloud, треки, наборы, пользователи, потоки |
/v1/youtube |
Состояние аккаунта и настройки |
/v1/links |
Разбор ссылок |
/v1/recognize |
Распознавание песен, история, состояние инструментов |
/v1/local |
Папки с музыкой, треки, статус, повторное сканирование, аудио, обложки |
/v1/downloads |
Очередь сохранения файлами |
/v1/fs |
Маршруты, которые вызывает только основной процесс Electron: они называют папки или возвращают документы для диалогов сохранения (сохранённые файлы, экспорт, локальные папки) |
/v1/recovery |
Фраза восстановления, подтверждение, восстановление |
/v1/appearance, /v1/shortcuts |
Сохранённые настройки |
/v1/system |
Проверка зависимостей, проверка сети, прокси, отчёт для поддержки, завершение работы |
/v1/lastfm |
Сессия Last.fm и скробблы (в приложении для этого пока нет экрана) |
/v1/explore |
Списки популярного и самого сохраняемого |
Аудио через сокет
GET /v1/cache/audio/{id} и GET /v1/local/tracks/{id}/audio обслуживают запросы Range. Демон расшифровывает только те части, которые нужны для диапазона. Рендерер обращается к ним через протокол nuvo-core://, который перенаправляет основной процесс.
Стабильность
Маршруты начинаются с /v1. Считайте API закрытым для Nuvo.