Files
MTS-music-another-client/README.md
jads c8043d8b80 Merge remote-tracking branch 'origin/main'
# Conflicts:
#	README.md
#	mtsmusic.py
#	qt_app.py
2026-10-25 23:45:33 +03:00

289 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# MTS Music — another client
Неофициальный клиент для **своего** аккаунта MTS Music: «Моя волна», поиск,
избранное, тексты песен, воспроизведение и скачивание в MP3 с полными
ID3-тегами. Есть компактный TUI-плеер и настольное Qt-приложение в стиле
телефона.
> Только для личного использования с собственной платной подпиской MTS.
> Проект не связан с МТС и Яндексом; контент не перераспространяется.
Внутри используется тот же путь, что и в веб-клиенте: MTS SSO выдаёт
OAuth-токен Яндекс.Музыки, дальше запросы идут на `api.music.yandex.net`.
## Установка
```bash
python3 -m venv .venv
.venv/bin/pip install -r requirements.txt
PLAYWRIGHT_BROWSERS_PATH="$PWD/.playwright" .venv/bin/playwright install chromium
```
Для Qt-приложения дополнительно:
```bash
.venv/bin/pip install -r requirements-qt.txt
```
Всё локальное лежит рядом с проектом:
- `.venv/` — зависимости
- `.playwright/` — браузер Chromium
- `.mts-music/` — профиль браузера и `credentials.json`
## Вход
```bash
.venv/bin/python mtsmusic.py login
```
Откроется браузер. Нужно вручную войти в MTS и пройти капчу. Токен и cookie
сохранятся в `.mts-music/credentials.json` с правами `600`.
Повторный вход нужен только когда токен перестанет работать.
## TUI-плеер
```bash
.venv/bin/python mtsmusic.py tui
```
Интерфейс в терминале сделан как экран телефона: чёрно-белые элементы и
цветная обложка. Обложка по центру, строго под ней по той же ширине —
большая кнопка play/pause и по бокам предыдущий/следующий треки, ниже
«Текст» и «Избранное». Кнопка «☰» в левом верхнем углу открывает боковое
меню: «Моя волна», избранное, история прослушивания, поиск, текст песни,
«Скачать трек», «Скачать список», «Настройки» и выход.
Мышь работает: кнопки, меню, строки списков и полоса прогресса кликабельны
(клик по прогрессу перематывает трек).
| Клавиша | Действие |
|---------|----------|
| `Space` | пауза / продолжить |
| `←` / `→` | перемотка на −5 / +5 секунд |
| `n` / `p` | следующий / предыдущий трек |
| `t` | текст песни |
| `l` | добавить / убрать из избранного |
| `m` | открыть меню |
| `w` | список «Моей волны» |
| `f` | избранное |
| `h` | история |
| `s` | поиск |
| `d` | скачать выделенный трек в списке |
| `q` | выход |
История хранится в `.mts-music/history.json` (последние 100 треков).
Плеер — `ffplay` (или `mpv`, если установлен). Пауза реализована через
`SIGSTOP`/`SIGCONT`, а перемотка перезапускает воспроизведение с нужной
секунды, поэтому отдельный демон не нужен.
Треки не транслируются напрямую: сначала они скачиваются в локальный кэш
`.mts-music/cache/` (до 512 МБ, старые файлы удаляются автоматически), а плеер
играет уже готовый MP3. Так надёжнее — сервер Яндекса закрывает соединение,
если клиент читает поток медленнее реального времени, из-за чего трек
обрывался через полминуты и клиент переключался на следующий. Заодно кэш
убирает задержку при повторном прослушивании и делает перемотку мгновенной.
## Qt-приложение
```bash
.venv/bin/python mtsmusic.py qt
```
Отдельное окно в стиле телефона: крупная цветная обложка, кнопка play/pause,
переключение треков, перемотка, текст песни и избранное. Кнопка «☰» открывает
боковую панель с «Моей волной», избранным, историей, поиском, скачиванием
и настройками.
Воспроизведение — через `QMediaPlayer`/FFmpeg из PySide6, поэтому работает
перемотка и системный звук. По полосе прогресса можно кликнуть в любое место —
каретка сразу перейдёт туда (и потянется, если вести мышью). Окно растягивается
вместе с обложкой, списки прокручиваются, двойной клик по строке запускает трек.
`Tab` переключает фокус по элементам: меню, полоса, предыдущий, play, следующий,
«Текст», «Избранное». Горячие клавиши: `Space`, `←`/`→`, `N`/`P`, `L`, `T`, `M`,
`F`, `H`, `S`, `W`; `Esc` закрывает меню/экран, `Ctrl+Q` — выход.
«Моя волна» продолжается с последних прослушанных треков (берётся история), а не
начинается каждый раз с одного и того же места.
## Скачивание и метаданные
В меню обоих клиентов пункт «Скачать» открывает выбор: текущий трек, всё
избранное, 20 треков «Моей волны» или результаты поиска; папка выбирается
диалогом в Qt и вводится вручную в TUI, прогресс и число ошибок видны на
экране. Быстрые пункты «Скачать трек»/«Скачать список» (и клавиша `d` на
экране списка в TUI) сразу кладут в папку `download_dir` без диалога. В CLI
это команда `download` с теми же источниками (`--likes`, `--wave`, `--search`).
Файлы кладутся в папку `download_dir` (`~/Music/MTS Music` по умолчанию),
имя — `Исполнитель - Название.mp3`; существующие файлы не перезаписываются,
при совпадении добавляется ` (2)`, ` (3)` и т.д. (`--force` перезаписывает).
В скачанный файл пишется максимум метаданных ID3v2.3 (через `mutagen`, он в
`requirements.txt`):
- название, все исполнители (`TPE1`), альбом (`TALB`) и альбомный исполнитель
(`TPE2`);
- номер трека и диска (`TRCK`/`TPOS`), год и дата релиза (`TYER`/`TDAT`),
жанр как в API (`TCON`), лейбл (`TPUB`), длительность (`TLEN`);
- обложка 600×600 (`APIC`);
- текст песни (`USLT`) и синхронный текст (`SYLT`), если он есть: сначала
пробуем MTS, затем [LRCLIB](https://lrclib.net);
- ссылка на трек (`WOAR`/`COMM`), пометка `explicit` (`ITUNESADVISORY`) и
служебные поля с id трека, альбома и `realId` (`TXXX`).
Без `mutagen` или при `--no-tags` теги не пишутся, скачивание при этом
работает как обычно.
## Управление из системной панели (MPRIS)
При запуске TUI и Qt-приложение регистрируются в сессионном D-Bus как источник
звука (`org.mpris.MediaPlayer2.mtsmusic`). Поэтому плеер виден системе и им можно
управлять из панели GNOME — например, расширением
[media-controls](https://github.com/sakithb/media-controls), — а также через
`playerctl` и другие MPRIS-клиенты.
Что работает из панели:
- play/pause, следующий/предыдущий трек;
- перемотка (слайдер и seek);
- отображение названия, исполнителя, альбома, длительности и цветной обложки;
- громкость.
Для этого нужен `dbus-next` (он уже в `requirements.txt`). Без сессионного
D-Bus или без `dbus-next` приложение просто работает как обычно, без интеграции.
## Настройки
Настройки открываются из меню (пункт «Настройки» в TUI и Qt) или из командной
строки и хранятся в `.mts-music/settings.json`:
```bash
# показать текущие настройки
.venv/bin/python mtsmusic.py settings
# изменить: громкость 60%, шаг перемотки 10 секунд
.venv/bin/python mtsmusic.py settings -s volume=60 seek_step=10
```
| Настройка | По умолчанию | Описание |
|-----------|--------------|----------|
| `volume` | `80` | громкость плеера, 0–100 |
| `seek_step` | `5` | шаг перемотки стрелками, секунды |
| `autoplay` | `false` | начинать воспроизведение сразу при запуске |
| `start_queue` | `wave` | что открыть первым: `wave`, `favorites` или `history` |
| `wave_from_history` | `true` | продолжать «Мою волну» с последних треков |
| `download_dir` | `~/Music/MTS Music` | куда сохранять скачанные MP3 |
В Qt-приложении на странице настроек дополнительно выбирается устройство вывода
звука и папка загрузок (кнопка «Выбрать…»). В TUI путь задаётся в настройках
пунктом «Папка загрузок». Громкость меняется на лету, остальные настройки
применяются к новым трекам и при следующем запуске.
## Команды
```bash
# кто я и есть ли подписка
.venv/bin/python mtsmusic.py status
# поиск
.venv/bin/python mtsmusic.py search "miyagi" -n 10
# «Моя волна»: 10 треков, ♥ — уже в избранном
.venv/bin/python mtsmusic.py mix -n 10
# сразу слушать подборку (Ctrl-C — остановить)
.venv/bin/python mtsmusic.py mix -n 5 --play
# избранное: добавить / убрать / показать текстом
.venv/bin/python mtsmusic.py like 12345678
.venv/bin/python mtsmusic.py unlike 12345678
.venv/bin/python mtsmusic.py likes # все любимые треки
.venv/bin/python mtsmusic.py likes -n 20 # только первые 20
.venv/bin/python mtsmusic.py likes --ids # только ID, для скриптов
# текст песни: показать, сохранить, или с таймкодами
.venv/bin/python mtsmusic.py lyrics 12345678
.venv/bin/python mtsmusic.py lyrics 12345678 -o track.txt
.venv/bin/python mtsmusic.py lyrics 12345678 --lrc -o track.lrc
# только права MTS, без внешнего источника
.venv/bin/python mtsmusic.py lyrics 12345678 --no-fallback
# прямая ссылка на MP3
.venv/bin/python mtsmusic.py url 12345678
# воспроизведение (нужен mpv или ffplay)
.venv/bin/python mtsmusic.py play 12345678
# скачивание: в папку из download_dir, имя «Исполнитель - Название.mp3»
.venv/bin/python mtsmusic.py download 12345678
# несколько треков или своя папка
.venv/bin/python mtsmusic.py download 12345678 87654321 -d ~/Music/MTS
# как в мобильном приложении: избранное, волна или результаты поиска
.venv/bin/python mtsmusic.py download --likes -d ~/Music/MTS
.venv/bin/python mtsmusic.py download --wave -n 20 -d ~/Music/MTS
.venv/bin/python mtsmusic.py download --search "Кино" -n 10 -d ~/Music/MTS
# один трек с явным именем файла, перезапись существующих
.venv/bin/python mtsmusic.py download 12345678 -o track.mp3
.venv/bin/python mtsmusic.py download --likes -d ~/Music/MTS --force
# то же самое есть в меню TUI и Qt — пункт «Скачать»
# без ID3-тегов (быстрее, без обложки и текста)
.venv/bin/python mtsmusic.py download 12345678 --no-tags
# настройки
.venv/bin/python mtsmusic.py settings
.venv/bin/python mtsmusic.py settings -s volume=60 seek_step=10
```
Токен можно передать и через переменную окружения:
```bash
export MTS_YA_TOKEN='...'
```
## Если TUI не отображается
```bash
# диагностика окружения
.venv/bin/python mtsmusic.py tui --check
# без alternate screen (если экран пустой)
.venv/bin/python mtsmusic.py tui --inline
# отключить мышь, если терминал плохо её поддерживает
.venv/bin/python mtsmusic.py tui --inline --no-mouse
```
TUI нужно запускать в настоящем терминале (stdin/stdout — TTY), а не в панели
вывода IDE. При падении traceback пишется в `.mts-music/tui-error.log`.
## Ограничения
- Логин автоматизирован не полностью: QRATOR-капчу проходит человек.
- `reference_uri` у MTS должен быть на домене `music.mts.ru`, поэтому
локальный callback не используется — токен забирается из браузера.
- Без активной подписки `download-info` отдаёт `preview` (короткий фрагмент).
- Тексты песен — отдельная подписка Яндекс Плюс, которой у MTS-аккаунта нет
(`hasPlus: false`), поэтому MTS возвращает `404` даже для треков с текстом.
`lyrics` автоматически берёт текст из бесплатного [LRCLIB](https://lrclib.net)
и помечает источник в выводе. `--no-fallback` отключает это поведение.
- Использовать только для личного прослушивания, не перераздавать контент.
- Если `api.music.yandex.net` недоступен, проверь IPv6: клиент принудительно
ходит по IPv4.
- Кэш треков лежит в `.mts-music/cache/`. Его можно удалить в любой момент —
при следующем запуске треки скачаются заново.
- `download` (и пункт «Скачать» в TUI/Qt) по умолчанию не перезаписывает уже
скачанные файлы: повторный запуск докачает только новое. Флаг `--force`
в CLI включает перезапись.
## Лицензия
[MIT](LICENSE) © 2026 jads. Проект предоставляется «как есть», без гарантий;
используйте на свой страх и риск и только со своим аккаунтом.