«Нет времени объяснять!» или Как реализовать трансляцию с IP камеры на сайт?

image


Пожалуй, мне везет на идиотские задачи в самый неподходящий момент. Это что, карма такая?! Ну да ладно…
В данном «отпускном» посте речь пойдет о том, как при наличии 3g модема и ноутбука реализовать трансляцию с IP-камеры на сайт.
Сам пост я бы не написал, если бы не задал вопрос на «Тостере», где мне подсказали, что гуглить.

Что мы имеем?


  1. Недешевая IP камера AXIS Q1755, которую я даже в руках не держал. Сама камера находится в городе «А» и подключена через тормозной 3g модем.
  2. Сервер на Debian 7, который крутится на почти дохлом Core2Duo. Хотя не такой уж он и дохлый, но для данных задач подходит не очень. Ах, да, сам сервер живет в городе Б.
  3. Сайт, на который необходимо повесить плеер. Находится на другом, более производительном сервере, в том же городе Б.
  4. Я, который находится в городе В, с ноутбуком, 3g-модемом и ограниченным трафиком в 4gb.


При помощи чего мы все это реализуем? Сама камера будет передавать поток по RTSP, FFmpeg будет принимать его и конвертировать в RTMP, а при помощи JW Player этот поток можно «повесить на сайт».

Для тех, кто любит наглядно – получайте:

image


Ну а теперь главное, что же нужно сделать, чтобы заиметь у себя такую штуку?

Подготовка


Для начала нам необходимо все подготовить и установить необходимые пакеты. Например, для сборки Nginx понадобится Perl библиотека регулярных выражений и заголовки OpenSSL:

apt-get install libpcre3 libpcre3-dev libssl-dev


Так же поставим утилиту rtmpdump, которая позволит нам понять, работает ли у нас rtmp или нет:

apt-get install rtmpdump


Далее скачаем сами исходники Nginx, стабильной версии 1.6.0 и распакуем их:

wget http://nginx.org/download/nginx-1.6.0.tar.gz
tar -xzvf nginx-1.6.0.tar.gz


Тоже самое сделаем и с модулем, с которым нам нужно будет скомпилировать Nginx:

wget https://github.com/arut/nginx-rtmp-module/zipball/master -O nginx-rtmp-module-master.zip
unzip nginx-rtmp-module-master.zip -d nginx-rtmp-module-master


Сборка Nginx с поддержкой rtmp


Теперь приступим к сборке. Для начала нужно сконфигурировать Nginx:
cd nginx-1.6.0
./configure --prefix=/usr --add-module=../nginx-rtmp-module-master/arut-nginx-rtmp-module-0bb2323/ --pid-path=/var/run/nginx.pid --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --with-http_ssl_module

На выходи мы должны получить что-то подобное:
...
<pre>configuring additional modules
<strong>adding module in ../nginx-rtmp-module-master/arut-nginx-rtmp-module-0bb2323/</strong>
<strong> + ngx_rtmp_module was configured</strong>
checking for PCRE library ... found
checking for PCRE JIT support ... found
checking for OpenSSL library ... found
checking for zlib library ... found
creating objs/Makefile</pre>
<pre>Configuration summary
 + using system PCRE library
 + using system OpenSSL library
 + md5: using OpenSSL library
 + sha1: using OpenSSL library
 + using system zlib library</pre>
<pre><strong> nginx path prefix: "/usr"</strong>
<strong> nginx binary file: "/usr/sbin/nginx"</strong>
<strong> nginx configuration prefix: "/etc/nginx"</strong>
<strong> nginx configuration file: "/etc/nginx/nginx.conf"</strong>
<strong> nginx pid file: "/var/run/nginx.pid"</strong>
<strong> nginx error log file: "/var/log/nginx/error.log"</strong>
<strong> nginx http access log file: "/var/log/nginx/access.log"</strong>
<strong> nginx http client request body temporary files: "client_body_temp"</strong>
<strong> nginx http proxy temporary files: "proxy_temp"</strong>
<strong> nginx http fastcgi temporary files: "fastcgi_temp"</strong>
<strong> nginx http uwsgi temporary files: "uwsgi_temp"</strong>
<strong> nginx http scgi temporary files: "scgi_temp"</strong>

Важно, чтобы сам rtmp модуль подключился и пути к логам, конфигам и бинарнику были верными. Выше я выделил то, что нужно проверить. Если все хорошо, то компилируем и устанавливаем:
make
make install

Теперь скопируем файл stat.xsl из папки с исходниками в папку nginx:
cp nginx-rtmp-module-master/arut-nginx-rtmp-module-0bb2323/stat.xsl /etc/nginx/

И проверим работу самого nginx.
service nginx start

Заходим на http:// ip_servera. Видим приветствие Nginx? Тогда все хорошо.

Установка FFmpeg и проверка его работы


Для того, чтобы мы смогли конвертировать поток rtsp в fvl, нам понадобится ffmpeg.

Да, кстати, если вы проделывайте все эти действия на Ubuntu, то имейте в виду, что в этом Ubuntu FFmpeg считается устаревшим, и в замен предлагает использовать avconv. Не пугайтесь, замена «шила на мыло» ничего не сломает, все будет работать.

Ладно, подключаем репозитории FFmpeg и ставим его:

apt-add-repository ppa:jon-severinsson/ffmpeg
apt-get update
apt-get install ffmpeg


Теперь проверим, насколько удачно подключается ffmpeg к камерам. Я, например, забыл открыть доступ на маршрутизаторе к 554 порту.

ffmpeg -i rtsp://admin:admin@10.10.10.11/axis-media/media.amp


На выходе мы должны будем получить что-то подобное:

ffmpeg version 1.0.10 Copyright (c) 2000-2014 the FFmpeg developers
built on Jul 25 2014 07:50:40 with gcc 4.7 (Debian 4.7.2-5)
configuration: --prefix=/usr --extra-cflags='-g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security ' --extra-ldflags='-Wl,-z,relro' --cc='ccache cc' --enable-shared --enable-libmp3lame --enable-gpl --enable-nonfree --enable-libvorbis --enable-pthreads --enable-libfaac --enable-libxvid --enable-postproc --enable-x11grab --enable-libgsm --enable-libtheora --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libx264 --enable-libspeex --enable-nonfree --disable-stripping --enable-libvpx --enable-libschroedinger --disable-encoder=libschroedinger --enable-version3 --enable-libopenjpeg --enable-librtmp --enable-avfilter --enable-libfreetype --enable-libvo-aacenc --disable-decoder=amrnb --enable-libvo-amrwbenc --enable-libaacplus --libdir=/usr/lib/x86_64-linux-gnu --disable-vda --enable-libbluray --enable-libcdio --enable-gnutls --enable-frei0r --enable-openssl --enable-libass --enable-libopus --enable-fontconfig --enable-libfdk-aac --enable-libdc1394 --disable-altivec --dis libavutil 51. 73.101 / 51. 73.101
libavcodec 54. 59.100 / 54. 59.100
libavformat 54. 29.104 / 54. 29.104
libavdevice 54. 2.101 / 54. 2.101
libavfilter 3. 17.100 / 3. 17.100
libswscale 2. 1.101 / 2. 1.101
libswresample 0. 15.100 / 0. 15.100
libpostproc 52. 0.100 / 52. 0.100
[rtsp @ 0x19d6cc0] Estimating duration from bitrate, this may be inaccurate
Input #0, rtsp, from 'rtsp://admin:admin@10.10.10.11/axis-media/media.amp':
Metadata:
title : Media Presentation
Duration: N/A, start: 0.570122, bitrate: N/A
Stream #0:0: Video: h264 (Baseline), yuvj420p, 1280x720 [SAR 1:1 DAR 16:9], 25 tbr, 90k tbn, 180k tbc
At least one output file must be specified


Это доказывает, что камера работает, вещает rtsp поток и ffmpeg работает.

Настройка Nginx и проверка его работы


Теперь открываем файл коyфигурации nginx своим любимым редактором (у меня это vim):

vim /etc/nginx.conf


И приводим его к следующему состоянию:

user nginx;
# Узнать сколько ядер в системе можно при помощи команды nproc
worker_processes 2;
 
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
 
events {
  worker_connections 1024;
}
 
http {
  include /etc/nginx/mime.types;
  default_type application/octet-stream;
 
  log_format main '$remote_addr - $remote_user [$time_local] "$request" '
  '$status $body_bytes_sent "$http_referer" '
  '"$http_user_agent" "$http_x_forwarded_for"';
 
  access_log /var/log/nginx/access.log main;
  sendfile on;
  #tcp_nopush on;
  keepalive_timeout 65;
  #gzip on;
 
  server {
    listen 80;
    # rtmp stat
    location /stat {
     rtmp_stat all;
     rtmp_stat_stylesheet stat.xsl;
    }
 
    location /stat.xsl {
     # you can move stat.xsl to a different location
     root /etc/nginx/;
    }
 
    location / {
     rtmp_control all;
    }
 
    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
    root html;
  }
  #Добавим locations для просмотра статических изображений с камеры
  location /image/cam1/ {
    proxy_pass "http://10.10.10.11/axis-cgi/jpg/image.cgi";
  }
 }
 include /etc/nginx/conf.d/*.conf;
}
 
rtmp {
 access_log /var/log/nginx/rtmp_access.log;
 server {
 listen 1935;
 ping 30s;
 notify_method get;
 application cam1 {
   live on;
   exec_pull ffmpeg -i rtsp://admin:admin@10.10.10.11/axis-media/media.amp -threads 2 -f flv -r 25 -s 1280x720 -an rtmp://localhost:1935/cam1/stream 2>>/var/log/nginx/ffmpeg.log;
 }
 }
}


Сохраняем, закрываем, проверяем:

nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
service nginx restart


Проверить корректность работы RTMP сервера на базе NGINX можно следующей командой:

rtmpdump -r "rtmp://127.0.0.1:1935/cam1/stream" -v


Вывод видео вы получите пряма в консоль.

Подключение нашего потока к JWPlayer


Ну и последнее, что вам нужно будет сделать, так это зарегистрироваться на сайте www.jwplayer.com, получить код плеера и привести его к следующему виду:

<div id='player...'></div>
<script type='text/javascript'>
 jwplayer('player...').setup({
 file: 'rtmp://10.10.10.11:1935/cam1/stream',
 image: 'http://10.10.10.11/image/cam1/',
 width: '1280',
 height: '720',
 aspectratio: '16:9'
 });
</script>


Все, задача выполнена, наслаждайтесь!

Источники и прочие вспомогательные ресурсы


RTMP вещание с web-камер
Организация видеотрансляции на сайте. VLC+Erlyvideo+HLS+nginx.
image Захват видео с сетевых камер, часть 1
image Захват видео с сетевых камер, часть 2
image Сервер онлайн-вещаний на базе nginx
image Вещание онлайн-видео с помощью nginx
image Еще раз о видеонаблюдении, камерах, RTSP, onvif. И «велосипед»!
image Создание полноценного видеохостинга своими руками (nginx+php5-fpm+ffmpeg+cumulusclips)
How to set up your own private RTMP server using nginx
help.ubuntu.com/community/FFmpeg
github.com/arut/nginx-rtmp-module
toster.ru/q/128005
jwplayer.com
support.jwplayer.com: Using RTMP Streaming
Бесплатный плеер для сайта JW Player: облачное подключение
Поделиться публикацией
Ой, у вас баннер убежал!

Ну. И что?
Реклама
Комментарии 31
    +2
    motion. Там проще :)
      0
      Уточните пожалуйста, камера с 3G-модемом имеет белый IP? Или через сеть провайдера имеете доступ к серому IP 3G-модема (камеры)? Или камера имеет какие-то возможности настройки по транслации потока на некий сервер с белым IP?
        0
        Саму сеть на камере я не настраивал, но на сколько я знаю, у камеры внешний фиксированный ip, настраивал оператор связи.
        А сама по себе камера имеет множество настроек (не даром она стоит около 50-80 тысяч).
          +1
          Хреновое качество для такой цены.
        0
        >>ffmpeg version 1.0.10

        Взяли бы что посвежее. Уже давным давно вторая ветка есть.
          +1
          я уже думал об этом, и первым делом, приехав в Москву, опробую данную вариацию с avconv
            0
            Можно ограничиться checkinstall, собрав именно ffmpeg под себя.

            А вообще, сам давно хочу настроить себе пару-тройку камер дома. Может ваш пост наконец перевесит чашу с ленью, и сделаю таки)
              0
              Как человек, который довольно много использует ffmpeg и не так часто libav, советую вам как можно быстрее переходить на ffmpeg.
                0
                А почему, если не секрет?
                  0
                  Меньше багов, больше возможностей.
            +1
            Если бы я не верил в параллельные миры и единство сверхразума человека, я бы поверил в него сейчас. Данная статья является выжимкой моих изысканий с нуля в свободное время за последнюю неделю. Прям один в один)

            Что могу добавить, так это auto_push on для конфига nginx, если используется более чем 1 воркер.

            И еще вопрос, кто-нибудь знает, чем можно задетектть движение на _записанном_ видео. Motion и zoneminder делают это только с потока
              +2
              «У дураков мысли только сходятся, а у умных еще и вступают в дискуссию.» )
              Про auto_push — учту.
                0
                Как раз этой темой занимаюсь, тоже с нуля, только gstreamer использую и тоже про auto_push хотел добавить.)
                +6
                При сборке пакета все же нужно использовать checkinstall.
                  +1
                  Редко занимался сборкой, как правило все ставил с репозиториев и «не жаловался». И тут решил сделать все по старинке.
                  Пожалуй по итогам всех комментариев у меня будет вторая версия статьи)
                  +2
                  Минусующих за motion до фига, а объяснить?
                    +2
                    Несколько лет назад писал утилиту, которая подключалась к нескольким RTSP камерам (4), склеивала с них видеопоток в одну картинку и отправляля по MJPEG в браузере. Не написал только поддержку большого количества одновременных клиентов (хотя могу ошибаться, не помню уже).

                    Задание было в том, чтобы наблюдать за процессом стройки по хреновому 3G каналу. Запускал скрипт на ubuntu c 3G модемом, а наблюдатель мог подключаться по IP.

                    Код тут code.google.com/p/camproxy/
                        +1
                        ИМХО нужно вводить штрафы на законодательном уровне за установку приложений в обход пакетного менеджера. А за публичный призывы делать это в статьях и руководствах — месяц исправительных работ в виде чтения манов и сборки пакетов.
                        0
                        На каждую камеру по экземпляру ffmpeg будете запускать?
                          0
                          По сравнению с flussonic выйдет в 2-3 раза хуже по оперативной памяти, но по загрузке процессора примерно одинаково. Хотя, если потратить стоимость лицензии флуссоника на покупку оперативной памяти в сервер, и если не требуется вменяемого просмотра архива, то будет ok :)
                            0
                            Ок будет, пока не попадется китайская камера на софии =)
                            0
                            Интересно, а flussonic разве при перекодировке используя ffmpeg не точно так же делает?
                              0
                              термин перекодировка в видео слегка неточен.

                              При транскодировании — да, будет отдельный процесс. Больше 20 их на сервер всё равно не будет, поэтому наличие отдельных процессов — не беда.

                              При захвате и перепаковке, флюссоник может захватить до 600-800 камер. Мне было бы интересно посмотреть на сервер с 600 запущенными ffmpeg-ами
                            0
                            В своё время подобное делалось на VLC (rtsp-flv перекодирование).
                              +1
                              /usr/bin/vlc -vvv --loop --http-reconnect rtsp://160.74.34.2:554 --sout "#std{access=http{mime=video/x-flv},mux=ffmpeg{mux=flv},dst=:9109/camera1.flv}"
                                0
                                ага
                              0
                              А кто подскажет вариант с низкой задержкой,
                              Данная сборка у меня давала задержку относительно камеры до 10 секунд.
                              Идеально было бы с задержкой менее секунды opensource под linux.
                                0
                                Такая большая задержка возникала из-за конвертирования видео и его кеширования.
                                Я использовал mjpeg — там действительно удавалось достигнуть задержки в районе секунды и меньше — там больше были уже транспортные задержки, т.к. видео поток 640х480 20 fps был около одного мегабита
                                +1
                                Спасибо, dnbdrive, отличная статья, сегодня по ней сделал вещание.

                                Маленькое дополнение: на момент сентября 2015 в конфиге rtmp название потока должно быть равным названию application, иначе трансляция не запускается. Например:

                                rtmp {
                                    …
                                    application cam1 {
                                        live on;
                                        exec_pull ffmpeg -i rtsp://10.10.10.11/h264 -threads 1 -f flv -r 25 -s 1280x720 -an rtmp://localhost:1935/cam1/stream 2>>/var/log/nginx/ffmpeg.log;
                                        }
                                    }
                                }

                                  +1
                                  Спасибо, конфиг поправил ;)

                                Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                Самое читаемое