Задача простая: взять RTSP-поток с IP-камеры и круглосуточно отдавать его в YouTube Live, не держа ffmpeg руками в screen на сервере. Для этого я собрал Docker-образ alekseykrivoshein/rtsptoyoutube: он запускается на VPS, забирает поток с камеры и отправляет его в YouTube по RTMP.
Что внутри образа
Образ собран на базе jrottenberg/ffmpeg, сверху добавлен короткий скрипт entrypoint.sh. Он принимает два аргумента: адрес камеры и ключ трансляции YouTube. Дальше скрипт запускает ffmpeg примерно с такими настройками:
- поток с камеры забирается по RTSP через TCP, так меньше рассыпается картинка на плохом канале;
- видео не перекодируется (
-c:v copy), поэтому процессор VPS почти не нагружается, но камера должна отдавать H.264; - звук перекодируется в AAC;
- поток уходит на
rtmp://a.rtmp.youtube.com/live2/КЛЮЧ; - один запуск ffmpeg длится до 12 часов, потом процесс завершается, и Docker поднимает контейнер заново.
Что понадобится
- VPS или любой сервер с Docker, у которого есть доступ к камере: белый IP у камеры, проброс порта или VPN до домашней сети;
- камера с RTSP и видео в H.264, логин и пароль указываются прямо в адресе потока;
- канал YouTube с включёнными прямыми трансляциями и ключ трансляции из YouTube Studio.
Запуск
Адрес камеры и ключ передаются после имени образа обычными аргументами, без переменных окружения:
docker run -d --name stream-upload --restart=always \ -v /etc/localtime:/etc/localtime:ro \ alekseykrivoshein/rtsptoyoutube \ -- 'rtsp://user:pass@192.168.1.50:554/stream1' xxxx-xxxx-xxxx-xxxx-xxxx
Двойной дефис перед адресом камеры не опечатка. ENTRYPOINT в образе запускает скрипт через sh -c, и первый аргумент после имени образа туда не попадает. Без -- скрипт увидит только ключ и завершится с подсказкой «Arguments: IP_CAMERA_ADDRESS LIVE_ID».
Флаг --restart=always здесь обязателен: он перезапускает контейнер и после 12-часового цикла ffmpeg, и после обрыва связи с камерой, и после перезагрузки сервера. Посмотреть, что происходит, можно командой docker logs -f stream-upload: скрипт в начале печатает адрес камеры и ключ, поэтому эти логи никому не показывайте. Ключ трансляции тоже не кладите в git и публичные заметки.
Пример в работе
Этот образ крутил трансляцию на bolotnaya.online: камеры на Болотную площадь и улицу Серафимовича. Сейчас они выключены: со 2 июня 2026 года фасад закрыли строительные леса, и обзора нет.
Где запустить
Я гонял образ на Docker у Beget. Сейчас у Beget в облаке есть готовый VPS с Docker из маркетплейса: создаёте сервер, и Docker на нём уже стоит. Подойдёт и любой другой VPS, логика та же: Docker, доступ к RTSP камеры и открытый исходящий трафик до серверов YouTube (RTMP идёт на порт 1935).
Если трансляция не идёт
- Проверьте, что камера отвечает с того же сервера:
ffprobe 'rtsp://user:pass@IP:554/stream1'. - Уточните путь потока: у камер обычно есть основной и дополнительный поток (main и sub), с неправильным путём будет чёрный экран или обрыв.
- Если камера отдаёт H.265, копирование видео не сработает: YouTube по RTMP ждёт H.264. Переключите кодек в настройках камеры.
- В YouTube Studio трансляция должна быть активна, а ключ не сброшен. Рекомендуемые битрейты и разрешения есть в справке YouTube по настройкам кодировщика.
- Файрвол и NAT не должны резать исходящий RTMP.
В итоге вся трансляция сводится к одной команде docker run с двумя аргументами: адресом камеры и ключом YouTube. Видео идёт без перекодирования, поэтому хватает самого слабого VPS, а перезапуски берёт на себя Docker.