# nsm Терминальный музыкальный плеер на Rust — что-то вроде [cmus](https://cmus.github.io/), но с нуля, с эквалайзером, поддержкой cue-листов, интернет-радио и SMB-шар. *[Read this in English](README.en.md)* ## Возможности - **Библиотека**: рекурсивное сканирование вложенных папок, поиск (нечёткий, по названию/исполнителю/альбому), группировка по альбомам - **Воспроизведение**: открыть файл напрямую (весь альбом подряд) или добавить в плейлист; несколько плейлистов с возможностью переставлять и удалять треки - **Транспорт**: shuffle, повтор (выкл/один трек/всё), изменение скорости воспроизведения (0.25×–1.75×), mute, честный seek (перемотка) с сохранением позиции - **`.cue`-листы**: один физический файл (например, целый альбом одним FLAC) корректно распознаётся как несколько треков с правильными названиями и границами - **Эквалайзер**: 8 полос, свои биквадратные фильтры - **Обложка**: отображается прямо в терминале (kitty/sixel/iTerm2-протоколы с fallback на блочную графику) - **Анализатор спектра**: настоящий FFT в реальном времени (не анимация) — переключение обложка/спектр клавишей `v`, разворот на весь экран клавишей `z` (транспорт — пробел/next/prev/seek/mute — работает и в полноэкранном режиме) - **Затухание в конце трека**: последние 4 секунды перед концом плавно уводятся в тишину — включается клавишей `F`, по умолчанию выключено - **Выравнивание громкости**: тег ReplayGain в приоритете (если есть в файле), иначе — адаптивный левеллер (AGC), подстраивающий громкость на лету — клавиша `G`, по умолчанию выключено - **Интернет-радио**: свои станции по URL, встроенный список (SomaFM, Radio Paradise), поиск станций через открытый [Radio Browser API](https://api.radio-browser.info) (с автопереключением между несколькими зеркалами, если одно недоступно), ICY-метаданные ("сейчас играет" прямо из потока) - **SMB-шары**: подключение к сетевым папкам (в т.ч. анонимно/гостевой доступ) через системный gvfs — без реализации протокола внутри плеера - **История прослушиваний**: при первом запуске спрашивает, запоминать ли прослушанное; статистика (артист/трек/дата) — диаграммой по часам за сегодня, по дням за неделю/месяц; включается/выключается в любой момент, сбрасывается с подтверждением - **Новые релизы**: проверка новых альбомов/EP/синглов **у артистов, уже имеющихся в твоей библиотеке**, через открытую базу [MusicBrainz](https://musicbrainz.org) (без ключей API) — не глобальный чарт, а именно "что вышло нового у тех, кого ты слушаешь" - **Раскладка**: хоткеи работают одинаково что на английской, что на русской раскладке ## Форматы Поддерживается всё, что умеет декодировать [symphonia](https://github.com/pdeltuvia/symphonia): **MP3, FLAC, ALAC/AAC (в `.m4a`), WAV, AIFF, OGG (Vorbis), MKV/WebM**. **Не поддерживается: Opus** — у symphonia нет собственного Opus-декодера ни в одном наборе фич (только сторонние биндинги к libopus, которых в проекте нет). `.opus`-файлы не индексируются сканером библиотеки. ## Сборка ### Системные зависимости **Linux** — нужны заголовки ALSA (для аудио-вывода через [cpal](https://github.com/RustAudio/cpal)): ```bash # Debian/Ubuntu sudo apt-get install libasound2-dev pkg-config # ALT Linux sudo apt-get install libalsa-devel # Fedora sudo dnf install alsa-lib-devel ``` **macOS** *(не проверено — собиралось и тестировалось только на Linux)* — отдельных аудио-зависимостей не нужно, `cpal` использует системный CoreAudio напрямую. Нужны стандартные инструменты сборки: ```bash xcode-select --install ``` **Windows** *(не проверено — собиралось и тестировалось только на Linux)* — отдельных аудио-зависимостей тоже не нужно (`cpal` использует WASAPI), достаточно обычной установки Rust через [rustup](https://rustup.rs) (MSVC toolchain). Для нормального отображения обложки в терминале нужен современный эмулятор с поддержкой true color — рекомендуется Windows Terminal; протоколы отображения картинок (kitty/sixel/iTerm2) там, скорее всего, не поддерживаются, так что обложка будет через block-графику как fallback. **SMB-фича (`c` в Library) работает только на Linux** — она целиком построена на `gio`/gvfs (GNOME-стек), которого нет ни на macOS, ни на Windows. На этих системах при попытке подключить SMB-шару через nsm просто вернётся понятная ошибка ("is gvfs installed?"), без краша — сетевые папки там штатно монтируются через Finder/Проводник, не через nsm. **Если получаешь ошибку "volume doesn't implement mount" / "том не поддерживает монтирование"** — это gvfs-специфичная ошибка, при том что сама SMB-шара доступна и работает. Обычно значит, что не хватает именно **SMB-бэкенда gvfs** (сам `gio` может быть установлен как чужая зависимость, а конкретно SMB-плагин к нему — нет). Проверить и починить: ```bash # проверить руками, минуя nsm gio mount smb://сервер/шара # на ALT/Fedora-подобных — убедиться, что бэкенд установлен sudo apt-get install gvfs-backends # (или свой пакетный менеджер) # проверить, что D-Bus сессия вообще есть (без неё gvfs не активируется) echo $DBUS_SESSION_BUS_ADDRESS ``` Если это не помогло — причина может быть глубже, в согласовании версии протокола SMB между клиентом и сервером (см. `journalctl` на предмет строк вида `smbXcli_negprot` от `gvfsd`); в этом случае поможет `client min protocol` в `/etc/samba/smb.conf`, как описано выше. Для интернет-радио (**SomaFM**, **Radio Paradise** и т.д.) и MusicBrainz дополнительных системных зависимостей не нужно ни на одной ОС — TLS обеспечивает `rustls` (чистый Rust, без OpenSSL). ### Сборка проекта ```bash git clone cd nsm cargo build --release ``` Бинарник появится в `target/release/nsm` (на Windows — `target\release\nsm.exe`). ### Сборка Windows-бинарника с Linux (кросс-компиляция) ```bash # 1. Добавить Windows-таргет (нужен rustup — обычная установка Rust с rustup.rs) rustup target add x86_64-pc-windows-gnu # 2. Поставить mingw-w64 — кросс-компилятор/линкер под Windows sudo apt-get install gcc-mingw-w64-x86-64 # Debian/Ubuntu; на других — свой пакетный менеджер # 3. Указать cargo, каким линкером пользоваться для этого таргета mkdir -p .cargo cat >> .cargo/config.toml <