📜 ⬆️ ⬇️

We create a video wall with the image broadcast from ip-cameras via satellite with a minimum of traffic

The article describes how to provide “almost video broadcasting” with ffmpeg, wget, JS, html and such and such mothers . In fact, we create a slideshow with its accurate output and dynamic update on a web page. Perhaps someone will benefit from my experience.
Knowledgeable people will not find anything new in the article for themselves, but if they read it, I would love to hear comments on how to improve this scheme.

Introduction and Prehistory

I work as a system administrator (network support specialist) in a company that, by occupation, has about 10 branches located in the taiga. Internet in all branches, except one, the happiest, is provided via satellite. Satellite Internet, when it is the only way to communicate with the outside world (except for jokes, the nearest village with a connection is usually 70 kilometers away), turns out to be a very unstable and expensive thing.

Among other things (mail, sip-telephony), the Internet in our company is spent on video surveillance. The Directorate is very keen to observe the work in the branches. But little traffic. At the maximum rate of FAP.4000 + .AST 2GB of traffic per day, that in the presence of three two-megapixel cameras is ridiculous. In principle, the image from the cameras can be cut (we do so), but still viewing the cameras without internal traffic restrictions can easily drive the point into a “hard limit” (when the daily traffic limit is reached). One camera with a 128 kbit / s stream per day will eat 1350 mb.

I was given the task to create a kind of “video wall” for the directors, where images from all the cameras of our company would be displayed. With the draconian limitations of satellite Internet, there is no talk about direct streaming from the camera. Software type from Macroscop does not support stream recoding from camera on the fly. To be honest, it seems to me that Macroscop gives its client a bold stream than it receives from the camera. I experimented with VLC (unstable, periodically browser plugin crashes or spontaneously pauses the stream, eats a lot of resources during transcoding), ffmpeg + ffserver (so I did not start this bundle). As a result, I came up with the idea of ​​capturing screenshots from the stream from the cameras and its further transfer to the central office with a predetermined frequency. Everything turned out, but it turned out clumsy and kondovo. I would say Dubove. But it works. I will finish in the future.
')
Technical part

Our cameras are mostly Beward. There are several Hikvision. All cameras (in theory, but practice later) support RTSP. In ideal conditions, we use it. The final image is always issued through ffmpeg - it adjusts the image size and jpg quality, using these parameters, we can control the amount of traffic that flows per day. Also, the frequency of request for frames from the central server affects the amount of traffic.

Next comes JavaScript and some HTML (and a bit of php). On the Internet, I found a script on JS, which dynamically updates the image on the page, but only after downloading it and catching the OnLoad event. A page was prepared for this case, with which I pass the parameters (the name of the camera, the address of its admin, a link to the screenshot).
Personal camera page
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <script type="text/javascript"> var speed = 2; function cam_show() { var imac = document.getElementById('camimage'); var time = now(); imac.onload = function() { start_show(imac, now()-time); document.getElementById('speed').innerHTML = ((now()-time)*(speed+5))/1000; }; imac.src = "<?php echo ($_GET['urlpic']) ?>?r=" + Math.random(); } function now(){ return (new Date).getTime(); } function start_show(img, time) { setTimeout(function() { var ctime = now(); img.onload = function() { start_show(img, now()-ctime) document.getElementById('speed').innerHTML = ((now()-ctime)*(speed+5))/1000; }; img.src = "<?php echo ($_GET['urlpic']) ?>?r=" + Math.random(); }, time*(speed+5)); } </script> <meta http-equiv="Content-Type" content="text/html; charset=windows-1251"> <meta http-equiv="imagetoolbar" content="no"> </head> <?php error_reporting(E_ALL); ?> <body onload="cam_show()"> <center><?php echo "<a class='store' href=\"./cam-get.php?picwidth=60%&urladmin={$_GET['urladmin']}&urlpic={$_GET['urlpic']}&textpage={$_GET['textpage']}\" target=_blank alt=test>{$_GET['textpage']}</a>";?></center> <div align="center"> <img width=<?php echo "{$_GET['picwidth']}";?> id="camimage" src="" alt=""> </div> <center> <?php echo "<div id=\"div1\" style=\"display:{$_GET['visibletxt']}\">" ?> <?php echo "<a class='store' href=\"{$_GET['urladmin']}\" target=_blank>[]</a>";?> <?php echo "<a class='store' href=\"{$_GET['urlpic']}\" target=_blank>[ ]</a>";?> </div> </center> </body> </html> 



How is all of this tied up?

In the branches on the servers (win 2008 r2 or win 7, if it is a separate virtual machine), the following software is installed:



nnCron runs tasks (it is much more stable than the Windows task scheduler), these are ordinary .bat, in which ffmpeg indicates what to get from and where and how and where to put it. If the camera has difficulties with RTSP, the dances begin with ftp, sampling the last screenshot and banging the extras and substituting the correct date into the address, because the Beardard cameras want to put screens at ddmmgggg \ camera_name \ 1 \ *. Jpg. Ugliness, of course, but where to go?

Vindov.bat for processing screenshots from cameras, self-folding them on an ftp-server
 set day=%DATE:~0,2% set month=%DATE:~3,2% set year=%DATE:~6,4% set YYYYMMDD=%year%-%month%-%day% FOR /L %%i IN (0,1,4) DO ( cd "C:\ftp\kpp\%YYYYMMDD%\kpp\1\" c: for /f %%i in ('dir /b /T:A /A:-D /O:-D *.jpg') do (copy /Y "%%i" "c:\ftp\copy\andat-kpp.jpg") C:\ffmpeg\bin\ffmpeg.exe -i "c:\ftp\copy\andat-kpp.jpg" -f image2 -vframes 1 -y -q:v 15 -s 480x360 C:\Apache24\htdocs\andat-kpp.jpg del /Q "C:\ftp\kpp\%YYYYMMDD%\kpp\1\*.jpg" timeout /t 5 /nobreak ) exit 


ffmpeg adds images with the necessary sizes and quality to the root folder of the web server. Then begins the server in the central office, where all this is stored and slipped into the main page, where the video wall is located.

The script that pulls out the screenshots from the branch and adds the old screenshots to the archive
 #!/bin/sh cd /var/www/ mkdir /var/www/archieve/ mkdir /var/www/archieve/tuhterek mkdir /var/www/archieve/tuhterek/gep1/ mkdir /var/www/archieve/tuhterek/polygon/ cp /var/www/tuht-gep1.jpg /var/www/archieve/tuhterek/gep1/gep1-`date +-%d-%m-%Y-%H%M%S`.jpg cp /var/www/tuht-polygon.jpg /var/www/archieve/tuhterek/polygon/polygon-`date +-%d-%m-%Y-%H%M%S`.jpg wget http://172.30.99.80/tuht-gep1.jpg -O tuht-gep1.jpg.bak cp tuht-gep1.jpg.bak tuht-gep1.jpg wget http://172.30.99.80/tuht-polygon.jpg -O tuht-polygon.jpg.bak cp tuht-polygon.jpg.bak tuht-polygon.jpg 


A slice of the video wall
 <iframe src="./cam-get.php?urlpic=http://192.168.1.239/bak_cam200.jpg&picwidth=92%&textpage=26  -  &urladmin=http://192.168.0.200"align=center width="340" height="290" scrolling="no">test</iframe> <iframe src="./cam-get.php?urlpic=http://192.168.1.239/bak_cam201.jpg&picwidth=92%&textpage=26  -   &urladmin=http://192.168.0.201"align=center width="340" height="290" scrolling="no">test</iframe> <iframe src="./cam-get.php?urlpic=http://192.168.1.239/bak_cam202.jpg&picwidth=92%&textpage=26  - &urladmin=http://192.168.0.202"align=center width="340" height="290" scrolling="no">test</iframe> <iframe src="./cam-get.php?urlpic=http://192.168.1.239/bak_cam203.jpg&picwidth=92%&textpage=26  - &urladmin=http://192.168.0.203"align=center width="340" height="290" scrolling="no">test</iframe> <iframe src="./cam-get.php?urlpic=http://192.168.1.239/bak_cam205.jpg&picwidth=92%&textpage=26  -  &urladmin=http://192.168.0.205"align=center width="340" height="290" scrolling="no">test</iframe> <iframe src="./cam-get.php?urlpic=http://192.168.1.239/bak_cam206.jpg&picwidth=92%&textpage=26  -  &urladmin=http://192.168.0.206"align=center width="340" height="290" scrolling="no">test</iframe> <iframe src="./cam-get.php?urlpic=http://192.168.1.239/bak_cam204.jpg&picwidth=92%&textpage=26  - &urladmin=http://192.168.0.204"align=center width="340" height="290" scrolling="no">test</iframe> <iframe src="./cam-get.php?urlpic=http://192.168.1.239/bak_cam207.jpg&picwidth=92%&textpage=26  - &urladmin=http://192.168.0.207"align=center width="340" height="290" scrolling="no">test</iframe> 


The server periodically (several times per minute) extorts all screenshots from the dots, adds instead of the old ones, the old ones go to the archive. At night, another script takes them from the archive, which carefully collects all the screenshots in one video and names it by date and camera name.

The script that compiles the archive of screenshots in the video
 #!/bin/bash tochka=$1 kamera=$2 yestday=`date +%d -d yesterday` year=`date +%Y -d yesterday` mes=`date +%m -d yesterday` stime=`date +%H%M%S -d yesterday` mkdir /var/www/archieve/video/ mkdir /var/www/archieve/video/$tochka mkdir /var/www/archieve/video/$tochka/$kamera mkdir /tmp/picture/ rm /tmp/picture/* echo "$day $mes $year" cd /var/www/archieve/$tochka/$kamera/ find * -type f -size 0k -exec rm {} \; | awk '{ print $8 }' X=1; for i in *.jpg; do mv $i /tmp/picture/$(printf %07d.%s ${X%.*} ${i##*.}) let X="$X+1" done cd /tmp/picture/ ffmpeg -f image2 -r 1 -i %07d.jpg -y /var/www/archieve/video/$tochka/$kamera/$kamera-$yestday-$mes-$year.avi 


Screenshot flowchart



Future plans

I would very much like to get rid of the need to prescribe the same parameters n times in different scripts. I plan to save the settings <somewhere>, take them from there as necessary and automatically generate the necessary scripts when adding the desired camera.
I plan to fasten the form of adding a new camera.

I would like to transfer everything to linux (it is not always possible to deploy virtual machines with it now, the company uses Win-server and hyper-v mainly).

I would like greater reliability, increasing the quality of images and their update frequency, but without a strong increase in traffic.

This is not the very first version, but it is still far from perfect. This can be said to be a prototype. Therefore, criticism (constructive) is welcomed, but cries of "cyclist on crutches" are not. I know myself. But, since the finished software does not fulfill our desires, you have to dodge and do it yourself.

PS

About errors in a personal, please, or mail.

UPD:

Part of a home-made monitoring system
Clickable


The inscription “site available” is issued using a php script that checks the availability of the camera admin panel on http. When you hover on the image in the left column pops up a full-sized window.
I will insert the wall a little later.

Source: https://habr.com/ru/post/239853/


All Articles