Самостоятельный видеохостинг на Flask: загрузка видео, автоматическое транскодирование в несколько разрешений с GPU-ускорением (NVIDIA NVENC/CUDA), потоковая раздача с поддержкой Range-запросов и простая авторизация пользователей.
- Регистрация и авторизация пользователей (Flask-Login, пароли хешируются через Werkzeug)
- Загрузка видео с обложкой через веб-форму
- Автоматическое транскодирование загруженного видео в набор разрешений (2160p–360p, без апскейла выше исходного качества) с помощью ffmpeg на GPU (
-hwaccel cuda, кодеки*_nvenc) - Определение ориентации видео (горизонтальное/вертикальное/квадратное) и подбор разрешения под него
- Автогенерация миниатюры из кадра видео через ffprobe/ffmpeg, если обложка не загружена
- Потоковая отдача видео с поддержкой
HTTP Range(перемотка без полной загрузки файла) - Переключение качества прямо во время просмотра, без потери позиции воспроизведения
- Кэширование статики (favicon, миниатюры) через
ETag
- Backend: Python, Flask, Flask-Login, Werkzeug, SQLite (хранение пользователей)
- Frontend: Jinja2-шаблоны, Tailwind CSS (через CDN), Font Awesome
- Видео: ffmpeg / ffprobe (с поддержкой NVIDIA NVENC/CUDA)
- Python 3.10+
- ffmpeg и ffprobe, установленные в систему (для проверки:
ffmpeg -version) - Видеокарта NVIDIA с поддержкой NVENC/CUVID и собранный с этой поддержкой ffmpeg (драйверы NVIDIA должны быть установлены отдельно)
git clone https://github.com/GameFriendsTeam/UltraStream.git
cd UltraStream
python3 -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install -r requirements.txtУбедитесь, что ffmpeg доступен из консоли:
ffmpeg -version
ffprobe -versionПеред запуском в создайте файл .env и заполните его:
SECRET_KEY='CHANGE-ME'python srv.pyДоступные параметры командной строки:
| Флаг | Сокращение | По умолчанию | Описание |
|---|---|---|---|
--host |
-H |
0.0.0.0 |
IP-адрес для прослушивания |
--port |
-p |
5000 |
Порт |
--debug |
-d |
False |
Режим отладки Flask |
--video_dir |
-v |
videos |
Папка с видео |
--thumbnail_dir |
-t |
thumbnail |
Папка с миниатюрами |
Пример:
python srv.py --host 127.0.0.1 --port 8000 --video_dir /data/videosПосле запуска сайт доступен по адресу http://<host>:<port>/.
Видео можно загрузить и обработать без веб-интерфейса, напрямую через loader.py:
python loader.py --upload \
--target-dir videos/my-video-id \
--video-file /path/to/video.mp4 \
--title "Название видео" \
--description "Описание видео" \
--thumbnail /path/to/cover.jpgUltraStream/
├── srv.py # Flask-приложение: маршруты, авторизация, стриминг
├── loader.py # Транскодирование и обработка видео (ffmpeg/ffprobe)
├── thumbnail.py # Генерация и хранение миниатюр
├── sql.py # Вспомогательная обёртка над SQLite (универсальный CRUD)
├── templates/
│ ├── index.html # Главная страница со списком видео
│ ├── watch.html # Страница просмотра видео
│ ├── upload.html # Форма загрузки видео
│ ├── login.html # Вход
│ └── register.html # Регистрация
├── users.db # SQLite база пользователей (создаётся автоматически)
└── videos/ # Папка с загруженными и транскодированными видео
Каждое видео хранится в собственной подпапке videos/<video_id>/ с файлами <качество>.mp4 и метаданными в data.json (название, описание, год, миниатюра, ориентация, доступные качества).
- Файл
loader.pyрассчитан на NVIDIA GPU (NVENC/CUDA); на системах без поддержки CUDA транскодирование не запустится без правки команд ffmpeg на другие кодеки (например:libx264/libx265) - Проект не предназначен для продакшен-нагрузки «из коробки» — рекомендуется ставить за reverse proxy (nginx) и использовать WSGI-сервер (gunicorn/uwsgi) вместо встроенного
app.run()