MeTube: своя веб-морда для yt-dlp
MeTube — самохостований UI поверх yt-dlp. Не альтернатива yt-dlp, а обгортка: браузерна форма замість CLI, черга завантажень, підписки на канали й плейлисти. Список сайтів, з яких тягне, — весь той, що підтримує сам yt-dlp, не тільки 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, фронтенд (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узгоджені з реальним nginxlocation(обидва торкаються шляхів, які віддає UI) DOWNLOAD_DIR/STATE_DIR/TEMP_DIRрозведені по реальних дисках, якщо том один — усі три лишити дефолтними- Якщо позаду nginx —
proxy_set_header Upgrade/Connection "upgrade"прописані, інакше черга не оновлюється CORS_ALLOWED_ORIGINS— конкретні origin-и, не*, якщо потрібні креди (розширення/букмарклети зазвичай кредів не шлють, тож*їм і так підходить)ALLOW_PRIVATE_ADDRESSESлишаєтьсяfalse, якщо немає контрольованого проксі між контейнером і мережею- Публічний no-auth — усвідомлене рішення, не дефолт за забудькуватістю
Найчесніший індикатор у будь-якому self-hosted завантажувачі — не статус "активно", а таймер, якого немає. Кукі показують зелену галочку рівно доти, доки хтось не спробує ними скористатись через три години — і тоді з'ясовується, що галочка означала «була жива на момент завантаження», а не «жива зараз». POT-провайдер усередині контейнера про це навіть не знає: він просто працює, поки хтось намагається компенсувати відсутню проблему кукі, яких давно не існувало.