[2026-09-21] eagle: family/plans/watchlist-disk-overflow-fix.md personal/tech/inter-site-throughput-taiga-to-mac.md personal/tech/multistream-single-flow-limit.md
This commit is contained in:
1 parent
313df3409d
commit
ae1caede69
3 files changed
+367
-43
No files matched your search
@@ -11,6 +11,8 @@ tags:
|
||||
- disk
|
||||
- radarr
|
||||
- incident
|
||||
- mark-queued
|
||||
- horror-filter
|
||||
related:
|
||||
- '[[family/projects/watchlist-automation]]'
|
||||
- '[[family/plans/watchlist-cleanup]]'
|
||||
@@ -23,6 +25,11 @@ related:
|
||||
> Radarr лежит с `disk I/O error`. `watchlist-nightly` и `watchlist-discover` остановлены.
|
||||
> Причина: `sync-down --batch 5` качал 5 фильмов ежедневно **без проверки свободного места**.
|
||||
|
||||
> **Три независимых дефекта (все найдены 2026-09-21 по коду):**
|
||||
> 1. **Нет проверки места** → диск забит под ноль (`sync_down.py`)
|
||||
> 2. **`mark_queued` молча проваливается** → 3 метки `⬇️` потеряны (`parser.py:77`)
|
||||
> 3. **Правила «ужасы не качаются» НЕТ в коде вообще** → `🧟♀️` только рисуется, фильтр отсутствует; `⭐` приоритетнее `🧟` тоже не реализовано
|
||||
|
||||
---
|
||||
|
||||
## Статус: Фаза 0 ожидает апрува Alex
|
||||
@@ -30,11 +37,14 @@ related:
|
||||
| Фаза | Что | Статус |
|
||||
|---|---|---|
|
||||
| 0 | Освободить место (удалить 5 remux = 403.4 ГБ) | 🔴 **ЖДЁТ АПРУВА** |
|
||||
| 0b | Снять `⬇️` у Неистового в watchlist | ⏸ после Фазы 0 |
|
||||
| 1 | `MIN_FREE_GB` в скрипт (стоп-кран) | ⏸ |
|
||||
| 2 | Лимит размера файла | ❌ **НЕ ДЕЛАЕМ** — Alex: «лимит качества и так настроен» |
|
||||
| 3 | Починить `cleanup` (видит только Radarr) | ⏸ отдельно |
|
||||
| 4 | Вернуть крон с меньшим `--batch` | ⏸ после Фазы 1 |
|
||||
| 0b | Снять `⬇️` у Шиндлера (396) + Неистового (107) | ⏸ после Фазы 0 |
|
||||
| 1 | **Фикс `mark_queued`** — эмодзи-префиксы + возврат `bool` + лог провала | ⏸ **НОВОЕ** |
|
||||
| 2 | `MIN_FREE_GB` в скрипт (стоп-кран) | ⏸ |
|
||||
| 2b | Лимит размера файла | ❌ **НЕ ДЕЛАЕМ** — Alex: «лимит качества и так настроен» |
|
||||
| 3 | **Фильтр ужасов + приоритет `⭐ > 🧟`** (правило новое, в коде его нет) | ⏸ **НОВОЕ** |
|
||||
| 3b | Починить `cleanup` (видит только Radarr) | ⏸ отдельно |
|
||||
| 4 | Восстановить 3 потерянные `⬇️` (Babylon, Midsommar, Triangle) | ⏸ после Фазы 1 |
|
||||
| 5 | Вернуть крон с `--batch 2` | ⏸ после Фаз 1–2 |
|
||||
|
||||
**Сделано 2026-09-21:** крон `watchlist-nightly` + `watchlist-discover` остановлен.
|
||||
Бэкап crontab: `~/crontab-backup-20260921.txt`.
|
||||
@@ -68,21 +78,32 @@ related:
|
||||
|
||||
**Признак remux — имя файла:** `Remux` / `BDREMUX` / `BDRemux` / `BD-Remux`.
|
||||
|
||||
### 🔴 Метки `⬇️` в watchlist — есть только у одного из пяти
|
||||
### 🔴 Метки `⬇️` — факт: у 3 из 5 метки ПОТЕРЯНЫ (баг `mark_queued`)
|
||||
|
||||
`family/documents/movies-watchlist.md`:
|
||||
`family/documents/movies-watchlist.md` — **все 5 фильмов есть в списке** (проверено `grep` по ru+en):
|
||||
|
||||
| Фильм | Строка | Метка |
|
||||
| Фильм | Строка | Метка `⬇️` |
|
||||
|---|---|---|
|
||||
| Неистовый (Unhinged) | 107: `- [x] ⬇️ Неистовый` | ✅ |
|
||||
| Babylon (2022) | 83: `- [ ] Babylon (2022)` | ❌ |
|
||||
| Midsommar | 81: `- [ ] 🧟♀️ midsommar 2019` | ❌ |
|
||||
| Triangle of Sadness | 82: `- [ ] Triangle of Sadness 2022` | ❌ |
|
||||
| Schindler's List | — | **отсутствует в файле** |
|
||||
| Неистовый (Unhinged) | 107: `- [x] ⬇️ Неистовый` | ✅ есть |
|
||||
| Список Шиндлера | 396: `- [ ] ⬇️ Список Шиндлера` | ✅ есть |
|
||||
| Babylon (2022) | 83: `- [ ] Babylon (2022)` | ❌ **потеряна** |
|
||||
| Midsommar | 81: `- [ ] 🧟♀️ midsommar 2019` | ❌ **потеряна** |
|
||||
| Triangle of Sadness | 82: `- [ ] Triangle of Sadness 2022` | ❌ **потеряна** |
|
||||
|
||||
`sync-down` ставит `⬇️` только на то, что добавил сам. Эти четыре попали в Radarr иначе.
|
||||
⚠️ **Питфолл поиска:** Шиндлер записан **по-русски** («Список Шиндлера»). `grep -i schindler` его **не находит** → ошибочный вывод «фильма нет в списке». Искать и ru, и en.
|
||||
|
||||
**Решение Alex:** снять `⬇️` (там, где есть). `[x]` у Неистового **не трогать** — это отметка просмотра.
|
||||
**Корень потери меток — баг `mark_queued` (`parser.py:77`):**
|
||||
```python
|
||||
pattern = re.compile(r'(^\s*-\s*\[ \]\s*)(' + re.escape(title) + r')', re.MULTILINE)
|
||||
new_text = pattern.sub(r'\1⬇️ \2', text, count=1)
|
||||
if new_text != text:
|
||||
path.write_text(new_text) # ← молча ничего, если не совпало
|
||||
```
|
||||
1. Между `]` и названием бывает **эмодзи-маркер** (`🧟♀️`, `✭`) → regex не матчит. Строка `- [ ] 🧟♀️ midsommar 2019` не подпадает.
|
||||
2. `title` может не совпадать буквально (год/скобки) → не матчит.
|
||||
3. **Тихий провал:** нет ошибки, нет лога. `sync_down.py` вызывает `mark_queued` (строки 98, 104, 113, 122) и **не проверяет результат** → считает, что всё ок.
|
||||
|
||||
**Решение Alex:** снять `⬇️` там, где есть (Шиндлер, Неистовый). `[x]` у Неистового **не трогать** — это отметка просмотра.
|
||||
|
||||
### Почему удаляем файлами, а не через Radarr API
|
||||
|
||||
@@ -95,7 +116,128 @@ Radarr **не отвечает** — диск в нуле, SQLite не може
|
||||
|
||||
---
|
||||
|
||||
## Фаза 1 — Стоп-кран `MIN_FREE_GB` (главный фикс)
|
||||
## Фаза 1 — Фикс `mark_queued` (корень потери меток) 🆕
|
||||
|
||||
**Файл:** `watchlist_sync/parser.py:77`
|
||||
|
||||
**Дефект:** regex ожидает название **сразу** после `- [ ]`, но в файле бывает эмодзи-маркер. Плюс тихий провал:
|
||||
```python
|
||||
pattern = re.compile(r'(^\s*-\s*\[ \]\s*)(' + re.escape(title) + r')', re.MULTILINE)
|
||||
new_text = pattern.sub(r'\1⬇️ \2', text, count=1)
|
||||
if new_text != text:
|
||||
path.write_text(new_text) # ← молча ничего, если не совпало
|
||||
```
|
||||
|
||||
**Что чинить:**
|
||||
```python
|
||||
# 1. Разрешить опциональные маркеры перед названием (в т.ч. ⭐ — он может стоять где угодно)
|
||||
pattern = re.compile(
|
||||
r'(^\s*-\s*\[ \]\s*)'
|
||||
r'([🧟♀️✭🗓️❓⭐]\s*)?'
|
||||
r'(' + escaped + r')',
|
||||
re.MULTILINE
|
||||
)
|
||||
# 2. Возвращать bool — вставилась ли метка
|
||||
# 3. При провале — log warning / raise, а не тишина
|
||||
```
|
||||
|
||||
**Плюс:** в `sync_down.py` (строки **98, 104, 113, 122** — четыре места) **проверять результат**:
|
||||
```python
|
||||
if not mark_queued(watchlist, item.title):
|
||||
print(f" [!] failed to mark ⬇️ for {item.title!r}")
|
||||
```
|
||||
|
||||
**Проверка:** прогнать на копии файла → убедиться, что 3 проблемные строки (81, 82, 83) получают метку.
|
||||
|
||||
⚠️ Наличие `⭐` в коде уже известно (`parser.py:_clean`): *«U+2B50 may sit ANYWHERE in the title ("Простите за беспокойство ⭐ 2018")»* → проверять **всю строку**, не только конец.
|
||||
|
||||
---
|
||||
|
||||
## Фаза 3 — Фильтр ужасов + приоритет `⭐ > 🧟` (ПРАВИЛО НОВОЕ) 🆕
|
||||
|
||||
**🔴 Установлено фактами: правила «ужасы не качаются» в коде НЕТ вообще.**
|
||||
|
||||
| Компонент | Есть? | Где |
|
||||
|---|---|---|
|
||||
| `is_horror()` — определяет жанр | ✅ | `resolver.py:43` (по жанрам TMDB, `27` = Horror) |
|
||||
| `mark_horror()` — ставит `🧟♀️` | ✅ | `parser.py:156`, вызов `cli.py:127` |
|
||||
| **Фильтр в `sync_down`** | ❌ **ОТСУТСТВУЕТ** | `sync_down.py` не вызывает `is_horror()` — проверено по всему файлу |
|
||||
|
||||
`🧟♀️` — **только визуальная метка**. Единственный фильтр в `sync_down` — `MIN_RATING` (строка 63).
|
||||
Поэтому **Midsommar скачался**, будучи помеченным `🧟♀️`.
|
||||
|
||||
**Правило, которое надо реализовать (сформулировано Alex 2026-09-21):**
|
||||
|
||||
| Случай | Действие |
|
||||
|---|---|
|
||||
| Ужас + `⭐` | **качаем** — `⭐` приоритетнее `🧟` |
|
||||
| Ужас без `⭐` | **пропускаем** |
|
||||
| Не ужас | качаем как обычно |
|
||||
|
||||
```python
|
||||
def should_skip_horror(candidate, raw_line: str) -> bool:
|
||||
if not candidate.is_horror():
|
||||
return False
|
||||
if '\u2b50' in raw_line: # ⭐ — явный приоритет пользователя
|
||||
return False
|
||||
return True # ужасы без ⭐ — пропускаем
|
||||
```
|
||||
|
||||
**Что нужно:**
|
||||
1. `parser.py` — читать наличие `⭐` **в любой позиции** строки → новое поле `priority: bool` в `WatchItem`
|
||||
2. `sync_down.py` — перед добавлением в Radarr: `if should_skip_horror(c, item.raw): continue`
|
||||
3. `cli.py` — при маркировке: ужас + `⭐` → `🧟♀️` **не навешивать**
|
||||
|
||||
---
|
||||
|
||||
## Фаза 4 — Восстановить потерянные `⬇️`
|
||||
|
||||
Три фильма без метки (после фикса `mark_queued` — правильным инструментом, не руками):
|
||||
- строка **83**: `Babylon (2022)`
|
||||
- строка **81**: `🧟♀️ midsommar 2019`
|
||||
- строка **82**: `Triangle of Sadness 2022`
|
||||
|
||||
**Проверка:** `grep` по каждой строке → метка на месте.
|
||||
|
||||
---
|
||||
|
||||
## Фаза 5 — Вернуть крон
|
||||
|
||||
После того как Фазы 1–2 проверены и стоп-кран работает:
|
||||
- вернуть строки `watchlist-nightly` (01:00) и `watchlist-discover` (вс 09:00) в crontab;
|
||||
- **снизить `--batch` с 5 до 2**.
|
||||
|
||||
---
|
||||
|
||||
## Фаза 3b — Починить `cleanup` (отдельно, осторожно)
|
||||
|
||||
**Дефект:** cleanup сопоставляет `[x]` из watchlist с **Radarr-библиотекой**, а просмотренное лежит в `/media/movies` (ручные торренты). Пересечение = 0 → удаляет 0 файлов.
|
||||
|
||||
**Замер 2026-09-21:** `watchlist [x] items: 177` / `radarr movies with file: 28` / `nothing to delete`.
|
||||
|
||||
**Это не причина инцидента** — cleanup не мог занять место, он только удаляет. Расширять его — отдельная задача, идёт после Фаз 0–2.
|
||||
|
||||
---
|
||||
|
||||
## Порог `MIN_FREE_GB` — ⏸ ожидает решения Alex
|
||||
|
||||
Предложение: **100 ГБ**. Alex ещё не подтвердил число.
|
||||
|
||||
---
|
||||
|
||||
## Уроки
|
||||
|
||||
1. **Любой скрипт, ставящий закачки в очередь, ОБЯЗАН проверять свободное место до добавления.** Лимита качества недостаточно — он про тип релиза, не про размер.
|
||||
2. **«Radarr молчит / I/O error» на заполненном диске — сначала проверить место**, потом конфиг и сеть.
|
||||
3. **Крон в 01:00 без присмотра = диск заполняется незаметно.** Тревога при >порога не настроена: cleanup писал «nothing to delete» и молчал.
|
||||
4. **Не выдавать догадки за факт.** Первая версия разбора указывала на `cleanup` как виновника — Alex поправил: cleanup удаляет, а не занимает. Виновник — `sync-down`.
|
||||
5. **Функция, которая «тихо ничего не делает» при провале — источник невидимых дефектов.** `mark_queued` молчал → 3 метки потеряны, никто не заметил. Возвращать `bool` и логировать.
|
||||
6. **Метка ≠ правило.** `🧟♀️` рисовалась, но фильтра не было — Midsommar скачался. Если метка должна что-то запрещать — запрет надо писать отдельно.
|
||||
7. **Искать и по-русски, и по-латинице.** `grep -i schindler` не нашёл «Список Шиндлера» → ложный вывод «фильма нет». Проверять оба написания перед любым утверждением.
|
||||
|
||||
---
|
||||
|
||||
## Фаза 2 — Стоп-кран `MIN_FREE_GB` (главный фикс заполнения)
|
||||
|
||||
**Цель:** перед добавлением фильма в Radarr проверить свободное место. Если мало — не добавлять.
|
||||
|
||||
@@ -131,33 +273,6 @@ Alex 2026-09-21: **«лимит качества и так настроен»**.
|
||||
|
||||
---
|
||||
|
||||
## Фаза 3 — Починить `cleanup` (отдельно, осторожно)
|
||||
|
||||
**Дефект:** cleanup сопоставляет `[x]` из watchlist с **Radarr-библиотекой**, а просмотренное лежит в `/media/movies` (ручные торренты). Пересечение = 0 → удаляет 0 файлов.
|
||||
|
||||
**Замер 2026-09-21:** `watchlist [x] items: 177` / `radarr movies with file: 28` / `nothing to delete`.
|
||||
|
||||
**Это не причина инцидента** — cleanup не мог занять место, он только удаляет. Расширять его — отдельная задача, идёт после Фаз 0–1.
|
||||
|
||||
---
|
||||
|
||||
## Фаза 4 — Вернуть крон
|
||||
|
||||
После того как Фаза 1 проверена и стоп-кран работает:
|
||||
- вернуть строки `watchlist-nightly` (01:00) и `watchlist-discover` (вс 09:00) в crontab;
|
||||
- **снизить `--batch`** (сейчас 5) — 5 фильмов/сутки без учёта размера и есть корень инцидента.
|
||||
|
||||
---
|
||||
|
||||
## Уроки
|
||||
|
||||
1. **Любой скрипт, ставящий закачки в очередь, ОБЯЗАН проверять свободное место до добавления.** Лимита качества недостаточно — он про тип релиза, не про размер.
|
||||
2. **«Radarr молчит / I/O error» на заполненном диске — сначала проверить место**, потом конфиг и сеть.
|
||||
3. **Крон в 01:00 без присмотра = диск заполняется незаметно.** Тревога при >порога не настроена: cleanup писал «nothing to delete» и молчал.
|
||||
4. **Не выдавать догадки за факт.** Первая версия разбора указывала на `cleanup` как виновника — Alex поправил: cleanup удаляет, а не занимает. Виновник — `sync-down`.
|
||||
|
||||
---
|
||||
|
||||
## Связанные заметки
|
||||
|
||||
- [[family/projects/watchlist-automation]] — полный pipeline, статус крона
|
||||
|
||||
@@ -49,6 +49,19 @@ related:
|
||||
- "Один день в Стамбуле"/"Рождественские хроники" — ремукс `-codec:v:0 copy` в HLS (не перекодирование), стоп на ~2-3 сек.
|
||||
- В моменте (пока ТВ крутит 720p) — ffmpeg-дочерних процессов нет, папка transcodes пуста → **прямой stream/direct, транскодинг не идёт**.
|
||||
|
||||
## 🧭 2026-09-21: развилка решена — многопоточный HLS не существует в Jellyfin/webOS
|
||||
|
||||
Перепроверено по первоисточникам (см. [[personal/tech/multistream-single-flow-limit]]):
|
||||
- Jellyfin «multiple parallel connections» — **Planned** 5 лет, кода нет (230 голосов).
|
||||
- hls.js multi-segment prefetch (#6753) — открыт, не реализован.
|
||||
- webOS-приложения используют **нативный media pipeline** → подменить логику загрузки нельзя.
|
||||
- **Несколько xray-туннелей не помогут** — один физический путь, одно congestion window.
|
||||
- Speedtest 120 Мбит = 8 параллельных сессий. Одна сессия упирается в **~28–45 Мбит** (подтверждено замерами ниже).
|
||||
|
||||
**Рабочие пути:** ограничить битрейт в клиенте / Moonfin с буфером / **Lampac на Кра́кене**
|
||||
(буфер 50–100 МБ + GStreamer транскод) / prefetch-proxy. Полный разбор — в
|
||||
[[personal/tech/multistream-single-flow-limit]].
|
||||
|
||||
## Решение / направление
|
||||
1. **Правильное лекарство** (не мультипоток ради мультипотока, а либо снижение латентности, либо запас по битрейту под single-flow): лимит транскода ~12–18 Мбит, ЛИБО гнать трафик ТВ→TrueNAS через **xray tunnel** (`vpn.mallexxx.duckdns.org`, смотри `[[xray-reverse-tunnel-kraken-truenas]]`) вместо прямого межоператорского пути.
|
||||
2. Jellyfin **не умеет** штатно разбивать один плейбек на параллельные TCP. Параллельность (28→51 Мбит) достижима только поднятием файла способом «качалка в N коннектов» + прокси, либо через туннель.
|
||||
|
||||
@@ -0,0 +1,196 @@
|
||||
---
|
||||
title: Многопоточный стриминг и обход single-flow лимита (Jellyfin / webOS / TorrServer)
|
||||
created: '2026-09-21'
|
||||
updated: '2026-09-21'
|
||||
type: research
|
||||
namespace: personal
|
||||
status: research-complete
|
||||
tags:
|
||||
- jellyfin
|
||||
- webos
|
||||
- streaming
|
||||
- tcp
|
||||
- lampa
|
||||
- torrserver
|
||||
- bandwidth
|
||||
related:
|
||||
- '[[personal/tech/inter-site-throughput-taiga-to-mac]]'
|
||||
- '[[personal/tech/xray-reverse-tunnel-kraken-truenas]]'
|
||||
- '[[family/how-to/kraken-network]]'
|
||||
---
|
||||
|
||||
# Многопоточный стриминг — что реально существует
|
||||
|
||||
> **Контекст:** Jellyfin на TrueNAS (Новосибирск) тормозит при просмотре из Бишкека.
|
||||
> Speedtest через reverse-туннель показывает **до 120 Мбит/с**, но видео дёргается.
|
||||
> Разбор: почему, и какие пути обхода существуют. Дата: 2026-09-21.
|
||||
|
||||
---
|
||||
|
||||
## 1. Почему speedtest 120 Мбит, а видео тормозит
|
||||
|
||||
**Speedtest открывает 8+ параллельных TCP-сессий.** Каждая независимо разгоняется своим congestion window.
|
||||
8 сессий × ~15 Мбит = 120 Мбит. Это доказывает, что **канал физически пропускает 120 Мбит**.
|
||||
|
||||
**Но одна TCP-сессия не берёт 120 Мбит.** Скорость ≈ окно / RTT. При RTT ~104 мс для 120 Мбит нужно
|
||||
окно ≈ 1.5 МБ «в полёте», не подтверждённых. Одна сессия разгоняется не сразу, при потерях окно режется
|
||||
вдвое, на межоператорском стыке потери почти всегда есть.
|
||||
|
||||
**Замеры межсайтовой пропускной способности (2026-09-02):**
|
||||
| Режим | Пропускная способность |
|
||||
|---|---|
|
||||
| Mac → TrueNAS, 1 SCP-поток | ~28 Мбит/с |
|
||||
| Mac → TrueNAS, 4 параллельных | ~51 Мбит/с (×1.8) |
|
||||
| Speedtest (8 потоков) | до 120 Мбит/с |
|
||||
|
||||
Рост ×1.8 при 4 потоках **доказывает**: ограничение — не полоса транзита, а **один TCP-поток при высоком RTT**.
|
||||
|
||||
**Аналогия (уточнена Alex):** не «узкая труба», а **8 касс, где канал пропустит 120 чел/мин —
|
||||
если открыты все 8. Один покупатель с одной корзиной в одной кассе уедет не быстрее этой кассы.**
|
||||
Узкое — не канал, а **одно соединение на длинном пути**.
|
||||
|
||||
---
|
||||
|
||||
## 2. Почему туннели не помогают
|
||||
|
||||
**Замеры 2026-09-02 через `xray-test-client`:**
|
||||
| Режим | Egress | Down | Стабильность |
|
||||
|---|---|---|---|
|
||||
| `kraken-user` (reverse) | `92.62.70.41` (Kraken) | ~45 Мбит | нестабилен, падал к 2 МБ/с |
|
||||
| `user1` (direct/REALITY) | `90.189.160.148` (TrueNAS) | ~37 Мбит | 3.67–5.63 МБ/с |
|
||||
| Контроль (Mac → Cloudflare напрямую) | — | ~55 МБ/с | — |
|
||||
|
||||
**VLESS/REALITY идёт через тот же маршрут** ТТК → Ростелеком (хоп 8, +50 мс). Меняется инкапсуляция,
|
||||
не физика. REALITY/Vision добавляет обёртки → обычно **чуть хуже** прямого, не лучше.
|
||||
|
||||
### 🔴 Несколько xray-туннелей НЕ дадут скорости
|
||||
|
||||
Это MPTCP/bonding — он агрегирует **разные физические пути**. Путь **один**.
|
||||
N туннелей по одному пути разделят тот же congestion window — суммарно не больше одного, плюс оверхед.
|
||||
Подтверждено замерами: reverse 45 и direct 37 — один коридор, не ×2.
|
||||
|
||||
**Реальная агрегация требует второго независимого линка** (мобильный 4G/5G как backup-WAN).
|
||||
|
||||
---
|
||||
|
||||
## 3. Многопоточный HLS — существует, но не реализован
|
||||
|
||||
| Решение | Статус |
|
||||
|---|---|
|
||||
| **Jellyfin** feature request «multiple parallel connections» | ✅ **Planned**, 230 голосов (features.jellyfin.org/posts/2171). Issue #3206 (2020) закрыт как stale. **5 лет, кода нет** |
|
||||
| **hls.js** issue #6753 (multi-segment prefetch) | Открыт Oct 2024, milestone 1.8.0, «Top priorities». **Кода нет, PR отсутствует** |
|
||||
| **ExoPlayer** #5978 (parallelize DASH/HLS) | Android, не webOS |
|
||||
|
||||
**Механизм, которого все ждут:** клиент тянет N сегментов одновременно → N независимых TCP-окон → 120 Мбит.
|
||||
**Ровно то, что нужно. Но нигде не реализовано.**
|
||||
|
||||
⚠️ **На webOS это безнадёжно:** приложения используют **нативный media pipeline** (Starfish / HTML5 `<video>`).
|
||||
Это чёрный ящик — подменить логику загрузки нельзя. Все клиенты (официальный, Moonfin, Breezyfin) одинаково
|
||||
однопоточны.
|
||||
|
||||
**Вывод: ждать нечего — ни от Jellyfin, ни от новых клиентов.**
|
||||
|
||||
---
|
||||
|
||||
## 4. Что реально умеет многопоток
|
||||
|
||||
| Решение | Многопоток | Пригодность |
|
||||
|---|---|---|
|
||||
| **aria2 / aria3** | ✅ до 16 соединений | Качает файл, не стримит в плеер |
|
||||
| **jspeedstreamer**, **node-HLS-Proxy** | ✅ параллельный prefetch сегментов | ✅ работает |
|
||||
| **nginx `proxy_cache` + `slice`** | ✅ кэш byte-ranges | ✅ база для prefetcher |
|
||||
| **Infuse (Apple TV)** | ✅ параллельные Range | ✅ но не webOS |
|
||||
| **Торрент (много пиров)** | ✅ N пиров = N соединений | ✅ по природе |
|
||||
| Jellyfin / Moonfin / Breezyfin | ❌ 1 соединение | — |
|
||||
| 8 xray-туннелей + mux | ❌ одно логическое окно | — |
|
||||
| MPTCP по одному пути | ❌ | — |
|
||||
|
||||
**Ключевое:** все рабочие многопоточные решения — **внешние прокси/префетчеры**, не клиенты.
|
||||
Прокси стоит рядом с клиентом, тянет параллельно, отдаёт из локального кэша.
|
||||
|
||||
---
|
||||
|
||||
## 5. Lampa + TorrServer + Lampac (webOS)
|
||||
|
||||
### TorrServer
|
||||
`YouROK/TorrServer` (3.0k★, GPL-3.0). Качает торрент, отдаёт HTTP-поток, управляет размером кэша.
|
||||
- Docker: `ghcr.io/yourok/torrserver:latest`, порт **8090**
|
||||
- Health check: `http://<ip>:8090/echo` → версия сервера
|
||||
- Флаги: `-d PATH` (БД/конфиг), `-a` (HTTP Auth), `-m BYTES` (макс. размер потока), `-t DIR` (автозагрузка), **`--gst`** (GStreamer HLS/fMP4 транскод, сборки 141.10+), `--proxyurl`
|
||||
- **Многопоточность по природе торрента** (каждый пир = отдельное соединение)
|
||||
|
||||
### Lampa
|
||||
UI-каталог. Установка на LG webOS: **Media Station X** или LG Content Store.
|
||||
⚠️ Установка `.ipk` с флешки на розничных LG **не работает**.
|
||||
- Настройки → **TorrServer** → «Использовать основную ссылку» → `kraken:8090`
|
||||
- **Проверка:** `http://<ip>:8090/echo`
|
||||
- **Буфер настраивается: 50–100 МБ** (Настройки → Плеер) ← **этого нет в webOS Jellyfin-клиенте**
|
||||
- Качество по скорости: до 10 Мбит → 720p; 10–25 → 1080p; >25 → 4K
|
||||
- Plugin API открыт (`window.Lampa`): `Lampa.Component.add`, `Lampa.Activity.push`, `Lampa.Controller.add`, `Lampa.Player.play`, `Lampa.Scroll`
|
||||
- Плагины: `etor` (TorrServer), `kinopoisk.js` (папка «Буду смотреть», **лимит 50**), `synology_dlna.js` (DLNA)
|
||||
|
||||
### 🔥 Lampac — всё в одном контейнере
|
||||
`immisterio/Lampac` / `lampac-nextgen/lampac` (MIT, .NET 10, порт **9118**).
|
||||
Внутри: **TorrServer** (subprocess) + **JacRed** (Jackett-совместимый индексатор) + **GStreamer транскод** +
|
||||
**DLNA** + **TmdbProxy** + **LampaWeb** (хостит UI, отдаёт `/lg.ipk` для LG).
|
||||
- Плагин для Lampa: `http://<IP>:9118/online.js`
|
||||
- Проверка: `curl -fsS "http://localhost:9118/version?type=hash"`
|
||||
- ⚠️ В контейнере рабочий каталог `/lampac`, файлы читаются **из корня**, не из `config/`. Volumes по умолчанию закомментированы
|
||||
|
||||
### ⚠️ Торрент-стримеры НЕ смотрят твою библиотеку
|
||||
Показывают **публичные раздачи**, не файлы с TrueNAS. Popcorn Time на webOS нэйтивно не было.
|
||||
|
||||
---
|
||||
|
||||
## 6. 🔴 TorrServer/Lampac на Кра́кене проблему НЕ решает
|
||||
|
||||
**Многопоточность торрента работает только на участке «пиры → TorrServer».**
|
||||
Участок **«Lampac/TorrServer → ТВ» — тот же один TCP-поток** через узкий линк.
|
||||
|
||||
```
|
||||
Lampac на Кра́кене: пиры → Кра́кен → [УЗКИЙ ЛИНК, single-flow] → ТВ ❌
|
||||
```
|
||||
**Но** Lampac даёт то, чего не было: **буфер 50–100 МБ** + **GStreamer HLS-транскод** — можно отдать
|
||||
ТВ лёгкий поток 10–15 Мбит, который проходит одним соединением.
|
||||
|
||||
**Это другое решение той же проблемы:** не «обойти узкий канал», а **«сделать поток достаточно лёгким»**.
|
||||
|
||||
---
|
||||
|
||||
## 7. Ранжированные пути (актуальный вывод)
|
||||
|
||||
| # | Путь | Усилие | Шанс |
|
||||
|---|---|---|---|
|
||||
| 1 | **Ограничить битрейт** в webOS-клиенте (10–15 Мбит) | 2 мин | Средний, работает сегодня |
|
||||
| 2 | **Moonfin / Breezyfin** — нативный pipeline, буфер | ~30 мин sideload | Средний |
|
||||
| 3 | **Lampac на Кра́кене** — буфер + GStreamer транскод | Среднее | Средний |
|
||||
| 4 | **Prefetch-proxy** (nginx slice / node-HLS-Proxy) | Высокое (пилить) | Высокий, но сложно |
|
||||
| 5 | **Второй ISP на TrueNAS** + MPTCP | Дорого | Единственный честный путь к агрегации |
|
||||
|
||||
---
|
||||
|
||||
## Факты webOS-клиентов (проверено)
|
||||
|
||||
| | **Moonfin** | **Breezyfin** |
|
||||
|---|---|---|
|
||||
| Версия | 2.5.1, 409★ | v0.2.1 (авг 2026), 63★, beta |
|
||||
| webOS | 3.0+ (2016+) | 5.0+ |
|
||||
| Движок | Starfish (нативный) | HTML5 + Enact Sandstone |
|
||||
| Транскод-лимит в UI | ✅ явно есть (`Transcoding Limits`) | не заявлен |
|
||||
| Диагностика «кто отказал в Direct Play» | ✅ **есть** (Diagnostics & Logging) | есть |
|
||||
| Jellyfin backend | 10.9.0+, Jellyfin 12 ✅ | 12 auth fix |
|
||||
| Установка без истечения | ✅ **Homebrew Channel** (не Dev Mode) | ✅ Homebrew catalog |
|
||||
|
||||
⚠️ **Dev Mode на LG истекает через 50 часов** → sideloaded app исчезает. **Homebrew Channel не истекает** —
|
||||
оба клиента есть в его каталоге.
|
||||
|
||||
⚠️ **Ни один не распараллеливает поток.** Кодеки определяет железо ТВ, не клиент.
|
||||
|
||||
---
|
||||
|
||||
## Связанные заметки
|
||||
|
||||
- [[personal/tech/inter-site-throughput-taiga-to-mac]] — замеры RTT/полосы Taiga ↔ Mac
|
||||
- [[personal/tech/xray-reverse-tunnel-kraken-truenas]] — reverse-туннель, замеры egress
|
||||
- [[family/how-to/kraken-network]] — линки ТВ, история торможения 4K
|
||||
- [[family/projects/media-toolbox-taiga]] — медиа-стек TrueNAS
|
||||
Reference in new issue
Block a user