30 KiB
title, created, updated, type, namespace, tags, related
| title | created | updated | type | namespace | tags | related | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Межсайтовая пропускная способность — TrueNAS (Taiga) ↔ Mac/TV | 2026-09-02 | 2026-09-21 | tech | personal |
|
|
Межсайтовая пропускная способность — TrueNAS ↔ Mac/TV
Контекст: после восстановления стека медиа/права на Taiga (см.
family/documents/vault-sync/2026-09-02-restore-privilege-scope.md) Jellyfin запустился и файлы читаются, но прямое воспроизведение с ТВ «грузится кусками». Диагностика 2026-09-02 установила: это НЕ транскодинг и НЕ тариф, а ограничение сети между двумя физически разнесёнными локальными сетями.
Cетевой layout (фактический)
| Узел | LAN | Шлюз | Egress IP | Провайдер |
|---|---|---|---|---|
| Mac / TV (дом) | 192.168.1.57 |
192.168.1.1 |
динамический | ТТК (92.62.x / 185.20.x) |
| TrueNAS (Taiga) | 192.168.2.197 |
192.168.2.2 |
90.189.160.148 (mallexxx.duckdns.org) |
Ростелеком (194.186.x → 217.107.x) |
Ключевое: TrueNAS НЕ в локальной сети Мака/ТВ. Трафик ТВ→Jellyfin идёт целиком по интернету между двумя разными операторами/домохозяйствами.
Замеры (2026-09-02)
Задержка / маршрут
- RTT Mac → TrueNAS: ~104 мс.
- Traceroute: хопы 1–7 моего ISP (ТТК) — 3–6 мс ✅ чисто. На хопе 8 (
194.186.168.65) прыжок до ~54 мс — межоператорская передача в сеть Ростелекома, где живёт TrueNAS. Хоп 10 (217.107.108.41) ~60 мс. - Этот +50 мс — физическое/пиринговое расстояние между региональными операторами, НЕ петля. Перенастройка маршрута полностью RTT не уберёт.
- Примечание: дальние сети в целом (8.8.8.8 ~100 мс) у ТТК тоже идут через ~50 мс переход — деградация на стороне выхода, а не только до TrueNAS.
Пропускная способность (распутали про «тариф»)
- Mac download с CDN: ~78 Мбит/с (линия Мака в порядке).
- TrueNAS сторона: NIC
enp3s01 Gb/s, до шлюза 0.2–0.8 мс 0% loss. NAS→Cloudflare: download ~184 Мбит/с, upload ~117 Мбит/с. → Лимита тарифа на TrueNAS НЕТ. - Mac → TrueNAS (SCP 200MB): ~28 Мбит/с одним потоком.
- Mac → TrueNAS, 4 параллельных SCP потока: ~28 → ~51 Мбит/с (агрегат растёт с параллельностью).
Вывод (важно)
Ограничение — НЕ по суммарной полосе транзита, а по одному TCP-потоку из-за высокого RTT (~104 мс) + BDP / congestion-window. Доказательство: 4 потока дали рост ×1.8 (28→51) — при жёстком лимите линии рост не произошёл бы.
Почему Jellyfin дёргается прямо: Jellyfin отдаёт видео одним последовательным HLS-потоком (один TCP). Один поток душится RTT-штрафом до ~28–50 Мбит, а BluRay-файл в пиках идёт к 20+ Мбит → с 104 мс RTT сегменты не успевают → стоп-кары. Файл The.Jungle.Book.1967.720p.BluRay ≈ 7.1GB/~78мин → средний ~12 Мбит/с, пики выше.
Факты ИЗ ЛОГОВ Jellyfin (подтверждают: транскодинг не причина в этих тестах)
- Реальный транскод с
libx264+ reduce был только на "Snatch" (тестовые короткие старты каждые ~5 с — клиент переподключался). - "Один день в Стамбуле"/"Рождественские хроники" — ремукс
-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.
Решение / направление
- Правильное лекарство (не мультипоток ради мультипотока, а либо снижение латентности, либо запас по битрейту под single-flow): лимит транскода ~12–18 Мбит, ЛИБО гнать трафик ТВ→TrueNAS через xray tunnel (
vpn.mallexxx.duckdns.org, смотри[[xray-reverse-tunnel-kraken-truenas]]) вместо прямого межоператорского пути. - Jellyfin не умеет штатно разбивать один плейбек на параллельные TCP. Параллельность (28→51 Мбит) достижима только поднятием файла способом «качалка в N коннектов» + прокси, либо через туннель.
- Задача замера скорости через
xray-test-clientконтейнер (teddysun/xray, SOCKS127.0.0.1:1080) — НЕ завершена: команда замера была заблокирована юзером; способ/endpoint (стучались на внутренний192.168.2.197:8096) предложен неверно.
Связанный локальный кейс (Kraken, same-LAN)
Тот же симптом «ТВ Jellyfin Direct Play дёргается» 2026-09-02, но в локальной сети (Kraken RPi5, дом) — причина ДРУГАЯ. См.
family/how-to/kraken-network.md. Как отличать кейсы: если Jellyfin-хост в одной LAN с ТВ (ping < ~10 мс) → дёрганье Direct Play почти всегда из-за линка 100 Мбит/с на сервере, а НЕ полосы/RTT. Проверка:cat /sys/class/net/<iface>/speed(это Kракен упал 1G→100M). Если хост в другой сети/операторе (ping ~104 мс, как Taiga) → ограничение по одному TCP-потоку из-за RTT. «99 Mbps» в UI = битрейт 4K remux-файла (обычно ~60–100 Mbps), НЕ скорость сети/линка.
Endpoint-факты для замера туннеля
- Локальный тестовый xray-клиент на Mac: контейнер
xray-test-client(127.0.0.1:1080->1080/tcp), конфиг/Users/admin/xray-test/config.json, оставлен наkraken-user. - Per-user egress на
vpn.mallexxx.duckdns.org:user1→ direct TrueNAS90.189.160.148;kraken-user→ reverse через Kraken92.62.70.41. - Конфиг клиента лежит на Mac отдельно (не в vault); бэкап direct-клиента:
/Users/admin/xray-test/config.json.bak-user1-direct-20260902-1227.
🔴 2026-09-21 — РАЗБОР: почему speedtest 120 Мбит ≠ Jellyfin не тормозит. Что делать
Контекст: Alex (Бишкек) сообщил, что плейбек Jellyfin на ТВ тормозит даже по проводу, но speedtest через reverse-туннель показал до 120 Мбит. Гипотеза Alex: «поднять реальный VPN в 192.168.2.x через VLESS и проверить, может заработает». Ниже — разбор, почему это не поможет, и что реально может.
❌ Что опровергнуто этой сессией
1. «Speedtest доказал, что 120 Мбит физически можно — значит туннель/multi-tunnel даст столько же». Speedtest гоняет 8 параллельных TCP-сессий, каждая со своим congestion window. 8 × ~15 Мбит = 120 Мбит. Это доказывает, что канал пропускает 120 Мбит суммарно. Это НЕ доказывает, что одна сессия получит 120 Мбит. Наши замеры это уже показывали: 1 поток = 28 Мбит, 4 потока = 51 Мбит (×1.8). Скорость TCP ≈ окно / RTT; при RTT 104 мс для 120 Мбит нужно окно ≈ 1.5 МБ «в полёте», одна сессия до такого не разгоняется при потерях на межоператорском стыке.
Правильная модель (не «узкая труба», а «кассы»): канал пропустит 120, но только если запрашивать 8 потоками одновременно. У Jellyfin — один покупатель в одной кассе.
2. «Поднять несколько xray-туннелей и распараллелить». Не сработает: физический путь один (ТТК → Ростелеком, хоп 8 = +50 мс). N туннелей по одному пути делят один congestion window → суммарно не больше, чем один, плюс накладные расходы. Это MPTCP/bonding-территория, а он агрегирует разные пути. Аналогия Alex «узкое место — линк между провайдерами» — верно; вывод «значит, надо прокинуть больше туннелей» — нет, линк пропускает 120 Мбит, но не одному потоку.
- Честный путь к «несколько путей» — только второй независимый линк (мобильный 4G/5G backup-WAN на TrueNAS) + MPTCP/OpenMPTCProuter.
3. «VLESS/REALITY-туннель уберёт лимит».
Уже проверено 2026-09-02 (см. раздел «Замеры скорости туннелей» в [[xray-reverse-tunnel-kraken-truenas]]): direct через vpn.mallexxx = ~37 Мбит, reverse через Kraken = ~45 Мбит. Оба — в том же коридоре, что и прямой путь (28 Мбит single-flow). Туннель идёт тем же маршрутом; REALITY/Vision добавляет обёртки и обычно чуть хуже прямого. Строить «реальный VPN в 192.168.2.x» смысла нет — он уже есть (vpn.mallexxx), и он не помог.
✅ Что реально работает — ранжировано
| # | Подход | Механизм | Усилие | Шанс |
|---|---|---|---|---|
| 1 | Лимит битрейта в клиенте (10–15 Мбит) | Транскод на TrueNAS; один поток 10 Мбит проходит с запасом ×3 | 2 мин | Высокий |
| 2 | Moonfin / Breezyfin (webOS-клиенты) | Нативный pipeline + транскод-лимит в UI + лог «кто отказал в Direct Play» | ~30 мин (Homebrew Channel) | Средний (диагностика) |
| 3 | Prefetch-proxy на стороне клиента | Прокси тянет файл/HLS 8 параллельными Range-запросами, отдаёт клиенту из локального кэша → клиент видит «быстрый сервер» | Высокое (писать/настраивать) | Средний |
| 4 | BBR + HTTP/3 на TrueNAS | BBR вместо CUBIC держит cwnd на long-haul; Caddy умеет HTTP/3, но webOS-клиент его не использует | 30 мин | +20–50%, не ×4 |
| 5 | Второй ISP + MPTCP | Настоящая агрегация разных путей | Очень высокое / деньги | Ноль без второго линка |
🔑 Ключевое различие для варианта 3 (и почему он единственный «правильный»)
Параллелизм рождается от независимых HTTP-запросов (каждый = своё TCP-окно), а НЕ от мультиплексирования транспорта.
- ✅ Клиент/prefetch-proxy делает 8 Range-запросов → 8 независимых окон → 120 Мбит возможно.
- ❌ 8 xray-туннелей + mux → одно логическое окно, порезанное на 8 → head-of-line blocking, выигрыша нет. Prefetch-proxy обязан стоять на стороне клиента (Mac/ТВ в Бишкеке), не на TrueNAS — иначе параллельные запросы всё равно идут через узкий канал по отдельности, выигрыш частичный.
🔴 КРИТИЧНО: клиент Alex — LG webOS (Jellyfin for WebOS 1.2.2)
Официальный webOS-клиент — обёртка вокруг веб-интерфейса, внутри один HTML5 <video> element = один TCP-поток. Ни настройки числа соединений, ни Range-префетча.
📋 Исследование альтернативных webOS-клиентов (2026-09-21)
Оба проверены по первоисточникам (GitHub/вики).
| Moonfin | Breezyfin | |
|---|---|---|
| Проект | Moonfin-Client/Smart-TV (общий код Tizen+webOS), 409★, 1153 коммита, 58 форков |
botagas/Breezyfin, 63★, 6 форков |
| Версия | 2.5.1 | v0.2.1 (21 авг 2026), beta, 112 коммитов сверх upstream |
| Сайт | moonfin.io | breezyfin.app |
| webOS | 3.0+ / 2016+ | 5.0+ |
| Движок | Enact/Sandstone + Starfish (нативный webOS pipeline) | Enact Sandstone, HTML5 + нативный webOS player |
| Параллельные потоки | ❌ НЕТ (один HTML5 video element) | ❌ НЕТ |
| Транскод-лимит в UI | ✅ есть (Playback & SyncPlay → Video Playback Preferences → Transcoding Limits: Max Streaming Bitrate / Max Resolution) | не заявлено явно |
| Лог «кто отказал в Direct Play» | ✅ есть (Settings > About > Diagnostics & Logging; отчёт называет причину отказа) | Есть diagnostics/logs, формулировка не заявлена |
| Fallback-цепочка | Direct Play → native transcode → hls.js | Direct Play → Direct Stream → Transcode + explicit consent перед HDR/DV-даунгрейдом |
| Jellyfin backend | минимум 10.9.0; Jellyfin 12 совместим (ApiKey) |
12 auth fix: legacy X-Emby-Authorization/X-Emby-Token за флагом EnableLegacyAuthorization (по умолчанию off) |
| Emby | ✅ | ❌ |
| codec-профиль | per-TV профиль, сообщается серверу; на webOS транскод fallback HEVC→H264, когда сервер запрещает HEVC; FLAC direct play в MP4/MKV на webOS 5+ (до 8 каналов) | adaptive; JASSUB Canvas2D для сабтитров (WebGL на webOS ненадёжен) |
| Аудио passthrough | DTS/DTS-HD/TrueHD bitstream; на webOS — экспериментально; Force TrueHD/Atmos | не заявлено |
| Сабтитры | PGS client-side, ASS/SSA через libass, DVD/DVB burn-in сервером, отдельный стиль для HDR | configurable client/bitmap |
| Live TV/DVR | ✅ (webOS 5+) | ❌ |
| SyncPlay | ✅ | ✅ (native Jellyfin SyncPlay + JellyWatchParty) |
| Установка | Homebrew Channel (не истекает) или Dev Manager Desktop / ares-install |
Homebrew catalog или IPK |
| Лицензия | MPL 2.0 | GPL-3.0-only |
Ключевой факт по установке: LG Developer Mode истекает каждые 50 часов → sideloaded-приложения удаляются. Homebrew Channel-путь НЕ истекает (root-эксплойт, не Dev Mode). Оба клиента есть в основном каталоге Homebrew Channel (repo.webosbrew.org). → Установка через Homebrew Channel убирает главный минус sideload.
Проверка через Homebrew-каталог: https://repo.webosbrew.org/apps/com.breezyfin.app/, https://repo.webosbrew.org/apps/org.jellyfin.webos/.
⚠️ Честный вывод по клиентам
Moonfin/Breezyfin НЕ дадут 120 Мбит — они не распараллеливают поток. Их ценность:
- Endpoint-лимит битрейта в UI — то же лекарство, что ручной лимит, но штатно.
- Лог «почему не Direct Play» — диагностика, которой у официального клиента нет. Сразу различит «сеть душит» vs «кодек/аудио отказали».
- Нативный pipeline вместо веб-обёртки → меньше оверхеда.
- Homebrew Channel = без истечения Dev Mode.
Настоящее распараллеливание остаётся только за prefetch-proxy (вариант 3) — клиенты его не заменяют.
Готовые инструменты для prefetch-proxy (найдены 2026-09-21)
aria3(PyPI) — multi-threaded streaming proxy с кэшем и умным prefetch.node-HLS-Proxy(warren-bank) — prefetch.ts-сегментов, hook-функции для управления префетчем.jspeedstreamer(conorh) — Java-прокси, multiple parallel requests.- nginx
proxy_cache+slice— кэширует byte-ranges, а не файлы целиком (штатный механизм под Range-prefetch). JellyfinCache(ArnyminerZ) — прокси-кэш между клиентом и Jellyfin-сервером. ⚠️ Ставится на стороне клиента, не сервера.
Предложенный план (НЕ начат, ждёт решения Alex)
- Проверить версию Jellyfin на TrueNAS (нужно ≥10.9.0 для Moonfin). ~2 мин, ничего не меняет.
- Поставить Moonfin через Homebrew Channel. ~30 мин.
- Включить Diagnostics & Logging, проиграть проблемный файл.
- Прочитать лог: кто отказал в Direct Play и почему.
- По результату: сеть → лимит битрейта или prefetch-proxy; кодек → подбор профиля.
Статус: план предложен, Alex решения не дал. Ничего не менялось — ни на TrueNAS, ни на ТВ, ни в туннелях.
❌ «Поднять несколько xray-туннелей» — почему НЕ поможет (разобрано 2026-09-21)
Прямой вопрос Alex: «что помешает поднять несколько xray tunnels и использовать их? в тесте speedtest 120mbit показывало через наш реверс туннель»
Ответ: ничего не помешает поднять, но скорости это не даст.
speedtest = 8 параллельных TCP-сессий, каждая со своим congestion window → 8 × ~15 Мбит = 120.
Это доказывает, что канал пропускает 120 Мбит. НЕ доказывает, что одна сессия их возьмёт.
Скорость одной TCP-сессии ≈ окно / RTT. Для 120 Мбит при RTT 104 мс нужно ~1.5 МБ неподтверждённых данных «в полёте». Одна сессия так разгоняется только при отсутствии потерь; на межоператорском стыке потери есть → окно режется вдвое → стабилизируется на 28–45 Мбит (наши замеры 2026-09-02). Jellyfin отдаёт видео одним потоком → упирается в это.
| Подход | Независимых окон | Даст 120 Мбит? |
|---|---|---|
| speedtest (8 сессий) | ✅ 8 | ✅ |
| Клиент с Range-запросами / prefetch-proxy | ✅ N | ✅ правильный путь |
| Jellyfin webOS штатный | ❌ 1 | ❌ ~28–45 |
| 8 xray-туннелей + mux | ❌ одно логическое окно | ❌ head-of-line blocking |
| MPTCP по одному физическому пути | ❌ | ❌ |
MPTCP/bonding агрегируют РАЗНЫЕ физические пути. У нас путь один: ТТК → Ростелеком (хоп 8, +50 мс). N туннелей по одному пути делят один congestion window → суммарно не больше одного, плюс оверхед инкапсуляции. Единственный честный путь к реальной агрегации — второй независимый ISP.
⚠️ Питфолл объяснения: аналогия «узкая труба» НЕ работает
Первое объяснение было через метафору трубы — Alex: «ниче не понял в твоей аналогии с трубой». Метафора прятала механизм. Рабочая формулировка — через ЧИСЛО СЕССИЙ: «канал пропускает 120 Мбит, но только если запрашивать 8 потоками ОДНОВРЕМЕННО; одна сессия возьмёт ~28–45, потому что не может разогнать своё окно на 104 мс RTT». Объяснять механизмом, не метафорой.
🔴 Многопоточный HLS в Jellyfin / hls.js — есть в планах, НЕ реализован
| Где | Статус | Факт |
|---|---|---|
| Jellyfin feature request #2171, 230 голосов | ✅ Planned (maintainer Joshua M. Boniface) | «Jellyfin currently streams using only one connection». Но issue #3206 (2020) закрыт как stale, #6724 — как feature request. За 5 лет кода нет. |
| hls.js issue #6753 (окт 2024) | milestone 1.8.0, «Top priorities», PR отсутствует | Предлагает префетч 2–5 сегментов одновременно («Concurrent Loading»). Ровно наш механизм — но не сделано |
| ExoPlayer issue #5978 | proposal | Параллельные DASH/HLS-сегменты. Android, не webOS |
| webOS-клиенты | ❌ невозможно | Нативный video element = чёрный ящик, число соединений не настраивается. Moonfin/Breezyfin/официальный — все однопоточны |
Вывод: ждать нечего. Ни от обновления Jellyfin, ни от новых клиентов. Реальные многопоточные решения — только внешние прокси/префетчеры (см. «Готовые инструменты для prefetch-proxy»).
🆕 Lampac — самохостируемый backend для Lampa (рассмотрен 2026-09-21, НЕ внедрён)
lampac-nextgen/lampac (форк immisterio/Lampac) — ASP.NET Core (.NET 10), MIT, linux/amd64+linux/arm64.
Порт по умолчанию 9118. Ставится одним контейнером и отдаёт плагины самой Lampa.
Закрывает сразу всё, что разбиралось по частям:
| Компонент | Что даёт |
|---|---|
| TorrServer | встроен как subprocess — отдельный контейнер не нужен |
| JacRed | агрегатор торрент-индексаторов, Jackett-совместимый |
| GStreamer | HLS/fMP4 транскод (заменяет legacy FFmpeg, плагин /gst.js) — решает MKV/HEVC-проблему webOS |
| LampaWeb | хостит саму Lampa UI + собирает widgets: /lg.ipk для LG webOS, /samsung.wgt для Tizen |
| TmdbProxy | локальный кэш TMDB API |
| DLNA/UPnP, Tracks, Sync, TimeCode, Playwright, WAF, GeoIP | прочее |
Установка (Docker):
git clone https://github.com/lampac-nextgen/lampac.git && cd lampac
mkdir -p lampac-docker/config lampac-docker/plugins
cp config/example.init.conf lampac-docker/config/init.conf
printf '%s' 'пароль_root' > lampac-docker/config/passwd
# раскомментировать volumes в docker-compose.yaml
docker compose up -d
curl -fsS "http://localhost:9118/version?type=hash" # проверка
# плагин для Lampa: http://<IP>:9118/online.js
⚠️ В контейнере рабочий каталог /lampac, файлы читаются из корня, не из config/. Volumes по умолчанию закомментированы.
🔴 Главное ограничение — Lampac НЕ решает проблему узкого канала сам по себе
TorrServer внутри Lampac работает на том же хосте, что и Lampac.
Lampac на Кра́кене: пиры → Кра́кен → [УЗКИЙ КАНАЛ, 1 TCP] → ТВ ← лимит остаётся
Lampac в Бишкеке: пиры → Mac → [быстрая локалка] → ТВ ← лимит обойдён
Alex отверг вариант с Mac: «нахуя нам блядь на маке что-то! на кракене блядь бэкенд». Значит Lampac на Кра́кене решает только участок «пиры → Кра́кен».
Но у Lampac есть то, чего не было в других вариантах: встроенный GStreamer HLS-транскод → можно отдать ТВ поток 10–15 Мбит одним потоком, и он пройдёт. Это не «обойти лимит», а «сделать поток лёгким» — другое решение той же проблемы.
🚧 Блокер на момент рассмотрения (снят 2026-09-21)
Диск Кра́кена был 100% (0 байт) → Lampac не поставить, TorrServer некуда кэшировать.
Плюс / (SD-карта) — всего 8.4 ГБ свободно, кэш торрентов туда не влезет.
Диск освобождён до 77% / 404 ГБ (см. family/plans/watchlist-disk-overflow-fix) — блокер снят,
но решение по Lampac ещё не принято.
Альтернатива: TorrServer прямо на ТВ
6ebeng/torrserver-webos — TorrServer как webOS-приложение (.ipk), webOS 4.x–9.x, rooted и unrooted.
Управление с любого устройства на http://<tv-ip>:8090. Бинарник зашит в .ipk (32-bit ARM), работает offline.
⚠️ Плеер — встроенный HTML5 <video>: «webOS has no API to hand stream URL to native player. MP4/H.264 plays
most reliably; MKV support depends on TV's Chromium» → MKV может не заиграть. Торрент тянется многопоточно
(N пиров = N окон), но контент берётся из публичных раздач, не из библиотеки на TrueNAS.
Итог по Lampac/TorrServer: концепция рабочая, решение не принято. Требует ответа Alex — что важнее: своя библиотека (тогда prefetch-proxy) или «просто смотреть кино» (тогда торрент-путь).