[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-80692":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":16,"stars7d":17,"stars30d":18,"stars90d":16,"forks30d":16,"starsTrendScore":19,"compositeScore":20,"rankGlobal":10,"rankLanguage":10,"license":21,"archived":22,"fork":22,"defaultBranch":23,"hasWiki":22,"hasPages":22,"topics":24,"createdAt":10,"pushedAt":10,"updatedAt":25,"readmeContent":26,"aiSummary":27,"trendingCount":16,"starSnapshotCount":16,"syncStatus":28,"lastSyncTime":29,"discoverSource":30},80692,"youthub","HelpFreedom\u002Fyouthub","HelpFreedom","YouHub — console YouTube client. TUI grid, custom ffplay-yt player, SABR streaming, SponsorBlock, 1080p.","",null,"Python",80,14,46,1,0,17,34,3,55.43,"GNU General Public License v3.0",false,"main",[],"2026-06-12 04:01:29","# YouHub — консольный YouTube-клиент\n\nПолноценный YouTube-клиент для терминала: TUI-сетка с превью, воспроизведение в 1080p, рекомендации, поиск, SponsorBlock, статистика просмотров — без браузера, без yt-dlp в пути воспроизведения.\n\n![License: GPL v3](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Flicense-GPLv3-blue.svg)\n\n![YouHub screenshot](screen.png)\n\n---\n\n## Что это\n\nYouHub — это терминальный YouTube, работающий целиком из консоли. Вместо браузера — kitty-терминал с сеткой превью, вместо веб-плеера — кастомный `ffplay-yt` (форк FFplay из FFmpeg 4.3.9 с IPC-расширениями). Видеопоток получается напрямую через реверс-инженерный протокол SABR (Server ABR) YouTube, без посредников вроде yt-dlp.\n\n### Ключевые особенности\n\n- **TUI-сетка** — адаптивная раскладка превью через kitty graphics protocol, навигация стрелками\u002Fhjkl\n- **Видео до 1080p60** — H.264 предпочтительно (быстрое декодирование), Opus-аудио\n- **Кастомный плеер** — `ffplay-yt` с боковой панелью рекомендаций, переключением скорости (1×\u002F1.5×\u002F2×), анимированными оверлеями\n- **SponsorBlock** — автоматический пропуск спонсорских вставок с визуальной индикацией\n- **Поиск** — встроенный поиск по YouTube прямо из сетки\n- **Бесконечная прокрутка** — лента подгружается автоматически при прокрутке вниз\n- **Превью при наведении** — через 3 секунды на тайле начинается слайд-шоу из 4 кадров с плавными кроссфейдами\n- **Перемотка** — стрелками влево\u002Fвправо (±5с\u002F±30с), с автоматическим перезапуском SABR-сессии при перемотке за пределы буфера\n- **Статистика просмотров** — просмотренные видео попадают в историю YouTube (влияют на рекомендации)\n- **OAuth через TV-пейринг** — «откройте youtube.com\u002Factivate и введите код», без хранения пароля\n- **Обход бот-стены** — 24 стратегии ротации TLS-отпечатков с автоматическим перебором\n- **Без постоянного браузера** — PO Token генерируется через bgutils-js + jsdom (без Playwright в рантайме)\n- **Поддержка прокси** — SOCKS5\u002FHTTP прокси через переменные окружения\n\n---\n\nПри нажатии Enter открывается окно ffplay-yt с видео и боковой панелью рекомендаций (Tab).\n\n---\n\n## Требования\n\n### Система\n\n- **Linux** (X11) — тестировалось на Debian 11\n- **Терминал kitty** >= 0.26 (нужен kitty graphics protocol)\n- **Python 3.11**\n- **Node.js** >= 18\n- **FFmpeg** >= 4.3 (системный, для мультиплексирования)\n- **SDL2** >= 2.0.14 (для ffplay-yt)\n- **xdotool**, **wmctrl** (управление окнами X11)\n\n### Опционально\n\n- **SOCKS5\u002FHTTP прокси** \n- **Шрифт DejaVu Sans** — для текста в панели рекомендаций (`fonts-dejavu` в Debian)\n\n---\n\n## Установка\n\n### 1. Клонирование\n\n```bash\ngit clone https:\u002F\u002Fgithub.com\u002FHelpFreedom\u002Fyouthub.git\ncd youthub\n```\n\n### 2. Python-окружение\n\n```bash\npython3.11 -m venv .venv\nsource .venv\u002Fbin\u002Factivate\npython3.11 -m pip install curl_cffi httpx Pillow\n```\n\n### 3. Node-зависимости\n\n```bash\nnpm install\n```\n\nЭто установит `youtubei.js`, `googlevideo`, `bgutils-js`, `jsdom`, `canvas` и выполнит post-install патч (`scripts\u002Fpatch_googlevideo.mjs`).\n\n### 4. Сборка ffplay-yt\n\nffplay-yt — это минимальная кастомная сборка FFplay из FFmpeg 4.3.9 с IPC-расширениями. Патченный исходник лежит в `ffplay-yt\u002Fffplay.c`.\n\n```bash\n# Скачиваем исходники FFmpeg 4.3.9\nmkdir -p ffplay-yt\u002Fsrc && cd ffplay-yt\u002Fsrc\napt source ffmpeg=7:4.3.9-0+deb11u2\n# Или: wget https:\u002F\u002Fffmpeg.org\u002Freleases\u002Fffmpeg-4.3.9.tar.xz && tar xf ffmpeg-4.3.9.tar.xz\ncd ffmpeg-4.3*\n\n# Подставляем патченный ffplay.c\ncp ..\u002F..\u002Fffplay.c fftools\u002Fffplay.c\n\n# Конфигурируем минимальную сборку\n.\u002Fconfigure \\\n  --disable-everything \\\n  --enable-gpl --enable-version3 \\\n  --enable-decoder=h264,vp9,libdav1d,opus,aac,mp3,mjpeg,png \\\n  --enable-demuxer=matroska,mov,webm \\\n  --enable-protocol=file,pipe,unix,fd \\\n  --enable-filter=aresample,scale,atempo,volume \\\n  --enable-parser=h264,vp9,opus,aac \\\n  --enable-libdav1d --enable-libopus \\\n  --enable-sdl2 --enable-ffplay \\\n  --enable-indev=alsa \\\n  --disable-doc --disable-htmlpages --disable-manpages \\\n  --disable-ffmpeg --disable-ffprobe\n\n# Сборка\nmake ffplay -j$(nproc)\n\n# Копируем бинарник\nmkdir -p ..\u002F..\u002Fbin\ncp ffplay ..\u002F..\u002Fbin\u002Fffplay-yt\ncd ..\u002F..\u002F..\n```\n\n**Зависимости сборки** (Debian\u002FUbuntu):\n\n```bash\nsudo apt install build-essential nasm \\\n  libsdl2-dev libdav1d-dev libopus-dev \\\n  libavcodec-dev libavformat-dev libswscale-dev libavutil-dev\n```\n\n### 5. Системные утилиты\n\n```bash\nsudo apt install xdotool wmctrl fonts-dejavu\n```\n\n### 6. Прокси (опционально)\n\nЕсли используете прокси, экспортируйте переменную:\n\n```bash\nexport HTTPS_PROXY=\"socks5:\u002F\u002F127.0.0.1:1080\"\n```\n\n---\n\n## Запуск\n\n```bash\n# Запуск в kitty-терминале\n.venv\u002Fbin\u002Fpython3.11 grid_demo.py\n```\n\n### Первый запуск — OAuth-пейринг\n\nПри первом запуске YouHub попросит авторизоваться через TV-пейринг:\n\n1. Откройте https:\u002F\u002Fyoutube.com\u002Factivate в браузере\n2. Введите отображённый код (формат `XXXX-XXXX`)\n3. Подтвердите доступ для аккаунта\n\nТокены сохраняются в `cache\u002Foauth.json` (chmod 600). Повторный пейринг нужен только если refresh token протухнет.\n\n### Cookie-аутентификация (для watchstats)\n\nДля атрибуции просмотров (чтобы видео попадали в историю YouTube) нужны cookie из Firefox:\n\n```bash\n# Экспортируйте cookie из Firefox\npython3.11 extract_cookies.py\n\n# Cookie сохраняются в cache\u002Fyt_cookies.txt (chmod 600)\n```\n\nОтключить watchstats: `export WATCHSTATS_COOKIES=0`\n\n---\n\n## Управление\n\n### Сетка (grid_demo.py)\n\n| Клавиша | Действие |\n|---------|----------|\n| `←↑↓→` \u002F `hjkl` | Навигация по тайлам |\n| `Enter` | Воспроизведение выбранного видео |\n| `f` \u002F `а` | Поиск по YouTube |\n| `r` \u002F `к` | Обновить ленту |\n| `PgUp` \u002F `PgDn` | Постраничная прокрутка |\n| `Home` | В начало |\n| `q` \u002F `й` | Выход |\n\n### Плеер (ffplay-yt)\n\n| Клавиша | Действие |\n|---------|----------|\n| `←` \u002F `→` | Перемотка ±5 сек |\n| `↓` \u002F `↑` | Перемотка ±30 сек |\n| `Space` | Пауза |\n| `1` | Скорость 1× |\n| `2` | Скорость 2× |\n| `3` | Скорость 3× |\n| `Tab` | Открыть\u002Fзакрыть панель рекомендаций |\n| `q` \u002F `Esc` | Выход из плеера |\n| `m` | Mute |\n| `9` \u002F `0` | Громкость −\u002F+ |\n\n### Утилитарные скрипты (bin\u002F)\n\n| Скрипт | Назначение |\n|--------|-----------|\n| `bin\u002Fyt-kill-video` | Принудительно закрыть окно ffplay (для привязки к dwm keybind) |\n| `bin\u002Fyt-toggle-overlay` | Скрыть\u002Fпоказать окно ffplay (map\u002Funmap, аудио продолжает играть) |\n\n---\n\n## Архитектура\n\n```\ngrid_demo.py   (TUI-сетка — kitty graphics protocol)\n      │\n      │ Enter → воспроизведение\n      ▼\nbridge_player.py   (оркестратор)\n      │\n      ├──→ sabr_bridge.mjs   (Node.js SABR-мост)\n      │        │\n      │        ├──→ po_token.mjs      (PO Token: bgutils-js + jsdom)\n      │        ├──→ pr_fetch.py       (playerResponse: curl_cffi, 24 стратегии)\n      │        ├──→ youtubei.js       (дешифровка n-параметра)\n      │        └──→ googlevideo       (SabrStream → fMP4-сегменты)\n      │                 │\n      │                 ▼\n      │           ffmpeg (мультиплексор) → \u002Ftmp\u002Fytlive_\u003Cid>.mkv\n      │\n      ├──→ ffplay-yt                  (плеер: SDL2 + IPC)\n      │        │\n      │        └──→ Unix socket       (POS, SEEK_REQ, OPEN, QUIT, RECS_ITEM...)\n      │\n      ├──→ recs_pipeline.py           (рекомендации для боковой панели)\n      ├──→ sponsorblock.py            (авто-пропуск спонсорских вставок)\n      └──→ watchstats.py              (пинги статистики просмотра)\n```\n\n### Видеопоток\n\n1. `pr_fetch.py` получает `ytInitialPlayerResponse` с YouTube через curl_cffi (реальные TLS-отпечатки Chrome\u002FFirefox\u002FSafari), обходя бот-стену\n2. `po_token.mjs` генерирует PO Token (Proof of Origin) через BotGuard-чаллендж в jsdom (без браузера)\n3. `sabr_bridge.mjs` использует `youtubei.js` для дешифровки URL и `googlevideo` SabrStream для потоковой загрузки H.264+Opus через протокол SABR\n4. `ffmpeg` мультиплексирует видео и аудио в растущий `.mkv`-файл\n5. `ffplay-yt` воспроизводит этот файл, общаясь с `bridge_player.py` через IPC-сокет\n\n### Обход бот-стены YouTube\n\nYouTube блокирует автоматизированные запросы по TLS-отпечатку (JA3\u002FJA4). Система ротации в `pr_fetch.py` использует 24 стратегии:\n\n- **12 TLS-баз**: 7 HTML-скрейпинг (`chrome131`, `chrome145`, `firefox133`, `safari184`, `safari180_ios`, `chrome131_android`, `edge101`) + 5 InnerTube POST (`ANDROID_VR`, `IOS`, `MWEB`, `TVHTML5`, `WEB_EMBEDDED_PLAYER`)\n- **2 режима прокси**: напрямую \u002F через `HTTPS_PROXY`\n- **Предварительное чередование**: соседние стратегии отличаются и по TLS-семейству, и по прокси\n- **Липкий выбор**: рабочая стратегия используется пока не заблокируют\n- **Полный перебор**: при воспроизведении перебираются все 24 стратегии за один клик\n\nСостояние ротации сохраняется между сессиями в `cache\u002Fstrategy_state.json`.\n\n---\n\n## Структура файлов\n\n### Основной конвейер\n\n| Файл | Назначение |\n|------|-----------|\n| `grid_demo.py` | Главная точка входа — TUI-сетка с навигацией |\n| `bridge_player.py` | Оркестратор воспроизведения (мост, плеер, SponsorBlock, рекомендации) |\n| `sabr_bridge.mjs` | Персистентный Node.js SABR-стриминг-мост |\n| `pr_fetch.py` | Получение playerResponse с ротацией TLS-стратегий |\n| `po_token.mjs` | Генерация PO Token без браузера (bgutils-js + jsdom) |\n| `po_minter.mjs` | Чеканка PO Token из готового integrity token |\n| `sponsorblock.py` | Клиент SponsorBlock API (авто-пропуск спонсорских вставок) |\n| `recs_pipeline.py` | Получение и рендеринг рекомендаций для боковой панели |\n| `watchstats.py` | Пинги статистики просмотра (история YouTube) |\n| `auth_cookies.py` | Cookie-аутентификация с SAPISIDHASH |\n\n### Модуль `youthub\u002F`\n\n| Файл | Назначение |\n|------|-----------|\n| `innertube.py` | Клиент InnerTube API (TVHTML5): home, search, next, player |\n| `auth.py` | OAuth 2.0 Device Grant (TV-пейринг) |\n| `feed.py` | Парсер ответов InnerTube в структуры Video\u002FShelf\u002FFeed |\n| `feed_loader.py` | Движок бесконечной прокрутки |\n| `graphics.py` | Kitty Graphics Protocol (передача PNG в терминал) |\n| `terminal.py` | Размер терминала, KeyReader (raw-ввод + UTF-8) |\n| `thumbnails.py` | Дисковый кэш превью с параллельной предзагрузкой |\n| `preview.py` | Слайд-шоу при наведении (4 кадра с кроссфейдами) |\n\n### Кастомный плеер\n\n| Файл | Назначение |\n|------|-----------|\n| `ffplay-yt\u002Fffplay.c` | Патченный FFplay: IPC-сокет, боковая панель, оверлеи, анимации |\n\n### Вспомогательное\n\n| Файл | Назначение |\n|------|-----------|\n| `sabr.py` | Чисто-питоновский клиент протокола SABR (research\u002Ffallback) |\n| `proto_edit.py` | Round-trip библиотека для Protobuf |\n| `proto_dump.py` | Инспектор Protobuf-сообщений |\n| `bootstrap.py` | Browser-based bootstrap (legacy, для отладки) |\n| `extract_cookies.py` | Экспорт cookie из Firefox |\n| `scripts\u002Fpatch_googlevideo.mjs` | Post-install патч для npm-пакета googlevideo |\n\n### Утилиты диагностики\n\n| Файл | Назначение |\n|------|-----------|\n| `ump_extract.py` | Извлечение медиа-треков из UMP-потока |\n| `ump_inspect.py` | Инспектор UMP-сообщений |\n| `probe_potoken.py` | Диагностика PO Token |\n| `protocol_dump.py` | Запись сетевого трафика YouTube |\n| `verify_history.py` | Проверка попадания видео в историю YouTube |\n\n### Тесты\n\n| Файл | Назначение |\n|------|-----------|\n| `test_innertube.py` | Тест InnerTube API + OAuth-пейринг |\n| `test_tvpair.py` | Тест TV Device Grant (проверка client_id) |\n| `test_cookieexchange.py` | Тест обмена cookie |\n| `test_cookieping.py` | Тест пинга с cookie |\n| `test_logevent.py` | Тест отправки событий |\n\n### Ранние прототипы\n\n| Файл | Назначение |\n|------|-----------|\n| `player.py` | Первый плеер (yt-dlp + ffplay) |\n| `tui_player.py` | Видео целиком в терминале через kitty graphics |\n| `stream_player.py` | Стриминг через FIFO (заменён bridge_player) |\n| `live_stream.py` | Стриминг live-трансляций через Playwright |\n\n---\n\n## Кэширование\n\nВсе кэши хранятся в `cache\u002F` (создаётся автоматически):\n\n| Файл | TTL | Описание |\n|------|-----|----------|\n| `oauth.json` | до отзыва | OAuth-токены (chmod 600) |\n| `yt_cookies.txt` | до протухания | Cookie Firefox (chmod 600) |\n| `strategy_state.json` | постоянно | Состояние ротации TLS-стратегий |\n| `innertube_home.json` | 120 сек | Кэш домашней ленты |\n| `innertube_next.json` | 120 сек | Кэш \u002Fnext pivot |\n| `pr_\u003Cvid>.json` | 12 часов | Кэш playerResponse |\n| `sponsorblock_\u003Cvid>.json` | 24 часа | Кэш сегментов SponsorBlock |\n| `thumbnails\u002F\u003Cvid>.jpg` | бессрочно | Превью-изображения |\n| `recs_thumbs\u002F\u003Cvid>.jpg` | бессрочно | Превью для боковой панели |\n| `recs_text\u002F\u003Cvid>.png` | бессрочно | Текстовые полоски рекомендаций |\n\n---\n\n## Анимации ffplay-yt\n\nКастомный ffplay-yt включает несколько анимированных оверлеев, рендерящихся через SDL2:\n\n### Переключение скорости (клавиши 1\u002F2\u002F3)\nПолупрозрачная капсула с текущей скоростью (`1.0×`, `1.5×`, `2.0×`) — ease-out-back анимация с «пружинящим» эффектом, длительность 0.85 сек.\n\n### Слайд боковой панели (Tab)\nПанель рекомендаций выезжает справа с ease-out-cubic анимацией (0.22 сек). Видео плавно сдвигается влево.\n\n### Перемотка (стрелки)\nДва шеврона (`▶▶` \u002F `◀◀`) с текстом (`+5s`, `-30s`) — fade-in\u002Ffade-out, 0.7 сек.\n\n### SponsorBlock-пропуск\nЦветная метка категории + «skipped Xs» внизу экрана — выезд снизу, 1.6 сек. Цвет зависит от типа: sponsor=зелёный, selfpromo=жёлтый, intro=циановый, outro=синий и т.д.\n\nВсе оверлеи рендерятся через встроенный 3×5 bitmap-шрифт (`SPEED_GLYPH[16][5]`) и примитивы SDL_RenderFillRect (совместимость с SDL 2.0.14, без SDL_RenderGeometry).\n\n---\n\n## Технические решения\n\n1. **Без yt-dlp в пути воспроизведения** — прямой SABR через `googlevideo` npm-пакет\n2. **Без mpv** — кастомный ffplay-yt с IPC, полный контроль\n3. **Без постоянного браузера** — PO Token через bgutils-js + jsdom (BotGuard JS в headless DOM)\n4. **H.264 вместо VP9** — в 2-3× быстрее программное декодирование, запас для atempo\n5. **Растущий файл** — ffmpeg пишет .mkv, ffplay читает по мере роста. Перемотка за буфер → новая сессия (OPEN по IPC)\n6. **24 стратегии ротации** — TLS × прокси × эндпоинт, липкий выбор + полный перебор при неудаче\n7. **Cookie-based watchstats** — настоящие пинги `\u002Fapi\u002Fstats\u002Fwatchtime` с SAPISIDHASH\n8. **Только чтение** — никаких лайков\u002Fкомментариев\u002Fподписок. Kill-switch `WATCHSTATS_COOKIES=0`\n\n---\n\n## Безопасность\n\n- OAuth-токены и cookie хранятся с правами `chmod 600`\n- Используются только read-only API-эндпоинты (статистика просмотра)\n- Нет записи лайков, комментариев, подписок\n- Kill-switch `WATCHSTATS_COOKIES=0` полностью отключает отправку cookie\n- client_id для TV-пейринга — публичный (Kodi\u002FSmartTubeNext), не требует собственного Google Cloud-проекта\n- API-ключи в коде — стандартные публичные ключи YouTube (InnerTube, BotGuard), не являются секретами\n\n---\n\n## Переменные окружения\n\n| Переменная | По умолчанию | Описание |\n|-----------|-------------|----------|\n| `HTTPS_PROXY` | — | URL прокси (`socks5:\u002F\u002Fhost:port` или `http:\u002F\u002Fhost:port`) |\n| `WATCHSTATS_COOKIES` | `1` | `0` = отключить отправку watchstats |\n\n---\n\n## Известные ограничения:\n\n- Только X11 (Wayland не тестировался)\n- Только терминал kitty (нужен graphics protocol)\n- Без аппаратного ускорения декодирования (только CPU)\n- Без поддержки DRM-контента (YouTube Premium Originals)\n- Перемотка за пределы буфера занимает 1-3 секунды (перезапуск SABR-сессии)\n- YouTube периодически меняет протоколы — может потребоваться обновление `youtubei.js` \u002F `googlevideo`\n\n---\n\n## Авторы\n\n- **Black Triangle** — автор и архитектор проекта\n- **Claude** (Anthropic) — со-разработчик, ассистент по коду\n\n---\n\n## Лицензия\n\nGNU General Public License v3.0 — см. [LICENSE](LICENSE).\n\n---\n\n## Благодарности\n\n- [youtubei.js](https:\u002F\u002Fgithub.com\u002FLuanRT\u002FYouTube.js) — дешифровка подписей и n-параметра\n- [googlevideo](https:\u002F\u002Fgithub.com\u002Fnicholasgasior\u002Fgooglevideo) — клиент протокола SABR\n- [bgutils-js](https:\u002F\u002Fgithub.com\u002Fnicholasgasior\u002Fbgutils-js) — BotGuard challenge solver\n- [curl_cffi](https:\u002F\u002Fgithub.com\u002Fyifeikong\u002Fcurl_cffi) — HTTP с реальными TLS-отпечатками\n- [SponsorBlock](https:\u002F\u002Fsponsor.ajay.app\u002F) — краудсорсинговая база спонсорских сегментов\n- [FFmpeg](https:\u002F\u002Fffmpeg.org\u002F) — основа ffplay-yt\n","YouHub 是一个基于终端的YouTube客户端，允许用户在命令行环境中浏览和播放YouTube视频。它采用TUI网格界面展示视频预览，并通过自定义的`ffplay-yt`播放器支持高达1080p60的视频播放。项目利用SABR流媒体技术直接从YouTube获取视频流，无需依赖yt-dlp等中间件，同时集成SponsorBlock功能自动跳过赞助内容。此外，YouHub还提供搜索、无限滚动加载、鼠标悬停预览等功能，增强了用户体验。该项目特别适合那些偏好使用命令行工具或需要在资源受限环境下访问YouTube内容的用户。",2,"2026-06-11 04:01:39","CREATED_QUERY"]