Thank you for reading this post, don't forget to subscribe!
Вещание видео будет осуществляться с помощью модуля для nginx — nginx-rtmp-module.
Для этого необходимо собрать веб-сервер nginx из исходников, включив вышеназванный модуль.
RTMP - протокол передачи потокового видео, например с видеорегистратора или напрямую с камеры. Расшифровывается как Real Time Messaging Protocol. Разработан компанией Adobe.
RTMP активно используется для трансляции видео в качестве веб-контента (на сайте). Это возможно благодаря, например, веб-серверу NGINX в связке с модулем nginx-rtmp-module — захватываем медиаконтент по RTSP с использованием кодека ffmpeg и конвертируем его в потоковое видео.
В качестве клиентов (плееров), принимающих поток, можно использовать:
- Adobe Flash Player.
- JW Player.
- Uppod.
Иногда, ошибочно полагают, что поток можно принимать с помощью известной программы VLC. На самом деле, это не так — данный плеер не умеет работать с RTMP напрямую. Однако, можно захватывать видео при помощи утилиты rtmpdump и передавать его на VLC.
По умолчанию, протокол работает на порту 1935, транспорт осуществляется с использованием TCP.
Еще немного об RTMP на Википедии
Сборка NGINX + nginx-rtmp-module
Для удобства работы с nginx, сначала мы установим его из пакетов, хотя бы, чтобы создались скрипты автозапуска.
Установка nginx и пакетов для сборки
Настраиваем репозиторий:
vi /etc/yum.repos.d/nginx.repo
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=0
enabled=1
yum install nginx pcre-devel openssl-devel
Сборка из исходников
Смотрим версию установленного пакета:
nginx -v
Теперь переходим по ссылке https://nginx.org/download и копируем ссылку на установленную версию nginx (архив tar.gz). В моем случае, это была версия 1.10.0.
* обратите внимание, что в данном списке версии идут не по порядку — ориентируйтесь по дате (средняя колонка).
Скачиваем исходник:
wget http://nginx.org/download/nginx-1.10.0.tar.gz
Скачиваем модуль:
wget https://github.com/arut/nginx-rtmp-module/archive/master.tar.gz
Распаковываем исходник nginx и модуль:
tar xzf nginx-1.10.0.tar.gz
tar xzf master.tar.gz
И переходим в распакованный каталог nginx:
cd nginx-1.10.0
Смотрим, с какими опциями собран уже установленный nginx:
nginx -V
Копируем текст, который идет после configure arguments:
Теперь конфигурируем nginx со скопированными опциями + --add-module=../nginx-rtmp-module-master. Получиться что-то на вроде:
./configure --with-cc-opt='-g -O2 -fPIE -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -fPIE -pie -Wl,-z,relro -Wl,-z,now' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-pcre-jit --with-ipv6 --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_addition_module --with-http_dav_module --with-http_geoip_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module --with-http_v2_module --with-http_sub_module --with-http_xslt_module --with-stream --with-stream_ssl_module --with-mail --with-mail_ssl_module --with-threads --add-module=../nginx-rtmp-module-master
Собираем исходник:
make
И выполняем установку:
make install
Запускаем веб-сервер:
systemctl start nginx
Настройка захвата видео
Если используется брандмауэр, не забываем добавить в разрешения tcp порт 1935.
Установка утилит
Ubuntu:
apt-get install ffmpeg rtmpdump
CentOS:
Устанавливаем расширенный репозиторий пакетов EPEL:
yum install epel-release
Тянем дополнительный репозиторий:
rpm -Uvh http://li.nux.ro/download/nux/dextop/el7/x86_64/nux-dextop-release-0-5.el7.nux.noarch.rpm
Теперь можно устанавливать пакеты:
yum install ffmpeg rtmpdump
Настройка NGINX
Открываем на редактирование следующий файл:
vi /etc/nginx/nginx.conf
И дописываем следующее:
[codesyntax lang="php" blockstate="collapsed"]
1 2 3 4 5 6 7 8 |
rtmp { server { listen 1935; application cam1 { live on; } } } |
[/codesyntax]
* важно, чтобы данный блок шел не внутри, а отдельно от основного http.
Перезагружаем сервис:
systemcl restart nginx
На данном этапе мы настроили простейший rtmp-сервер, который сможет принимать запросы на передачу видео.
Чтобы проверить его работу, воспользуемся ранее установленной утилитой ffmpeg:
ffmpeg -i rtsp://admin:admin@192.168.0.12:554/Streaming/Channels/1/ -c copy -f flv rtmp://127.0.0.1/cam1/stream
* где admin:admin — логин и пароль на подключение к веб-камере; 192.168.0.12 — IP-адрес камеры; cam1 — имя application, которое мы задали в конфигурационном файле nginx; stream — произвольное название для потока.
В подтверждение правильного выполнения команды, мы увидим что-то наподобие:
frame= 1381 fps= 26 q=-1.0 size= 27586kB time=00:00:55.27 bitrate=4088.6kbits/
frame= 1394 fps= 26 q=-1.0 size= 27822kB time=00:00:55.79 bitrate=4085.1kbits/
frame= 1407 fps= 26 q=-1.0 size= 28131kB time=00:00:56.31 bitrate=4092.5kbits/
frame= 1420 fps= 26 q=-1.0 size= 28371kB time=00:00:56.83 bitrate=4089.6kbits/
frame= 1433 fps= 26 q=-1.0 size= 28609kB time=00:00:57.35 bitrate=4086.5kbits/
frame= 1446 fps= 26 q=-1.0 size= 28852kB time=00:00:57.87 bitrate=4084.1kbits/
Теперь можно запустить приложение воспроизведения видео, например, VLC плеер и подключиться к веб-серверу (Медиа - Открыть URL):
Вводим URL: rtmp://192.168.0.100/cam1/stream
* где 192.168.0.100 — IP-адрес сервера nginx; cam1 — наш application; stream — наше произвольное название для потока.
Если мы увидим видео с камеры, значит все настроено верно.
Теперь прерываем работу ffmpeg и открываем конфиг nginx:
vi /etc/nginx/nginx.conf
И добавляем следующее:
[codesyntax lang="php" blockstate="collapsed"]
1 2 3 4 5 6 7 8 9 |
rtmp { server { listen 1935; application cam1 { live on; exec_static ffmpeg -i rtsp://admin:admin@192.168.0.12:554/Streaming/Channels/1/ -c copy -f flv rtmp://127.0.0.1/cam1/stream; } } } |
[/codesyntax]
Перезапускаем nginx:
systemctl restart nginx
И снова, но уже не запуская вручную ffmpeg, проверяем наличие видеопотока при помощи VLC.
Несколько камер
Открываем nginx.conf:
vi /etc/nginx/nginx.conf
Настраиваем автоматическое определение воркеров:
worker_processes auto;
* оптимальное число одновременных потоков, позволит nginx работать быстрее.
В корень конфига добавляем:
rtmp_auto_push on;
* включает локальные ретрансляции для использования нескольких воркеров.
Теперь переходим к настройкам rtmp и приводим наш конфиг к следующему виду:
[codesyntax lang="php" blockstate="collapsed"]
1 2 3 4 5 6 7 8 9 10 11 12 13 |
rtmp { server { listen 1935; application cam1 { live on; exec_static ffmpeg -i rtsp://admin:admin@192.168.0.12:554/Streaming/Channels/1/ -c copy -f flv rtmp://127.0.0.1/cam1/stream; } application cam2 { live on; exec_static ffmpeg -i rtsp://admin:admin@192.168.0.13:554/Streaming/Channels/1/ -c copy -f flv rtmp://127.0.0.1/cam2/stream; } } } |
[/codesyntax]
его можно также настроить так:
[codesyntax lang="php" blockstate="collapsed"]
1 2 3 4 5 6 7 8 9 10 11 12 13 |
rtmp { server { listen 1935; application cam1 { live on; } application cam2 { live on; } exec_static ffmpeg -i rtsp://admin:admin@192.168.0.12:554/Streaming/Channels/1/ -c copy -f flv rtmp://127.0.0.1/cam1/stream; exec_static ffmpeg -i rtsp://admin:admin@192.168.0.13:554/Streaming/Channels/1/ -c copy -f flv rtmp://127.0.0.1/cam2/stream; } } |
[/codesyntax]
Или так:
[codesyntax lang="php" blockstate="collapsed"]
1 2 3 4 5 6 7 8 9 10 |
rtmp { server { listen 1935; application cams { live on; } exec_static ffmpeg -i rtsp://admin:admin@192.168.0.12:554/Streaming/Channels/1/ -c copy -f flv rtmp://127.0.0.1/cams/stream1; exec_static ffmpeg -i rtsp://admin:admin@192.168.0.13:554/Streaming/Channels/1/ -c copy -f flv rtmp://127.0.0.1/cams/stream2; } } |
[/codesyntax]
И перезапускаем nginx:
systemctl restart nginx
Запись
Для хранения видео на сервер, есть также несколько варинатов настройки.
1-й вариант: использование нескольких application. В каждом из них своя папка для хранения видео:
[codesyntax lang="php" blockstate="collapsed"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
rtmp { record all; live on; server { listen 1935; application cam1 { record_path /tmp/record1; exec_static ffmpeg -i rtsp://admin:admin@192.168.0.12:554/Streaming/Channels/1/ -c copy -f flv rtmp://127.0.0.1/cam1/stream; } application cam2 { record_path /tmp/record2; exec_static ffmpeg -i rtsp://admin:admin@192.168.0.13:554/Streaming/Channels/1/ -c copy -f flv rtmp://127.0.0.1/cam2/stream; } } } |
[/codesyntax]
Создаем папки:
mkdir /tmp/record1 /tmp/record2
Задаем права (владельца):
chown nginx:nginx /tmp/record*
2-й вариант: один application с разными именами для потоков:
[codesyntax lang="php" blockstate="collapsed"]
1 2 3 4 5 6 7 8 9 10 11 12 |
rtmp { server { listen 1935; application cams { live on; record all; record_path /tmp/record; } exec_static ffmpeg -i rtsp://admin:admin@192.168.0.12:554/Streaming/Channels/1/ -c copy -f flv rtmp://127.0.0.1/cams/stream1; exec_static ffmpeg -i rtsp://admin:admin@192.168.0.13:554/Streaming/Channels/1/ -c copy -f flv rtmp://127.0.0.1/cams/stream2; } } |
[/codesyntax]
Необходимо также создать папку и задать владельца:
mkdir /tmp/record
chown nginx:nginx /tmp/record
и не забываем перезагрузить nginx:
systemctl restart nginx
Полезные опции для записи
record_suffix -%Y-%m-%d-%H-%M-%S.flv;
record_max_size 5120K;
record_interval 3m;
record_suffix — добавляет окончание к каждому созданному файлу.
record_max_size — ограничивает размер каждого файла определенным объемом (в данном примере, 5 Мб). При лимите, будет создан новый файл.
record_interval — ограничивает файл видеофрагментом в несколько минут (в нашем примере, 3).
HLS
Прежде, чем начать, убедитесь, что брандмауэр отключен или пропускает http-запросы. Selinux на момент проведения тестов, лучше отключить.
Протокол HLS позволяем транслировать потоковое видео поверх HTTP. Это позволит сэкономить ресурсы сервера при множественном обращении и создать более кроссплатформенную инфраструктуру.
Для его включения, приводим наш nginx.conf к следующему виду:
[codesyntax lang="php" blockstate="collapsed"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
rtmp { live on; hls on; hls_fragment 5s; server { listen 1935; application cam1 { hls_path /tmp/cam1; } application cam2 { hls_path /tmp/cam2; } exec_static ffmpeg -i rtsp://admin:admin@192.168.0.12:554/Streaming/Channels/1/ -c copy -f flv rtmp://127.0.0.1/cam1/stream; exec_static ffmpeg -i rtsp://admin:admin@192.168.0.13:554/Streaming/Channels/1/ -c copy -f flv rtmp://127.0.0.1/cam2/stream; } } |
[/codesyntax]
Перезапуск:
systemctl restart nginx
Ждем 4-5 секунд и смотрим содержимое папок в /tmp:
ls /tmp/cam1
ls /tmp/cam2
Внутри каждой из них мы должны увидеть файл с расширением m3u8 — это плейлист с видеонарезками. Если файлы есть, значит HLS заработал.
Осталось научить наш NGINX отдавать данные файлы. Для этого в секции http добавим:
[codesyntax lang="php" blockstate="collapsed"]
1 2 3 |
location / { root /tmp; } |
[/codesyntax]
И снова:
systemctl restart nginx
В том же VLC для проверки вводим следующий URL:
http://192.168.0.100/cam1/stream.m3u8
MPEG-DASH
Как альтернатива HLS, используется для видеотрансляции поверх HTTP. Его основные преимущества — поддержка со стороны большого количества браузеров и работа на javascript-плеере.
И так, его настройка сильно напоминает настройку HLS. В конфиге NGINX:
[codesyntax lang="php" blockstate="collapsed"]
1 2 3 4 5 6 7 8 9 10 11 12 |
rtmp { live on; dash on; server { listen 1935; application cams { dash_path /tmp/cams; } exec_static ffmpeg -i rtsp://admin:admin@192.168.0.12:554/Streaming/Channels/1/ -c:v libx264 -profile:v baseline -c:a libfaac -ar 44100 -f flv rtmp://127.0.0.1/cams/stream1; exec_static ffmpeg -i rtsp://admin:admin@192.168.0.13:554/Streaming/Channels/1/ -c:v libx264 -profile:v baseline -c:a libfaac -ar 44100 -f flv rtmp://127.0.0.1/cams/stream2; } } |
[/codesyntax]
* обратите внимание, здесь мы решили настроить все в одном application с разными потоками для каждой камеры. И не потому, что так нужно для MPEG-DASH — скорее для демонстрации возможности различных способов конфигурации.
** также можно заменить, что мы добавили опции конвертации потока при переводе его в RTMP — это важно для MPEG-DASH.
Перезапускаем nginx:
systemctl restart nginx
Проверяем появление файлов с расширением .mpd.
ls /tmp/cams
Если они есть, переходим в /tmp
cd /tmp
И выполняем следующую команду:
git clone https://github.com/arut/dash.js.git
* мы скачали js-плеер для просмотра dash-видео.
** по хорошему, в продуктивной среде следует создать отдельный виртуальный домен и хранить все файлы в специальной выделенной директории, а не в каталоге /tmp. Для теста это не принципиально.
И создаем новую ветку live:
cd dash.js
git checkout live
Проверим работу плеера. Открываем браузер и вводим следующий URL:
http://192.168.0.100/dash.js/baseline.html
* где 192.168.0.100 — IP-адрес нашего видео-сервера.
И нажимаем play — начнется показ демонстративного видео.
Теперь откроем файл baseline.html внутри папки dash.js:
vi /tmp/dash.js/baseline.html
Найдем строчку:
url = "http://dash.edgesuite.net/envivio/dashpr/clear/Manifest.mpd",
И заменим ее на:
url = "http://192.168.0.100/cams/stream1.mpd",
* где cams — наш application; stream1 — имя потока с первой камеры.
И снова открываем браузер и вводим:
http://192.168.0.100/dash.js/baseline.html
Полезные директивы
respawn_timeout 15s;
chunk_size 8192;
respawn_timeout — время ожидания перед повторным запуском дочернего процесса. По умолчанию, 5 секунд.
chunk_size — максимальный размер порции для мультиплексирования потока. По умолчанию, 4096.
Полный перечень директив опубликован по ссылке: