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

ipcam_coverПожалуй мне везет на идиотские задачи в самый неподходящий момент. Это что, карма такая?! Ну да ладно..

В данном «отпускном» посте речь пойдет о том, как при наличии 3g модема и ноутбука реализовать трансляцию с IP камеры на сайт.

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

 

Что мы имеем?

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

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

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

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

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

Подготовка.

Для начала нам необходимо все подготовить и установить необходимые пакеты. Например для сборки 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<br />
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<br />
unzip nginx-rtmp-module-master.zip -d nginx-rtmp-module-master

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

Теперь приступим к сборке. Для начала нужно сконфигурировать Nginx:

cd nginx-1.6.0<br />
./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

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

...<br />
&lt;pre&gt;configuring additional modules<br />
&lt;strong&gt;adding module in ../nginx-rtmp-module-master/arut-nginx-rtmp-module-0bb2323/&lt;/strong&gt;<br />
&lt;strong&gt; + ngx_rtmp_module was configured&lt;/strong&gt;<br />
checking for PCRE library ... found<br />
checking for PCRE JIT support ... found<br />
checking for OpenSSL library ... found<br />
checking for zlib library ... found<br />
creating objs/Makefile&lt;/pre&gt;<br />
&lt;pre&gt;Configuration summary<br />
 + using system PCRE library<br />
 + using system OpenSSL library<br />
 + md5: using OpenSSL library<br />
 + sha1: using OpenSSL library<br />
 + using system zlib library&lt;/pre&gt;<br />
&lt;pre&gt;&lt;strong&gt; nginx path prefix: &quot;/usr&quot;&lt;/strong&gt;<br />
&lt;strong&gt; nginx binary file: &quot;/usr/sbin/nginx&quot;&lt;/strong&gt;<br />
&lt;strong&gt; nginx configuration prefix: &quot;/etc/nginx&quot;&lt;/strong&gt;<br />
&lt;strong&gt; nginx configuration file: &quot;/etc/nginx/nginx.conf&quot;&lt;/strong&gt;<br />
&lt;strong&gt; nginx pid file: &quot;/var/run/nginx.pid&quot;&lt;/strong&gt;<br />
&lt;strong&gt; nginx error log file: &quot;/var/log/nginx/error.log&quot;&lt;/strong&gt;<br />
&lt;strong&gt; nginx http access log file: &quot;/var/log/nginx/access.log&quot;&lt;/strong&gt;<br />
&lt;strong&gt; nginx http client request body temporary files: &quot;client_body_temp&quot;&lt;/strong&gt;<br />
&lt;strong&gt; nginx http proxy temporary files: &quot;proxy_temp&quot;&lt;/strong&gt;<br />
&lt;strong&gt; nginx http fastcgi temporary files: &quot;fastcgi_temp&quot;&lt;/strong&gt;<br />
&lt;strong&gt; nginx http uwsgi temporary files: &quot;uwsgi_temp&quot;&lt;/strong&gt;<br />
&lt;strong&gt; nginx http scgi temporary files: &quot;scgi_temp&quot;&lt;/strong&gt;<br />

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

make<br />
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<br />
apt-get update<br />
apt-get install ffmpeg

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

ffmpeg -i rtsp://admin:[email protected]/axis-media/media.amp

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

ffmpeg version 1.0.10 Copyright (c) 2000-2014 the FFmpeg developers<br />
built on Jul 25 2014 07:50:40 with gcc 4.7 (Debian 4.7.2-5)<br />
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<br />
libavcodec 54. 59.100 / 54. 59.100<br />
libavformat 54. 29.104 / 54. 29.104<br />
libavdevice 54. 2.101 / 54. 2.101<br />
libavfilter 3. 17.100 / 3. 17.100<br />
libswscale 2. 1.101 / 2. 1.101<br />
libswresample 0. 15.100 / 0. 15.100<br />
libpostproc 52. 0.100 / 52. 0.100<br />
[rtsp @ 0x19d6cc0] Estimating duration from bitrate, this may be inaccurate<br />
Input #0, rtsp, from 'rtsp://admin:[email protected]/axis-media/media.amp':<br />
Metadata:<br />
title : Media Presentation<br />
Duration: N/A, start: 0.570122, bitrate: N/A<br />
Stream #0:0: Video: h264 (Baseline), yuvj420p, 1280x720 [SAR 1:1 DAR 16:9], 25 tbr, 90k tbn, 180k tbc<br />
At least one output file must be specified

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

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

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

vim /etc/nginx.conf

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

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

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

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

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

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

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

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

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

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

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

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

  • https://www.sinyawskiy.ru/nginxrtmpmodule.html
  • https://help.ubuntu.com/community/FFmpeg
  • https://github.com/arut/nginx-rtmp-module
  • http://osdrive.ru/blog.php?page=entry&action=read&id=22
  • http://habrahabr.ru/post/117735/
  • https://toster.ru/q/128005
  • jwplayer.com
  • http://support.jwplayer.com/customer/portal/articles/1430358-using-rtmp-streaming
  • http://rugraphics.ru/forvideo/pleer-dlya-sayta-jw-player-oblachnoe-podklyuchenie
  • http://habrahabr.ru/post/162237/
  • https://obsproject.com/forum/resources/how-to-set-up-your-own-private-rtmp-server-using-nginx.50/
  • http://habrahabr.ru/post/145867/
  • http://habrahabr.ru/post/233237/
  • http://flance.onego.ru/2012/09/07/387
  • http://habrahabr.ru/post/188380/