|
15 | 15 | - 🛠️ Простое расширение новыми движками |
16 | 16 | - 📦 Легкая интеграция в проекты |
17 | 17 | - 🚀 Быстрая установка через pip |
18 | | -- 🖥️ TUI (Textual User Interface) с поиском, прослушиванием и скачиванием |
| 18 | +- 🖥️ TUI (Terminal User Interface) с поиском, прослушиванием и скачиванием |
19 | 19 |
|
20 | 20 | --- |
21 | 21 |
|
@@ -46,12 +46,52 @@ msoc --tui |
46 | 46 | python -m msoc --tui |
47 | 47 | ``` |
48 | 48 |
|
| 49 | + |
| 50 | + |
49 | 51 | TUI позволяет: |
50 | 52 | - Искать треки по запросу |
51 | 53 | - Прослушивать треки через ffmpeg (автоопределение PulseAudio/PipeWire) |
52 | 54 | - Скачивать треки в текущую директорию |
53 | 55 | - Видеть продолжительность треков |
54 | 56 |
|
| 57 | +> **Требование:** для работы TUI нужен ffmpeg в системе. При разработке |
| 58 | +> использовался `ffmpeg version n8.1.2`. |
| 59 | +
|
| 60 | +### Эксперименты с оптимизацией |
| 61 | + |
| 62 | +В процессе разработки я экспериментировал с тем, как уменьшить количество |
| 63 | +сетевых запросов при проигрывании. Для тестов использовал |
| 64 | +[wondershaper](https://github.com/magnific0/wondershaper) — под Linuх он |
| 65 | +позволяет искусственно резать пропускную способность интерфейса, что удобно |
| 66 | +симулировать слабый интернет. |
| 67 | + |
| 68 | +Сейчас воспроизведение выглядит так: |
| 69 | + |
| 70 | +1. **ffmpeg скачивает трек во временную папку** (`-c:a copy` — без |
| 71 | + перекодирования, просто сохраняет поток как есть). |
| 72 | +2. **Второй ffmpeg читает уже локальный файл**, декодирует в PCM |
| 73 | + и отправляет в sounddevice. |
| 74 | + |
| 75 | +Загрузка и воспроизведение работают в разных потоках, поэтому не блокируют |
| 76 | +друг друга — можно начать слушать, не дожидаясь полной загрузки. |
| 77 | + |
| 78 | +Что хочется доделать: сейчас длительность и другие метаданные вытаскиваются |
| 79 | +отдельным вызовом ffprobe (по сути — ещё один запрос к недокачанному файлу). |
| 80 | +Планирую парсить `stderr` первого ffmpeg, чтобы получать ту же информацию |
| 81 | +без лишних походов в сеть. |
| 82 | + |
| 83 | +#### Как работает скачивание |
| 84 | + |
| 85 | +Когда пользователь нажимает Download, логика такая: |
| 86 | + |
| 87 | +- **Если трек уже загружен во временную папку** (докачался во время |
| 88 | + прослушивания) — просто копируем оттуда в текущую директорию. |
| 89 | + Никаких новых запросов в сеть. |
| 90 | +- **Если трек прямо сейчас играет, но ещё не докачался** — ждём, пока |
| 91 | + фоновый ffmpeg закончит, и копируем. Пользователь видит `...` на кнопке. |
| 92 | +- **Если трек не играл и не загружался** — ffmpeg скачивает напрямую |
| 93 | + (`-c:a copy`), сохраняя в текущую папку. |
| 94 | + |
55 | 95 | ## 💻 В консоле |
56 | 96 |
|
57 | 97 | Можно протестировать пакет обычным скриптом: |
@@ -89,21 +129,21 @@ asyncio.run(main()) |
89 | 129 |
|
90 | 130 | Класс `Sound` содержит информацию о песне. |
91 | 131 |
|
92 | | -Атрибуты: |
93 | | - |
94 | | -- `title (str)`: Название песни. |
95 | | -- `url (str | None)`: Ссылка на скачивание песни. Может быть None, если ссылка недоступна (Необязательный атрибут). |
96 | | -- `artist (str | None)`: Исполнитель песни. Может быть None, если информация об исполнителе недоступна (Необязательный атрибут). |
97 | | -- `meta (dict[str, Any])`: Дополнительные метаданные трека. |
98 | | -- `_engine (str | None)`: Название движка, нашедшего трек (заполняется автоматически). |
| 132 | +| Поле | Тип | Описание | |
| 133 | +|------|-----|----------| |
| 134 | +| `title` | `str` | Название песни | |
| 135 | +| `url` | `str` | Ссылка на скачивание | |
| 136 | +| `artist` | `str \| None` | Исполнитель (опционально) | |
| 137 | +| `meta` | `dict[str, Any]` | Дополнительные метаданные (по умолчанию `{}`) | |
| 138 | +| `_engine` | `str \| None` | Движок-источник, заполняется автоматически | |
99 | 139 |
|
100 | 140 |
|
101 | 141 | ## 🔌 Реализованные движки поиска |
102 | 142 |
|
103 | 143 | В настоящее время библиотека MSOC поддерживает следующие движки поиска: |
104 | 144 |
|
105 | 145 | - zaycev_net: Поиск на сайте [zaycev.net](https://zaycev.net) |
106 | | -- hitmo: Поиск на сайте [rus.hitmotop.com](https://rus.hitmotop.com) - реализован на основе [данного кода](https://github.com/Ushiiro82/MelodyHub/blob/master/parsing/hitmo_parser.py) |
| 146 | +- hitmo: Поиск на сайте [rus.hitmotop.com](https://rus.hitmotop.com) - реализован на основе [данного кода от Ushiiro82](https://github.com/Ushiiro82/MelodyHub/blob/master/parsing/hitmo_parser.py) |
107 | 147 | - muzbomb: Поиск на сайте [muzbomb.net](https://muzbomb.net/) - создан [takilow](https://github.com/takilow) |
108 | 148 | - trekson: Поиск на сайте [trekson.net](https://trekson.net/) - обновлённый парсер |
109 | 149 |
|
|
0 commit comments