IP-камера в YouTube Live с VPS: Docker-образ rtsptoyoutube

Задача простая: взять 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.

Источники и ссылки


Комментарии загружаются…