Введение
Этот проект — веб-приложение для загрузки видео с YouTube и других поддерживаемых сайтов с помощью утилиты yt-dlp. На клиенте — удобная веб-панель, на сервере — FastAPI-приложение, которое запускает yt-dlp, передаёт логи и прогресс в реальном времени, управляет загрузками и отдаёт готовые файлы.
1. Клиентская часть: index.html
1.1 Структура
- Основной контейнер
#main-container: тёмная панель с границей, отступами и тенями, ограничена по ширине 640px, центрирована с отступом сверху. - Заголовок —
<h2>с названием приложения. - Форма
#downloadFormс элементами: textareaдля вставки ссылки видео.- - Интерактивная зона Drag & Drop (
#dropZone) — блок для загрузки файлаcookies.txtперетаскиванием мыши или кликом, с отображением имени выбранного файла и кнопкой быстрой очистки. input[type="text"]для ввода опций yt-dlp.- Подсказки с примерами опций (показывает популярные параметры yt-dlp).
- Группа кнопок
- Начать загрузку
- Отмена
- Загрузить на ПК (появляется после завершения загрузки)
- Показать форматы
- Прогресс-бар с визуальным отображением прогресса загрузки и текстовым процентом. - Вывод форматов (текстовое поле) при запросе доступных форматов для URL.
- Терминал — окно с лентой логов, куда выводятся стримы с сервера.
-
История — список ранее скачанных файлов с копированием ссылок и очисткой.
-
Навигация с полезными ссылками — для перехода к ресурсам yt-dlp, FFmpeg и другое.
- Кнопка выхода — кнопка завершения сессии в правом верхнем углу интерфейса.
- Кнопка обновления окружения — административная кнопка для запуска обновления зависимостей и утилиты прямо из панели.
1.2 Стили
- Реализован Dark Mode с контрастными цветами: тёмный фон, светлый текст.
- Унифицированные отступы, скругления, тени.
- Адаптивность: список ссылок меняет направление на мобильных.
- Кнопки с ховерами и стилями_disabled.
- Прогресс-бар с переходами и легкой анимацией.
- Бегущая строка (
marquee): автоматическая плавная прокрутка слишком длинных названий роликов в карточках истории с паузой при наведении курсора.
1.3 Скрипты
- Управление историей:
- Хранит историю в localStorage до 50 записей.
- Позволяет копировать ссылки кнопками.
- Очистка удаляет и файлы на сервере.
Обработка прогресса:
- построчно разбирает вывод yt-dlp, заменяет строки с возвратом каретки
\rи обновляет процент в прогресс-баре. - Показ доступных форматов: отправляет POST-запрос на
/formatsс передачей формы (URL и файла cookies) и выводит полученный список.
Асинхронная загрузка с отменой:
- Запускает POST запрос на
/download_streamс FormData. - Обрабатывает stream тела ответа, динамически обновляя интерфейс.
-
Возможность отмены загрузки HTTP AbortController.
-
Копирование ссылок и взаимодействие с буфером обмена.
2. Серверная часть: main.py
2.1 Архитектура проекта и директории
- templates/ — HTML-шаблоны (
index.htmlдля основной панели иlogin.htmlдля формы входа). - downloads/ — папка для временного хранения скачанных файлов.
- static/ — не используется: стили и скрипты встроены напрямую в шаблоны.
- .env — конфигурационный файл с учётными данными администратора и секретным ключом
SECRET_KEY. - Роуты реализованы на FastAPI с подключением сессионного middleware.
- Совместимость с Python 3.13: класс
MyJinja2Templatesпереопределяет метод рендеринга шаблонов, очищая системный ключattributesиз контекста.
2.2 Основные константы и пути
YT_DLP_PATH— путь к бинарнику yt-dlp.OUTPUT_TEMPLATE— формат имени для выходных файлов (использует title и расширение).- Директории получаются относительно текущего файла.
2.3 Утилиты
sanitize_filename(name)— избавляется от подозрительных символов в имени файла, заменяя на_.filter_user_options(options)— вырезает параметры вывода (-o,--output) и блокирует опасные флаги из набораDANGEROUS_OPTS(--exec,--config-locations,--print-to-fileи др.), разрешая из внешних загрузчиков толькоaria2c,ffmpegиcurl.is_extract_audio(options)— проверяет, запрашивал ли пользователь просто аудио (флаги-x,--extract-audio).- Очистка ссылок VK: функция
clean_vk_urlочищает ссылки на VK и VK Видео от лишних GET-параметров, сохраняя домен и чистый ID ролика.
2.4 Формирование команды yt-dlp: build_cmd
- Формирует список параметров для запуска команды
yt-dlp. - Добавляет параметры по умолчанию для стабильности (например,
--retries,--sleep-interval). - Умная обработка аудио: если запрошено извлечение звука (
-xили--extract-audio), дефолтные параметры (--audio-format m4a, битрейт320) подставляются только при отсутствии пользовательских. Это предотвращает дублирование флагов и сбои синтаксиса. - Добавляет флаг
--newlineдля корректного потокового вывода прогресса. - Ограничение контента: в команду принудительно добавляется флаг
--no-playlist, гарантирующий загрузку только одного ролика, а не всего плейлиста целиком.
2.5 Асинхронное управление yt-dlp: stream_yt_dlp
- Запускает yt-dlp как асинхронный сабпроцесс.
- Внедрена фильтрация вывода: из логов исключаются технические строки FFmpeg (hls, dash, segment), благодаря чему в терминале пользователя отображается только чистая информация о процессе.
- Стабилизация прогресс-бара: Реализована логика, которая игнорирует случайные скачки процентов назад, обеспечивая корректное отображение процесса загрузки в интерфейсе.
- После завершения проверяет наличие файла, обрабатывает временные файлы.
- Возвращает ссылку на скачивание в JSON.
- Отлавливает исключения и убивает процесс в случае таймаута или ошибки.
- Нечёткий поиск готового файла: сопоставление через
difflib.SequenceMatcherнаходит скачанный ролик на диске, даже еслиyt-dlpскорректировал спецсимволы в названии при сохранении.
2.6 Эндпоинты
GET /login— отображает страницу авторизации (login.html).POST /login— проверяет введённые учётные данные и создаёт сессию.GET /logout— завершает сессию пользователя и перенаправляет на страницу входа.GET /— отдаёт главную рабочую страницуindex.html(требует авторизации).POST /download_stream— принимает URL, опции и файл cookies, запускает процесс загрузки со стримингом логов в реальном времени (требует авторизации).POST /formats— возвращает список доступных форматов медиа черезyt-dlp -F(требует авторизации).POST /clear_history_files— удаляет все скачанные файлы из папкиdownloads/на сервере (требует авторизации).GET /download_file— отдаёт готовый файл с проверкой безопасности пути и заголовками для скачивания (требует авторизации).
2.7 Безопасность
- Ограничение размера истории в интерфейсе.
- Обработка ошибок с понятными сообщениями без утечки внутренних путей.
- Защита от инъекций и выполнения стороннего кода через фильтрацию опасных CLI-параметров утилиты
yt-dlp. - Безопасная отдача файлов: проверка пути через
safe_path.startswith(os.path.abspath(DOWNLOADS_DIR))предотвращает уязвимость Path Traversal. - Встроенная аутентификация: доступ защищён сессионной авторизацией (
SessionMiddleware, cookie на 1 год). Учётные данные администратора и секретный ключ безопасно вынесены в конфигурационный файл окружения.env. - Поддержка обратного проксирования: сервис полностью готов к работе за Nginx, корректно формирует относительные пути к файлам и поддерживает заголовок
X-Forwarded-Prefixпри размещении в подпапке.
3. Взаимодействие клиента и сервера
- Клиент отправляет форму со ссылкой и опциями, сервер запускает
yt-dlpв фоне. - Прогресс и логи приходят на клиент в режиме реального времени через потоковый ответ.
- Клиент отображает прогресс, выводит логи, обрабатывает ошибки.
- По завершении появляется кнопка для скачивания.
- История сохраняется локально, синхронизируется с очисткой на сервере.
4. Пример использования
- Вставьте ссылку YouTube (например, https://www.youtube.com/watch?v=...).
- По желанию добавьте cookies для приватного доступа.
- Введите опции yt-dlp (качество, преобразование аудио и т. д.).
- Нажмите «Начать загрузку».
- Следите за прогрессом и логами.
- После завершения скачайте файл.
- Просматривайте историю, копируйте ссылки, очищайте её по нужде.
5.Обоснование архитектурных решений
- FastAPI и асинхронность — позволяет обрабатывать потоковые ответы эффективно, не блокируя сервер.
- yt-dlp через оболочку — использует мощный инструмент без переписывания логики загрузки.
- Стриминг логов — даёт лучший UX с обратной связью.
- LocalStorage для истории — простое решение без необходимости бэкенд базы.
- Стандартизированные пути и фильтры — минимизируют риски взлома и конфликтов.
- ARIA и доступность — поддержка пользователей с особыми потребностями.
6. Возможные расширения
- Поддержка многопользовательского режима с разделением прав доступа.
- Расширенное управление файлами (выборочное удаление, повторная загрузка из истории).
- Кэширование и очереди параллельных загрузок.
- UI на современном фреймворке (React / Vue) для более динамичного интерфейса.
7. Как пользоваться окном «Показать форматы» и формировать команду загрузки
7.1 Зачем нужна функция «Показать форматы»
Видео, размещённые на YouTube и других платформах, обычно доступны в разных качествах и форматах: например, 1080p mp4, 720p webm, аудио отдельно и т.д. yt-dlp позволяет выбрать конкретный формат для загрузки.
В интерфейсе кнопка «Показать форматы» запрашивает у yt-dlp список доступных форматов для указанного видео и отображает его во втором текстовом окне. Это помогает понять, какие варианты есть, и подобрать нужные опции.
7.2 Как использовать окно «Показать форматы»
- Вставьте ссылку на видео в поле «Вставьте ссылку сюда».
- Нажмите кнопку «Показать форматы».
- В появившемся блоке снизу вы увидите примерно такой список (пример):
format code extension resolution note
249 webm audio only tiny 53k , opus @ 50k, 1.45MiB
250 webm audio only tiny 68k , opus @ 70k, 1.81MiB
140 m4a audio only tiny 129k , m4a_dash container, mp4a.40.2@128k, 3.54MiB
137 mp4 1080p 4479k , avc1.640028, 30fps, video only, 114.64MiB
136 mp4 720p 1856k , avc1.4d401f, 30fps, video only, 45.84MiB
135 mp4 480p 966k , avc1.4d401e, 30fps, video only, 24.75MiB
...
format code- уникальный идентификатор формата, который нужно указать для загрузки.extension- расширение файла.resolutionиnote- описание качества и особенности.
7.3 Пример формирования команды для загрузки
По умолчанию в проекте используется такая команда для выбора форматов:
-S res:1080,vcodec:av1,vcodec:vp9 -f "bv*[height<=1080]+ba/best[height<=1080]/b" --merge-output-format mp4
Эта сложная строка с -S (сортировкой форматов) пытается выбрать лучшее качество до 1080p, предпочтительно с кодеком av1 или vp9, с объединением аудио+видео в MP4.
7.4 Как подставить конкретные форматы из списка
Если вы получили список форматов и хотите загрузить, например, видео 1080p и аудио 128k, то можно указать:
-f 137+140
где
137- видео в формате mp4 1080p,140- аудио в формате m4a 128k.
В поле «Дополнительные опции yt-dlp» напишите:
-f 137+140 --merge-output-format mp4
Это загрузит указанное видео и аудио и объединит их в MP4.
7.5 Пример полного сценария
- Вставьте ссылку.
- Нажмите «Показать форматы» и выберите нужные коды.
- В «Дополнительные опции» введите строку с
-fили любыми другими параметрами. - Нажмите «Начать загрузку».
7.6 Полезные параметры
--no-playlist: скачивает только видео, а не весь плейлист.--extract-audio: извлекает аудио.--audio-format mp3: конвертирует аудио в mp3.--format best: выбирает лучшее качество автоматически.
Этот механизм позволяет гибко управлять загрузками, используя мощь yt-dlp через простой веб-интерфейс.
7.7 Шаблоны команд yt-dlp для поля «Дополнительные опции»
1. Скачать лучшее видео с объединением аудио (до 1080p, MP4)
-f 137+140 --merge-output-format mp4 --no-playlist
-f 137+140— видео 1080p (код 137) + аудио 128k (код 140)--merge-output-format mp4— объединить аудио и видео в MP4--no-playlist— скачать только одно видео из плейлиста
2. Скачать видео в наилучшем качестве с объединением в MKV
-f bestvideo+bestaudio --merge-output-format mkv --no-playlist
-f bestvideo+bestaudio— взять лучшие видео и аудиодорожки--merge-output-format mkv— объединить в контейнер MKV--no-playlist— без плейлистов
3. Скачать только аудио с конвертацией в MP3 с качеством 320 kbps
--extract-audio --audio-format mp3 --audio-quality 320 --no-playlist
--extract-audio– извлечь аудио из видео--audio-format mp3– конвертировать аудио в MP3--audio-quality 320– установить битрейт 320 кбит/с--no-playlist– скачать только одно видео
4. Скачать аудио с максимальным качеством (без конкретного битрейта)
--extract-audio --audio-format mp3 --audio-quality 0 --no-playlist
--audio-quality 0— максимально возможное качество (оптимальное значение для MP3)
5. Скачать аудио без конвертации, в исходном формате
-f bestaudio --no-playlist --extract-audio
-f bestaudio— выбрать лучшую аудиодорожку--extract-audio— извлечь аудио--no-playlist— без плейлистов
6. Скачать субтитры на русском и английском языках
--write-sub --sub-lang ru,en --skip-download
--write-sub— скачать субтитры--sub-lang ru,en— языки субтитров--skip-download— не скачивать само видео
Как скачать определённый участок видео с точной обрезкой
Для загрузки только части видео (например, с 1-й по 2-ю минуту), при этом сохраняя обрезку максимально точно по ключевым кадрам, используйте опции:
--force-keyframes-at-cuts --download-sections "*00:01:00-00:02:00"
Эта команда скачает указанный промежуток без артефактов, делая резы именно там, где расположены ключевые кадры.
Пример полной команды:
yt-dlp --force-keyframes-at-cuts --download-sections "*00:01:00-00:02:00" <URL>
Если нужно скачать несколько секций подряд – указывай их через запятую:
--force-keyframes-at-cuts --download-sections "*00:01:00-00:02:00,*00:03:30-00:04:00"
Как пользоваться шаблонами
- Вставьте ссылку на видео.
- Нажмите «Показать форматы» и выберите нужные коды форматов.
- Вставьте выбранный шаблон в поле «Дополнительные опции yt-dlp». При необходимости замените коды форматов из шага 2.
- Нажмите «Начать загрузку».
Заключение
Этот проект — отличный пример современного веб-сервиса с обращением к CLI-инструментам, потоковой обработкой и удобным интерфейсом. Он собирает надёжные компоненты, делая сложную задачу загрузки видео доступной для обычных пользователей.