--- title: metube section: music desc: MeTube — self-hosted веб-морда для yt-dlp; що вміє з коробки, де ламається, і як виглядає задизайнена під власну естетику копія на власному сервері. locked: false order: 1 featured: false --- # MeTube: своя веб-морда для yt-dlp [MeTube](https://github.com/alexta69/metube) — самохостований UI поверх `yt-dlp`. Не альтернатива yt-dlp, а обгортка: браузерна форма замість CLI, черга завантажень, підписки на канали й плейлисти. Список сайтів, з яких тягне, — [весь той, що підтримує сам yt-dlp](https://github.com/yt-dlp/yt-dlp/blob/master/supportedsites.md), не тільки YouTube. Розгорнуто на `tools.mandrock.me/ytdlp/` — без пароля, свідомо (особистий інструмент, не публічний сервіс). --- ## Що вміє з коробки - Відео, аудіо, субтитри, обкладинки — окремо чи разом. - Плейлисти й канали цілими пачками, з керованими шаблонами імен файлів. - Підписки: періодична перевірка каналу/плейлиста, нові відео стають у чергу автоматично — без ручного повторного запуску. - Три шари налаштувань `yt-dlp`, кожен наступний перекриває попередній: глобальні опції → пресети (обираються в UI) → разові оверрайди на конкретне завантаження. - Куки з браузера через **Advanced Options → Upload Cookies** — для приватного/віковообмеженого контенту. MeTube навмисно зупиняється, щойно файл записано: жодного тегування, жодної бібліотеки. Для аудіо — окремий інструмент поверх (beets, MusicBrainz Picard, Lidarr), не сюди. Ліцензія — AGPL-3.0. Публічний форк із модифікаціями (нижче) — не формальність, а вимога ліцензії: мережевий сервіс на зміненому коді зобов'язаний віддавати джерело. --- ## Свій скін Апстрім-образ (`ghcr.io/alexta69/metube`) замінено власним білдом: форк [0mandrock1/metube-mandrock0](https://github.com/0mandrock1/metube-mandrock0), фронтенд (Angular) переведений на токени й ембіент-шар власної дизайн-системи — `mandrock0-tokens.css` + `mandrock0-ambient.js`, той самий підхід, що на інших сторінках mandrock.me. Бекенд (сам `yt-dlp`-виклик, `app/`) не займано — змінено виключно `ui/`. Один новий CSS-файл ремапить наявні кольорові змінні MeTube (`--bs-*`, bootstrap-подібна тема) на токени дизайн-системи, замість переписування чужих SCSS. Світлу тему MeTube вимкнено — інструмент dark-only, перемикач теми прибрано з інтерфейсу. --- ## Коли ставити MeTube, а коли ні | Ситуація | Рішення | |---|---| | Один користувач, свій сервер, довіряєш мережі, де воно висить | MeTube як є — легкий, Docker, нічого зайвого | | Кілька людей мають ходити в один інстанс з різними правами | не MeTube — дивитись форки на кшталт `metube-extended` (multi-user, ролі, ізоляція черг) | | Публічний no-auth ендпоінт назовні | не робити, якщо це не свідомий вибір під VPN/особисту мережу — API нічим не захищений, крім того, що дав сам | | Потрібне тегування/бібліотека після завантаження | MeTube не про це — окремий інструмент (beets/Picard/Lidarr) поверх `AUDIO_DOWNLOAD_DIR` | | Треба надсилати посилання одним кліком (з телефону, з розширення) | браузерне розширення / bookmarklet / iOS Shortcut з офіційного списку, а не ручне вставляння URL | --- ## Антипатерни - **`CORS_ALLOWED_ORIGINS=*` + очікування, що креди пройдуть.** Wildcard навмисно блокує передачу кук/`Authorization` — це не баг, а захист від того, щоб будь-який відкритий сайт міг покерувати інстансом від імені сесії. Потрібні креди — переліковувати origin-и явно, не `*`. - **`ALLOW_PRIVATE_ADDRESSES=true` без розуміння, що це вимикає.** Захист від SSRF (заборона тягнути з внутрішніх/loopback адрес) вимикається цілком, не вибірково. Вмикати тільки коли трафік і так іде через контрольований проксі (fake-IP VPN-клієнт) — не «про всяк випадок». - **Reverse proxy без `Upgrade`/`Connection` заголовків.** MeTube тримає чергу через WebSocket; без прокидання цих двох заголовків проксі UI показує статичну сторінку, черга не оновлюється, і це виглядає як баг MeTube, а не конфіга nginx. - **Куки як «раз і назавжди».** Завантажений `cookies.txt` протухає за кілька годин — YouTube ротує кукі, поки живе сесія браузера-джерела. Форк уже несе `bgutil-ytdlp-pot-provider-rs` (self-contained POT provider, власний HTTP-сервер усередині контейнера) — цього досить для публічних відео взагалі без кук. Кукі вантажити тільки під контент, що реально вимагає залогованої сесії, і закладатись, що ця копія так само протухне за години — це властивість того, як YouTube прив'язує ротацію кук до клієнта-джерела, а не дірка в конфігурації. - **`ROBOTS_TXT` і no-auth разом без задуму.** Прев'ю-URL завантажень індексується, якщо не заблоковано явно, — на публічному (навіть без пароля, але видимому назовні) інстансі вартий уваги. --- ## Чекліст перед деплоєм своєї копії - [ ] Порт і `URL_PREFIX` узгоджені з реальним nginx `location` (обидва торкаються шляхів, які віддає UI) - [ ] `DOWNLOAD_DIR`/`STATE_DIR`/`TEMP_DIR` розведені по реальних дисках, якщо том один — усі три лишити дефолтними - [ ] Якщо позаду nginx — `proxy_set_header Upgrade`/`Connection "upgrade"` прописані, інакше черга не оновлюється - [ ] `CORS_ALLOWED_ORIGINS` — конкретні origin-и, не `*`, якщо потрібні креди (розширення/букмарклети зазвичай кредів не шлють, тож `*` їм і так підходить) - [ ] `ALLOW_PRIVATE_ADDRESSES` лишається `false`, якщо немає контрольованого проксі між контейнером і мережею - [ ] Публічний no-auth — усвідомлене рішення, не дефолт за забудькуватістю