📜 ⬆️ ⬇️

IPTV monitoring

There was a need to monitor multicast streams. Began the search for ready-made solutions. The first thing that managed to google: IPTV-Analyzer , NetUP IPTVProbe . Each solution had its drawbacks or cost a lot of money. It was decided to create its own monitoring. The main task is to notify and log a multicast stream drop.

Mechanism:
Using ffmpeg, we connect to the stream for NN time, the frame starts shooting from NN seconds, so that there are no artifacts in the picture. If within NN seconds it is impossible to get something, then we write to the database with a withdrawal error. It's pretty simple.

Let's start installing the main components:
sudo apt-get install apache2 php5 mysql-server libapache2-mod-php5 libapache2-mod-auth-mysql php5-mysql ffmpeg

apache - for the web interface.
mysql - in the database we will store the data necessary for statistics, and the list of channels.
ffmpeg - we will need to take screenshots from a multicast stream.
')
The main components are installed, proceed to configure.

In the directory (the default used by apache2 / var / www /), create a dbinit.php file with the database connection settings:

 <?php $dbhost = "localhost"; $dbname = "name"; $dbuser = "user"; $dbpass = "password"; mysql_connect($dbhost, $dbuser, $dbpass); mysql_query("set character_set_client='utf8'"); mysql_query("set character_set_results='utf8'"); mysql_query("set collation_connection='utf8_general_ci'"); mysql_select_db($dbname); ?> 


Base structure:
date - TIMESTAMP (Date of falling or raising the channel)
name - TEXT (Channel Name)
state - TEXT (State: true-raise, false-fall)

It is necessary for further calculation of how long the channel has been in Down.

Create a script that will generate well and, in fact, “monitor” channels.
Let's call it gen.php

 <?php include "dbinit.php"; $query = "SELECT * FROM `name`"; $result = mysql_query($query); if (!$result) { print "<center>:" . mysql_error() . "</center>"; } elseif (mysql_num_rows($result) == 0) { print ""; } else { $rows = array(); while ($row = mysql_fetch_assoc($result)) { $rows[]= $row; } foreach($rows as $row) { echo exec('/usr/bin/timeout 20s /usr/bin/time -f %U -o /var/www/tmp/'.$row['name'].'.txt /usr/bin/ffmpeg -i udp://@'.$row['mcast'].' -y -f image2 -sameq -t 0.001 -ss 00:00:4 -s 120*80 /var/www/screen/'.$row['mcast'].'.jpg'); echo exec('/bin/cp -f /var/www/tmp/'.$row['mcast'].'.txt /var/www/rez/'); } ?> 

Let's take a closer look at the script lines.
To execute the script, set the timeout for execution (timeout 20s) , if the channel is unavailable - it will hang for a very long time.
Time to take a screenshot write to the file:
  /usr/bin/time -f %U -o /var/www/tmp/'.$row['name'].'.txt 

Screenshot removal
 /usr/bin/ffmpeg -i udp://@'.$row['name'].' -y -f image2 -sameq -t 0.001 -ss 00:00:4 -s 120*80 /var/www/screen/'.$row['name'].'.jpg 


Getting results and adding them to the database:
Create a file rez.php

 <?php $lines = file ('rez/'.$row['mcast'].'.txt'); if ($lines[0]=='') { $last_result=mysql_result(mysql_query("select state from name where name='".$row['name']."' order by date desc limit 0,1"),0); if($last_result=='true') { $query = "INSERT INTO `name` (`date`, `name`, `state`) VALUES ('{$date}', '{$row['name']}', 'false');"; mysql_query($query) or die(mysql_error()); } foreach ($A as $v) { echo exec('/usr/bin/perl /usr/local/scripts/jabber_alert.pl -e '.$v.'@jabber.server -n tv@jabber.server -w password -y '.translitIt ($row['name']).'-'.$row['mcast'].' << "EOF" read -d "^D" input'); } } else { $last_result=mysql_result(mysql_query("select state from name where name='".$row['name']."' order by date desc limit 0,1"),0); echo $last_result; if($last_result=='false') { $query = "INSERT INTO `name` (`date`, `name`, `state`) VALUES ('{$date}', '{$row['name']}', 'true');"; mysql_query($query) or die(mysql_error()); } echo $row['name']." ". $lines[1]." "; } ?> 

With successful removal of the screenshot, the execution time is written to the file if the file fails to be empty. In the script, we check for the contents in the file.

We send by Jaber about the fallen channel
 echo exec('/usr/bin/perl /usr/local/scripts/jabber_alert.pl -e '.$v.'@jabber.server -n tv@jabber.server -w password -y '.translitIt ($row['name']).'-'.$row['mcast'].' << "EOF" read -d "^D" input'); 

jabber_alert.pl

Create index.php

 <?php foreach($rows as $row) { $work=mysql_result(mysql_query("select date from name where date>'".$row['date']." order by date limit 0,1'"),0); $date1 = new DateTime($work); $date2 = new DateTime($row['date']); $interval = $date2->diff($date1); if($work=="") { $style="red"; } else { $style="";} echo "<tr><td style='color:".$style."'><font color='red'>".$row['date']; if($work!="") { echo "</font> - <font color='green'>".$work."</font>"; } echo "</td><td>"; if($interval->format("%h") != 0) { echo $interval->format("%h. "); } echo $interval->format("%i. %s.")."</td><td style='color:".$style."'>".$row['name']."</td></tr>"; } ?> 

We deduce the fallen / raised channels and color them.

We add to the cron the execution of two scripts.
The solution is not so elegant, but it works and performs its tasks.

Having finished it is possible to receive it:

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


All Articles