Diffusez RTSP sur WEB. Conversion en HLS. Solution en boîte

La tâche était de collecter tous les flux RTSP à partir d'un enregistreur vidéo (netsurveillance) et de fournir un accès rapide au flux vidéo pour plusieurs personnes. Puisqu'aucun navigateur ne peut afficher indépendamment le protocole RTSP, il était nécessaire de trouver quoi que ce soit pour convertir ce flux en un format adapté au WEB.



Je vais faire une réservation tout de suite: lors du fonctionnement de cette solution, la possibilité de partager une archive vidéo à l'aide de SAMBA a été découverte. Cette opportunité m'a paru très pratique personnellement, et j'ai décidé de la mettre en œuvre dans ce contexte. Bien sûr, quelqu'un peut avoir une question: "Y a-t-il une ligne et pourquoi tout le reste est-il nécessaire?" - dans notre cas, cette solution s'est avérée trop coûteuse. Et ils comptent toujours en dollars . Alors ce qui est disponible:



  • Réseau d'entreprise basé sur Mikrotik utilisant un VPN standard
  • Plusieurs vidéosurveillance comprenant une variété de caméras et un enregistreur vidéo
  • Machine Linux avec SAMBA-AD-DC et serveur WEB déployés dans le bureau central


Vaut-il la peine de rappeler que le tout est en cours de conversion de RTSP en HLS? J'installe l'hôte Shinobi sur Linux selon cette instruction . Il n'y a rien de compliqué dans l'installation, il vous suffit d'installer git, quelques dépendances et d'exécuter le script d'installation. Techniquement la même ligne, uniquement gratuitement. Peut-être assez pour la première fois. L'interface semble seulement plus pratique, sinon la même chose. Après l'installation et le lancement, ouvrez localhost : 8080 / super, connectez-vous en tant que admin@shinobi.video avec le mot de passe admin et créez une entrée principale pour accéder à la surveillance.



Les options de stockage par défaut ne fonctionnaient pas pour moi. De plus, pendant le fonctionnement, j'ai cherché ces paramètres pendant longtemps, mais l'urgence m'a obligé à simplement désactiver cron.js (sudo pm2 stop cron) et à utiliser les outils Linux pour nettoyer les répertoires d'archives vidéo.



image



Nombre de jours pour conserver les vidéos - le nombre de jours pour conserver les vidéos.

Nombre de jours pour conserver les événements - le nombre de jours pour conserver les événements (connexions, changements de mot de passe, etc.).

Nombre de jours pour conserver les journaux - le nombre de jours pour conserver les messages système: échecs, erreurs, initialisation.



Tous ces paramètres sont réglés individuellement pour chaque utilisateur, très pratique. Mais il existe aussi une API. En utilisant ses moyens, vous pouvez obtenir tous les flux d'un moniteur spécifique (un moniteur est un ensemble de flux pour la diffusion) et présenter chacun d'eux séparément en tant que diffusion en ligne sur une page Web. Tout d'abord, vous devez ajouter des informations sur les flux des caméras de vidéosurveillance à la surveillance.



image



image



image



Mode - mode diffusion: enregistrement - enregistrement, lecture seule - visualisation uniquement.

Nom - le nom du flux vidéo

Emplacement de stockage - l' emplacement de stockage des archives, si vous avez défini Enregistrer en mode

Chemin d'URL complet - un lien vers le flux rtsp lui-même. Pour la netsurveillance, il s'agit généralement du lien: rtsp: // IP: 554 / user = USER & password = PASSWORD & channel = CHANNELNUMBER & stream = 1.sdp? Real_stream - rtp-caching = 100 Les



informations de consommation de ressources affichées dans Shinobi diffèrent grandement de celui affiché par htop . Dans l'interface Web, je vois constamment de la mémoire à moitié pleine, mais la charge du processeur, en passant, est assez cohérente avec ce que l'on peut voir depuis la console.



image



Pour autant que l'on sache, il est également possible d'utiliser le GPU du système pour convertir le flux. Mais comme nous ne l'avons pas installé, il n'y avait aucun moyen de s'en assurer. Tout se passe au moyen du CPU. Nous avons converti 17 flux, dont 3 sont enregistrés localement. Je vais donner ici des informations sur notre processeur:



lscpu
Architecture: x86_64

CPU op-mode(s): 32-bit, 64-bit

Byte Order: Little Endian

Address sizes: 36 bits physical, 48 bits virtual

CPU(s): 8

On-line CPU(s) list: 0-7

Thread(s) per core: 2

Core(s) per socket: 4

Socket(s): 1

NUMA node(s): 1

Vendor ID: GenuineIntel

CPU family: 6

Model: 30

Model name: Intel(R) Xeon(R) CPU X3440 @ 2.53GHz

Stepping: 5

CPU MHz: 1210.183

CPU max MHz: 2534,0000

CPU min MHz: 1200,0000

BogoMIPS: 5066.32

Virtualization: VT-x

L1d cache: 32K

L1i cache: 32K

L2 cache: 256K

L3 cache: 8192K

NUMA node0 CPU(s): 0-7








Si vous avez uniquement besoin de connecter une diffusion en ligne sur une page Web, vous devez d'abord ajouter la clé API à l'utilisateur dont le moniteur nous intéresse. Un guide API complet est disponible sur le site officiel de l' application. En haut, placez le curseur sur l'e-mail de l'utilisateur, cliquez sur, sélectionnez l'élément API.



image



Le paramètre principal pour nous est les adresses IP autorisées (IP autorisées). Mon accès est ouvert uniquement pour le réseau local, mais si vous prévoyez de diffuser vos flux sur Internet mondial, vous devez spécifier 0.0.0.0/0 et transférer le port Shinobi à l'extérieur.



, Shinobi RTSP , -. . : , 100% -, - RJ-45. , IP : - . AHD . , , ( ) — , .


Les informations sur les flux Web peuvent être obtenues avec une simple requête GET, le résultat est obtenu au format JSON, qui peut être facilement converti en données. Un exemple de script PHP simple:



<?php
 
$url = array(
    'host'          => '192.168.2.104',                      # ,    Shinobi
    'port'          => '8080',                               #  web- Shinobi
    'api'           => 'TyIp1yRhqPLnJmlDpMzAenWYqVW8vt', # API 
    'monitor'       => 'f2xnMN0VAv'                          # ID ,   
);
 
$link = file_get_contents("http://". $url['host'] .":". $url['port'] ."/". $url['api'] ."/monitor/". $url['monitor'] ."/");
 
foreach(json_decode($link) as $data) {
     
    $source['title'][]  = $data->name;
    $source['url'][]    = "http://". $url['host'] .":". $url['port'] . $data->streams[0];
    $source['width'][]  = $data->width;
    $source['height'][] = $data->height;
    $source['status'][] = $data->status;
 
}
 
print "<html>
 
    <head>
        <title> </title>
        <link rel='stylesheet' href='https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css' integrity='sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T' crossorigin='anonymous'>
        <link href='https://vjs.zencdn.net/7.2.3/video-js.css' rel='stylesheet'>
    </head>
    <body>
     
    <div class='container' style='padding: 30pt 0;'>
 
        <div class='row'>
        <div class='col-sm-12' style='margin: 10pt 0 10pt;'>  
 
            <div class='card'>
                <div class='card-body'>
 
                <form action='' method='POST'>
                  <select class='form-control form-control-lg' name='streamId' onchange='this.form.submit()'>
                    ";
 
for($i = 0; $i <= count($source['title']); $i++){
     
    if( $_POST['streamId'] == $i) {
        print "<option value=". $i ." selected>". $source['title'][$i] ."</option>";
    } else {
        print "<option value=". $i .">". $source['title'][$i] ."</option>";
    }
}
 
if( isset($_POST['streamId']) ) {
    $id = $_POST['streamId'];
} else {
    $id = 0;
}
 
print "         </select></form>
        </div>
      </div>
</div>
 
<div class='col-sm-12'>   
 
    <div class='card'>
        <div class='card-body'>
         <video id='hls-example' style='margin: 0 auto;' class='video-js vjs-default-skin' width='". $source['width'][$id] ."' height='". $source['height'][$id] ."' controls>
            <source type='application/x-mpegURL' src='". $source['url'][$id] ."'>
            </video>
         <!-- <p class='card-text'>This is another card with title and supporting text below. This card has some additional content to make it slightly taller overall.</p> -->
          <p class='card-text' style='text-align: center;'> <small class='text-muted'>  : ". $source['status'][$id] ."</small></p>
        </div>
      </div>
    </div>
 
</div>
 
 
    <script src='https://vjs.zencdn.net/ie8/ie8-version/videojs-ie8.min.js'></script>
    <script src='https://cdnjs.cloudflare.com/ajax/libs/videojs-contrib-hls/5.14.1/videojs-contrib-hls.js'></script>
    <script src='https://vjs.zencdn.net/7.2.3/video.js'></script>
 
    <script>
    var player = videojs('hls-example');
    player.play();
    </script>
 
 
 
    </div>
         
    </body>
</html>";
 
?>
      
      





Pour certaines caméras, j'ai spécifié le mode d'enregistrement. Dans ce cas, en plus de convertir le flux, il enregistre également de RTSP sur le disque dur local. Si Default est spécifié dans les paramètres d'enregistrement, l'enregistrement sera stocké dans le dossier ./Shinobi/videos/ [MinitorID] / [[CameraID] . Pour moi, certains dossiers du moniteur principal sont accessibles sur le réseau et montés au moyen de GPO pour un groupe spécifique en tant que lecteurs réseau.



image



Pourquoi est-ce fait? Une caractéristique simple de la logistique: il arrive qu'une grosse voiture soit chargée de marchandises et part pour une autre ville, où elle est déchargée par l'acheteur, qui peut dire qu'il manque quelque chose. Et il arrive que dans leurs magasins, ils ne puissent plus compter quelque chose. Par conséquent, un enregistrement séparé est effectué pour l'entrepôt à partir de certaines caméras déjà au format mp4. Cela peut économiser des tonnes de temps de débriefing.



All Articles