109 lines
3.7 KiB
Markdown
109 lines
3.7 KiB
Markdown
---
|
||
title: Jellyfin Транскод на RPi5 — PGS/Subtitle Pitfalls
|
||
type: reference
|
||
namespace: work
|
||
tags:
|
||
- jellyfin
|
||
- kraken
|
||
- transcode
|
||
- subtitles
|
||
- pitfalls
|
||
created: '2026-05-18'
|
||
updated: '2026-05-18'
|
||
---
|
||
# Jellyfin Транскод на RPi5 — PGS/Subtitle Pitfalls
|
||
|
||
## Контекст
|
||
|
||
Клиент: Konka TV с WebOS. Сервер: Raspberry Pi 5 (Крaken, ARM64).
|
||
|
||
## Direct Play условия
|
||
|
||
Direct Play работает при выполнении всех условий:
|
||
- Аудио: AAC
|
||
- Субтитры: **отсутствуют** (или внешние SRT, без burn-in)
|
||
|
||
## Проблема PGS/ASS субтитров
|
||
|
||
PGS и ASS (SSA) субтитры вызывают **burn-in** — Jellyfin рендерит субтитры прямо в видеопоток.
|
||
|
||
**Результат:** полный транскод на CPU → **275% CPU load** на RPi5 → лаги, перегрев.
|
||
|
||
**Экспериментальный PGS rendering** в настройках Jellyfin — **не помогает** на RPi5.
|
||
|
||
## Решение: конвертация PGS → SRT
|
||
|
||
Установка через uv (arm64/aarch64 совместимо):
|
||
```bash
|
||
~/.local/bin/uv tool install pgsrip
|
||
sudo apt-get install -y libgl1 libglib2.0-0 tesseract-ocr tesseract-ocr-rus tesseract-ocr-eng
|
||
```
|
||
|
||
Скрипт конвертации:
|
||
```
|
||
/srv/dev-disk-by-uuid.../docker/media-pipeline/pgs-to-srt.sh
|
||
```
|
||
|
||
```bash
|
||
# один файл
|
||
pgs-to-srt.sh /media/movies/Film.mkv
|
||
|
||
# вся директория
|
||
pgs-to-srt.sh /media
|
||
```
|
||
|
||
Логи: `/srv/.../docker/media-pipeline/pgs-to-srt.log`
|
||
|
||
Скрипт:
|
||
- Скипает файлы без PGS-дорожек (S_HDMV)
|
||
- Скипает если .srt уже есть рядом
|
||
- Пишет лог с timestamp
|
||
|
||
После конвертации Jellyfin читает внешние `.srt` без транскода.
|
||
|
||
## Transmission completion hook
|
||
|
||
Хук `/config/on-download-complete.sh` (монтируется в контейнер `:ro`) после завершения загрузки:
|
||
1. Запускает media-pipeline sync
|
||
2. Запускает pgs-to-srt.sh для скачанного файла/директории
|
||
|
||
Лог: `/srv/.../docker/media-pipeline/download-complete.log`
|
||
|
||
## Итог по субтитрам
|
||
|
||
| Тип | Direct Play | Транскод |
|
||
|-----|------------|---------|
|
||
| Нет субтитров | ✅ | — |
|
||
| Внешний SRT | ✅ | — |
|
||
| ASS/SSA | ❌ | burn-in, 275% CPU |
|
||
| PGS (MKS/MKV) | ❌ | burn-in, 275% CPU |
|
||
|
||
## NFD/NFC filename encoding pitfall
|
||
|
||
**Проблема:** HTPC сохраняет имена файлов в NFD, Kraken — в NFC.
|
||
→ Jellyfin видит **две** папки: одна с `.avi` файлом (NFD), другая с `.nfo` (NFC).
|
||
→ NFO не применяется — Jellyfin берёт NFD-папку (с видео) и игнорирует NFC-папку (с NFO).
|
||
→ Метаданные пустые.
|
||
|
||
**Фикс A (быстрый):** скопировать `movie.nfo` + `poster.jpg` в NFD-папку:
|
||
```bash
|
||
# python3 — использовать bytes для путей
|
||
import os, shutil
|
||
nfc_path = "…/Movie.NFC/movie.nfo"
|
||
nfd_path = "…/Movie.NFD/movie.nfo"
|
||
shutil.copy(nfc_path.encode(), nfd_path.encode())
|
||
```
|
||
|
||
**Фикс B (радикальный):** переименовать всё в NFC (нормализовать).
|
||
|
||
**Диагностика:**
|
||
```bash
|
||
ls -la | cat -v # покажет NFD-escape символы как ^ escape sequences
|
||
python3 -c "import os; [print(repr(f)) for f in os.listdir('.')]"
|
||
```
|
||
|
||
## Связанные страницы
|
||
|
||
- [[concepts/kraken-media-stack]] — полный медиастек: *arr + Jellyfin + media-pipeline
|
||
- [[tech/kraken-network]] — инфра Кракена, HDD error recovery
|