Как это устроено

Кэш аудио

Как Nuvo хранит аудио в зашифрованном виде, отдаёт его по диапазонам, подгружает заранее и ограничивает размер.

Формат файла

Каждый кэшированный трек - один файл с именем <sha256(track id)>.lac в ~/.cache/nuvo/audio/. Имя скрывает идентификатор трека. Файлы индексирует база данных.

"LAC1" | 16-byte nonce prefix | sealed chunk | sealed chunk | ...
  • Аудио режется на части по 64 КиБ. Каждая часть запечатывается отдельно шифром XChaCha20-Poly1305. Nonce составляется из случайного префикса файла и номера части.
  • Части независимы. При перемотке расшифровываются только нужные части. Повреждённая часть не проходит проверку подлинности.
  • Ключ выводится из мастер-ключа. Файл, записанный с другим ключом, считается повреждённым.

Загрузка

Рендерер просит демон скачать URL потока или загружает аудио, которое у него уже есть. Задачи загрузки:

  • принимают только URL https на хостах воспроизведения (*.googlevideo.com, *.sndcdn.com, playback.media-streaming.soundcloud.cloud), без учётных данных и без нестандартного порта,
  • проверяют, что все адреса, в которые разрешается хост, публичные,
  • следуют не больше чем трём перенаправлениям, и каждое проверяется так же,
  • качают диапазонами по 10 МиБ, выполняют две задачи одновременно и завершаются по таймауту через десять минут,
  • хранят состояние последних 50 задач.

Загрузка пишется во временный файл .part со случайным именем и переименовывается по окончании. При запуске демон удаляет частично скачанные файлы и файлы, которых нет в индексе.

Подгрузка заранее

Пока трек играет, Nuvo в фоне загружает следующий, чтобы следующий старт шёл из кэша.

Ограничение размера

Лимит по умолчанию - 5 ГиБ. Минимум - 256 МиБ. Значение 0 означает отсутствие лимита. Когда кэш превышает лимит, демон удаляет файлы: сначала те, что реже играли за последние 30 дней, затем те, что дольше всего не слушали. Он сохраняет любимые треки, треки из плейлистов, закреплённых для офлайна, и треки, которые вы дослушали до конца не меньше трёх раз за последние 30 дней. В «Настройки», «Хранилище» видно, сколько занято, и можно изменить лимит («Лимит кэша») или очистить кэш.

Обложки

Обложки лежат в отдельном зашифрованном кэше, в размерах для показа, по одной загрузке на обложку и размер.

Локальные файлы

Локальные файлы никогда не копируются в этот кэш. Они играют оттуда, где лежат.