NGINX + nginx-rtmp-module — трансляция видео с веб-сервера

Вещание видео будет осуществляться с помощью модуля для nginx — nginx-rtmp-module.

Для этого необходимо собрать веб-сервер nginx из исходников, включив вышеназванный модуль.

Содержание:

Сборка программного обеспечения
Захват видео с камер
Несколько камер
Запись
HLS
MPEG-DASH
Директивы

Сборка NGINX + nginx-rtmp-module

Для удобства работы с nginx, сначала мы установим его из пакетов, хотя бы, чтобы создались скрипты автозапуска.

Установка nginx и пакетов для сборки

Ubuntu:

apt-get install nginx libpcre++-dev libssl-dev libxslt1-dev libgd2-xpm-dev libgeoip-dev

CentOS:

Настраиваем репозиторий:

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

Теперь переходим по ссылке http://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

И дописываем следующее:

rtmp {
    server {
        listen 1935;
        application cam1 {
            live on;
        }
    }
}

* важно, чтобы данный блок шел не внутри, а отдельно от основного 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.12IP-адрес камеры; 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 в VLC

Вводим URL: rtmp://192.168.0.100/cam1/stream

* где 192.168.0.100 — IP-адрес сервера nginx; cam1 — наш application; stream — наше произвольное название для потока.

Если мы увидим видео с камеры, значит все настроено верно.

Теперь прерываем работу ffmpeg и открываем конфиг nginx:

vi /etc/nginx/nginx.conf

И добавляем следующее:

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;
        }
    }
}

Перезапускаем nginx:

systemctl restart nginx

И снова, но уже не запуская вручную ffmpeg, проверяем наличие видеопотока при помощи VLC.

Несколько камер

Открываем nginx.conf:

vi /etc/nginx/nginx.conf

Настраиваем автоматическое определение воркеров:

worker_processes auto;

* оптимальное число одновременных потоков, позволит nginx работать быстрее.

В корень конфига добавляем:

rtmp_auto_push on;

* включает локальные ретрансляции для использования нескольких воркеров.

Теперь переходим к настройкам rtmp и приводим наш конфиг к следующему виду:

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;
        }
    }
}

На самом деле, его можно также настроить так:

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;
    }
}

Или так:

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;
    }
}

И перезапускаем nginx:

systemctl restart nginx

Запись

Для хранения видео на сервер, есть также несколько варинатов настройки.

1-й вариант: использование нескольких application. В каждом из них своя папка для хранения видео:

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;
        }
    }
}

Создаем папки:

mkdir /tmp/record1 /tmp/record2

Задаем права (владельца):

chown nginx:nginx /tmp/record*

2-й вариант: один application с разными именами для потоков:

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;
    }
}

Необходимо также создать папку и задать владельца:

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 к следующему виду:

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;
    }
}

Перезапуск:

systemctl restart nginx

Ждем 4-5 секунд и смотрим содержимое папок в /tmp:

ls /tmp/cam1

ls /tmp/cam2

Внутри каждой из них мы должны увидеть файл с расширением m3u8 — это плейлист с видеонарезками. Если файлы есть, значит HLS заработал.

Осталось научить наш NGINX отдавать данные файлы. Для этого в секции http добавим:

    location / {
        root /tmp;
    }

И снова:

systemctl restart nginx

В том же VLC для проверки вводим следующий URL:

http://192.168.0.100/cam1/stream.m3u8

MPEG-DASH

Как альтернатива HLS, используется для видеотрансляции поверх HTTP. Его основные преимущества — поддержка со стороны большого количества браузеров и работа на javascript-плеере.

И так, его настройка сильно напоминает настройку HLS. В конфиге NGINX:

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;
    }
}

* обратите внимание, здесь мы решили настроить все в одном 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.

Полный перечень директив опубликован Романом Арутюняном по ссылке:

https://github.com/arut/nginx-rtmp-module/wiki/Directives

# Сервера # Безопасность # Linux # NGINX # UNIX # Ubuntu
Дмитрий Моск — частный мастер
Была ли полезна вам эта инструкция?

Да            Нет