2023-07-03 22:31:18 +00:00
|
|
|
|
<!DOCTYPE html>
|
|
|
|
|
<html lang="en">
|
|
|
|
|
<head>
|
|
|
|
|
<meta charset="UTF-8">
|
|
|
|
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
|
|
|
<title>Трансляция</title>
|
|
|
|
|
<link rel="stylesheet" href="../styles/main.css" />
|
2023-08-22 15:29:23 +00:00
|
|
|
|
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css" />
|
|
|
|
|
<script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"></script>
|
2023-07-03 22:31:18 +00:00
|
|
|
|
</head>
|
|
|
|
|
<body>
|
|
|
|
|
|
2023-08-01 11:52:35 +00:00
|
|
|
|
|
|
|
|
|
|
2023-07-03 22:31:18 +00:00
|
|
|
|
<header>
|
2023-09-18 01:58:49 +00:00
|
|
|
|
<img src="../img/argus.png">
|
2023-07-03 22:31:18 +00:00
|
|
|
|
<h1>Аргус</h1>
|
2023-08-07 11:44:15 +00:00
|
|
|
|
<h2><span>/</span> {{Organisation}}</h2>
|
2023-07-03 22:31:18 +00:00
|
|
|
|
</header>
|
|
|
|
|
|
|
|
|
|
<section class="account-info">
|
|
|
|
|
<div id="account-main">
|
|
|
|
|
<img id="person" src="../img/person.svg">
|
2023-08-07 11:44:15 +00:00
|
|
|
|
<span>{{User}}</span>
|
2023-07-03 22:31:18 +00:00
|
|
|
|
<img id="down" src="../img/down.svg">
|
|
|
|
|
<img id="up" src="../img/up.svg">
|
|
|
|
|
</div>
|
2023-09-11 09:57:10 +00:00
|
|
|
|
<a href="/logout"><div id="account-additional" class="additional">Выйти</div></a>
|
2023-07-03 22:31:18 +00:00
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<section class="navigation">
|
|
|
|
|
<a href="/">
|
|
|
|
|
<div><img src="../img/chart.svg">Главная</div>
|
|
|
|
|
</a>
|
|
|
|
|
<a href="/devices">
|
|
|
|
|
<div><img src="../img/cloud.svg">Устройства</div>
|
|
|
|
|
</a>
|
|
|
|
|
<a href="/reports">
|
|
|
|
|
<div><img src="../img/bubble.svg">Отчёты</div>
|
|
|
|
|
</a>
|
|
|
|
|
<a href="/live">
|
|
|
|
|
<div class="selected"><img src="../img/waves.svg">Трансляция</div>
|
|
|
|
|
</a>
|
2023-08-21 03:28:58 +00:00
|
|
|
|
<a href="/videos">
|
2023-07-03 22:31:18 +00:00
|
|
|
|
<div><img src="../img/play.svg">Записи</div>
|
|
|
|
|
</a>
|
2023-09-11 09:57:10 +00:00
|
|
|
|
{{#if isAdmin}}
|
2023-09-11 05:59:00 +00:00
|
|
|
|
<a class="admin-panel" href="/admin">
|
2023-09-11 09:57:10 +00:00
|
|
|
|
<div><img src="../img/keyboard.svg">Админка</div>
|
|
|
|
|
</a>
|
|
|
|
|
{{/if}}
|
2023-08-28 04:40:58 +00:00
|
|
|
|
<a class="settings" href="/settings">
|
2023-07-03 22:31:18 +00:00
|
|
|
|
<div><img src="../img/gear.svg">Настройки</div>
|
|
|
|
|
</a>
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
<section class="main">
|
2023-07-18 01:32:15 +00:00
|
|
|
|
{{#if ifDBError}}
|
|
|
|
|
<section class="dberror">
|
|
|
|
|
<div class="erorr-container">
|
|
|
|
|
<img src="../img/warning.svg"> <br>
|
|
|
|
|
<h1>Ошибка </h1> <br>
|
|
|
|
|
<span>Не удалось получить данные из БД</span>
|
|
|
|
|
<button type="button" onclick="location.reload();">Повторить попытку</button>
|
|
|
|
|
</div>
|
|
|
|
|
</section>
|
|
|
|
|
{{/if}}
|
2023-07-03 22:31:18 +00:00
|
|
|
|
<div class="name">
|
|
|
|
|
<span>Прямые трансляции</span>
|
|
|
|
|
</div>
|
|
|
|
|
<nav>
|
2023-09-18 01:58:49 +00:00
|
|
|
|
<a class="selected" href="/live">Отслеживание</a>
|
2023-07-03 22:31:18 +00:00
|
|
|
|
</nav>
|
|
|
|
|
<section class="bg">
|
|
|
|
|
<section class="content">
|
|
|
|
|
<section class="for-table">
|
|
|
|
|
|
|
|
|
|
<section class="organisation">
|
|
|
|
|
<h1>Организация</h1>
|
|
|
|
|
|
|
|
|
|
<ul class="area">
|
2023-09-04 09:11:22 +00:00
|
|
|
|
{{#each Groups}}
|
|
|
|
|
<li class="area-name"><img src="../img/ul.svg"><input type="checkbox" id="{{name}}" class="checkbox-input" hidden checked><label for="{{name}}" class="checkbox-label">{{name}}</label>
|
2023-07-03 22:31:18 +00:00
|
|
|
|
<ul class="area-devices" id="devices-1">
|
2023-09-04 09:11:22 +00:00
|
|
|
|
{{#each devices}}
|
|
|
|
|
<li class="device">
|
|
|
|
|
<img>
|
|
|
|
|
<input type="checkbox" name="devices" id="{{this.id}}" class="checkbox-input device-filter" value="{{this.id}}" hidden checked>
|
|
|
|
|
<label for="{{this.id}}" class="checkbox-label active-{{this.status}}">
|
|
|
|
|
<div class="checkmark"></div>
|
|
|
|
|
</label>
|
|
|
|
|
<input type="number" id="channels-{{this.serial}}" value="{{this.channels}}" hidden>
|
|
|
|
|
<input type="radio" name="camera-serial" id="radio-{{this.serial}}" class="radio-input" value="{{this.serial}}" hidden>
|
|
|
|
|
<label for="radio-{{this.serial}}" class="radio-label active-{{this.status}}">
|
|
|
|
|
{{this.serial}}
|
|
|
|
|
</label>
|
|
|
|
|
</li>
|
|
|
|
|
{{/each}}
|
2023-07-03 22:31:18 +00:00
|
|
|
|
</ul>
|
|
|
|
|
</li>
|
2023-09-04 09:11:22 +00:00
|
|
|
|
{{/each}}
|
|
|
|
|
</ul>
|
|
|
|
|
|
|
|
|
|
|
2023-07-03 22:31:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</section>
|
|
|
|
|
|
2023-08-21 03:28:58 +00:00
|
|
|
|
<div id="video-popup" class="video-popup">
|
|
|
|
|
<div id="video-popup-content" class="video-popup-content">
|
|
|
|
|
<span class="close-popup" id="close-popup">×</span>
|
|
|
|
|
<div id="popup-video-container" class="popup-video-container">
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2023-07-03 22:31:18 +00:00
|
|
|
|
|
|
|
|
|
|
2023-08-01 11:52:35 +00:00
|
|
|
|
<section class="table" style="position: relative;">
|
2023-07-03 22:31:18 +00:00
|
|
|
|
<div id="signals-list" class="signals-list">
|
2023-08-13 17:52:23 +00:00
|
|
|
|
<h1>Сигналы ТС</h1>
|
2023-09-18 01:58:49 +00:00
|
|
|
|
<!-- <input class="search" type="text" placeholder="Поиск"> -->
|
2023-07-03 22:31:18 +00:00
|
|
|
|
|
2023-07-18 01:32:15 +00:00
|
|
|
|
<ul id="list">
|
2023-08-07 01:15:36 +00:00
|
|
|
|
{{#each Alarms}}
|
2023-07-03 22:31:18 +00:00
|
|
|
|
<li>
|
2023-08-21 03:28:58 +00:00
|
|
|
|
<!-- <input type="radio" name="signal" id="signal-{{this.id}}" hidden> -->
|
|
|
|
|
<a style="color:rgba(0, 0, 0, 0.7);" href="/reports/{{this.id}}" target="_blank">
|
2023-08-07 01:15:36 +00:00
|
|
|
|
<label for="signal-{{this.id}}">
|
2023-09-18 01:58:49 +00:00
|
|
|
|
<!-- <h2>{{this.type}}</h2> -->
|
|
|
|
|
<!-- <span>ID {{this.id}}</span> -->
|
|
|
|
|
<!-- <p><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="none" viewBox="0 0 14 14">
|
2023-08-07 01:15:36 +00:00
|
|
|
|
<path fill="#000" fill-opacity=".75" d="M3.41 7.737h3.583c.268 0 .48-.205.48-.48V2.634a.472.472 0 0 0-.48-.473.466.466 0 0 0-.473.473v4.15H3.41a.467.467 0 0 0-.48.473c0 .275.206.48.48.48ZM7 13.993c3.83 0 7-3.176 7-6.996C14 3.169 10.822 0 6.993 0 3.171 0 0 3.169 0 6.997c0 3.82 3.177 6.996 7 6.996Zm0-1.166a5.804 5.804 0 0 1-5.826-5.83c0-3.238 2.58-5.83 5.82-5.83a5.815 5.815 0 0 1 5.84 5.83A5.81 5.81 0 0 1 7 12.827Z"/>
|
|
|
|
|
</svg>{{this.time}}</p>
|
|
|
|
|
<p><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="none" viewBox="0 0 5 14">
|
|
|
|
|
<path fill="#000" fill-opacity=".75" d="M0 2.402c0 1.122.792 2.059 1.877 2.32v5.913c0 1.88.353 2.906.62 2.906.273 0 .619-1.02.619-2.906V4.722C4.2 4.467 5 3.524 5 2.402 5 1.083 3.888 0 2.497 0 1.112 0 0 1.083 0 2.402Zm1.784.134c-.46 0-.859-.382-.859-.828 0-.44.4-.816.86-.816.465 0 .851.376.851.816 0 .446-.386.828-.852.828Z"/>
|
2023-09-18 01:58:49 +00:00
|
|
|
|
</svg>{{this.latitude}},{{this.longitude}}</p> -->
|
2023-08-07 01:15:36 +00:00
|
|
|
|
<p class="name"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="none" viewBox="0 0 24 19">
|
|
|
|
|
<path fill="#000" fill-opacity=".75" d="M4.58 6.143c-.078.341.068.478.44.459 1.562-.108 3.418-.196 6.533-.196 3.125 0 4.98.088 6.543.196.361.02.508-.118.43-.46-.235-1.035-.684-2.382-.997-2.92-.254-.439-.537-.634-1.045-.702-.703-.098-2.304-.166-4.931-.166-2.617 0-4.219.068-4.932.166-.508.068-.79.263-1.045.703-.312.537-.752 1.884-.996 2.92Zm-.068 6.65c.888 0 1.572-.684 1.572-1.572 0-.899-.684-1.573-1.572-1.573-.889 0-1.573.674-1.573 1.573 0 .888.684 1.572 1.573 1.572Zm4.463-.39h5.166c.664 0 1.123-.46 1.123-1.133 0-.665-.46-1.123-1.123-1.123H8.975c-.674 0-1.133.458-1.133 1.123 0 .673.459 1.132 1.133 1.132Zm9.619.39c.898 0 1.572-.684 1.572-1.572 0-.899-.674-1.573-1.572-1.573-.889 0-1.563.674-1.563 1.573 0 .888.674 1.572 1.563 1.572Zm-7.041 2.637c3.281 0 7.646-.166 9.492-.381 1.328-.147 2.06-.88 2.06-2.13v-1.718c0-1.65-.332-2.568-1.23-3.74l-.83-1.065c-.352-1.757-1.006-3.603-1.338-4.326C19.18.967 18.174.313 16.875.137 16.221.049 14.082 0 11.553 0 9.033 0 6.895.059 6.24.137 4.941.293 3.926.967 3.408 2.07c-.342.723-.986 2.569-1.347 4.326l-.82 1.065C.331 8.633 0 9.55 0 11.2v1.719c0 1.25.742 1.982 2.06 2.129 1.856.215 6.211.38 9.493.38Zm0-1.28c-3.32 0-7.578-.156-9.15-.351-.83-.098-1.124-.527-1.124-1.27v-1.328c0-1.338.215-1.963.977-2.959l.996-1.308c.264-1.416.898-3.39 1.318-4.288.313-.673.928-1.093 1.817-1.2.625-.079 2.607-.167 5.166-.167 2.568 0 4.58.088 5.146.166.918.117 1.524.537 1.846 1.201.42.899 1.055 2.872 1.308 4.288l1.006 1.308c.752.996.967 1.621.967 2.96v1.327c0 .742-.293 1.172-1.123 1.27-1.562.195-5.83.351-9.15.351Zm-9.756 3.965h1.142c.733 0 1.3-.566 1.3-1.289v-2.324l-3.741-.537v2.861c0 .723.566 1.29 1.299 1.29Zm18.369 0h1.152a1.27 1.27 0 0 0 1.29-1.289v-2.861l-3.731.537v2.324a1.27 1.27 0 0 0 1.289 1.29Z"/>
|
|
|
|
|
</svg>{{this.serial}}</p>
|
2023-09-18 01:58:49 +00:00
|
|
|
|
<p class="name"><svg xmlns="http://www.w3.org/2000/svg" width="13" height="14" fill="none" viewBox="0 0 13 14">
|
|
|
|
|
<path fill="rgba(255, 106, 75, 0.8)" fill-opacity=".85" d="M0 10.722c0 .494.386.82 1.04.82h2.908c.055 1.307 1.095 2.451 2.549 2.451 1.46 0 2.5-1.138 2.555-2.452h2.908c.647 0 1.04-.325 1.04-.82 0-.677-.703-1.286-1.295-1.889-.455-.467-.579-1.429-.634-2.208-.048-2.668-.75-4.389-2.583-5.04C8.253.699 7.516 0 6.497 0 5.484 0 4.74.698 4.512 1.585c-1.832.65-2.535 2.37-2.583 5.04-.055.778-.18 1.74-.634 2.207C.695 9.435 0 10.044 0 10.722Zm1.337-.203v-.082c.124-.196.537-.596.895-.989.496-.541.73-1.415.792-2.736.055-2.96.951-3.901 2.13-4.22.171-.04.268-.121.275-.298.02-.704.434-1.198 1.068-1.198.64 0 1.047.494 1.074 1.198.007.177.097.258.269.299 1.185.318 2.08 1.26 2.136 4.22.062 1.32.296 2.194.785 2.735.365.393.772.793.896.99v.08H1.337Zm3.685 1.022h2.956c-.055.922-.648 1.497-1.481 1.497-.827 0-1.427-.575-1.475-1.497Z"/>
|
|
|
|
|
</svg>{{this.type}}</p>
|
2023-08-07 01:15:36 +00:00
|
|
|
|
|
|
|
|
|
<!-- <p class="name"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="none" viewBox="0 0 13 14">
|
|
|
|
|
<path fill="#000" fill-opacity=".75" d="M1.82 14h9.335c1.233 0 1.82-.371 1.82-1.188 0-1.946-2.458-4.761-6.484-4.761C2.458 8.05 0 10.866 0 12.81 0 13.63.587 14 1.82 14Zm-.35-1.121c-.193 0-.274-.053-.274-.208 0-1.218 1.886-3.499 5.295-3.499 3.402 0 5.288 2.28 5.288 3.499 0 .155-.074.208-.267.208H1.47ZM6.492 7.13C8.26 7.13 9.7 5.555 9.7 3.64 9.7 1.737 8.266.244 6.49.244c-1.76 0-3.208 1.523-3.208 3.41C3.29 5.562 4.723 7.13 6.49 7.13Zm0-1.121c-1.084 0-2.012-1.04-2.012-2.355 0-1.292.913-2.287 2.012-2.287 1.107 0 2.013.98 2.013 2.272 0 1.315-.921 2.37-2.013 2.37Z"/>
|
|
|
|
|
</svg></p>
|
|
|
|
|
<p class="phone"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="none" viewBox="0 0 14 14">
|
|
|
|
|
<path fill="#000" fill-opacity=".75" d="M10.38 14c1.25 0 2.07-.336 2.792-1.15.057-.056.114-.12.164-.178.428-.478.628-.95.628-1.4 0-.513-.3-.992-.935-1.434l-2.077-1.442c-.643-.443-1.393-.493-1.992.1l-.55.55c-.164.164-.307.17-.464.07-.386-.242-1.164-.92-1.692-1.448-.557-.55-1.092-1.164-1.378-1.614-.093-.164-.086-.3.079-.464l.542-.55c.6-.6.55-1.356.107-1.992L4.162.971C3.72.336 3.242.043 2.727.036c-.45-.007-.92.2-1.4.628-.063.057-.12.107-.178.157C.336 1.549 0 2.371 0 3.605c0 2.042 1.256 4.527 3.562 6.832C5.854 12.73 8.346 14 10.38 14Zm.008-1.1c-1.82.036-4.155-1.363-6.005-3.205-1.863-1.856-3.326-4.27-3.29-6.09.014-.785.292-1.463.849-1.949.05-.043.086-.078.136-.114.214-.186.442-.285.65-.285.206 0 .392.078.527.292L4.64 3.627c.15.221.165.47-.057.692l-.628.628c-.492.493-.457 1.093-.1 1.571.407.55 1.114 1.35 1.664 1.892.542.55 1.406 1.32 1.963 1.735.478.357 1.078.393 1.57-.1l.629-.628c.221-.222.464-.207.692-.065l2.078 1.385a.6.6 0 0 1 .292.536c0 .207-.1.435-.285.65l-.114.135c-.486.557-1.164.828-1.956.843Z"/>
|
|
|
|
|
</svg></p> -->
|
|
|
|
|
</label>
|
2023-08-21 03:28:58 +00:00
|
|
|
|
</a>
|
2023-08-07 01:15:36 +00:00
|
|
|
|
</li>
|
|
|
|
|
{{/each}}
|
2023-08-08 17:46:12 +00:00
|
|
|
|
|
2023-07-03 22:31:18 +00:00
|
|
|
|
</ul>
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
2023-08-21 03:28:58 +00:00
|
|
|
|
<div class="stream-map">
|
2023-08-14 04:11:03 +00:00
|
|
|
|
<div id="properties" class="properties" style="display: none;">
|
|
|
|
|
<div class="propert"><h1>Группа</h1><br><h2 id="propert-group">Автобусы</h2></div>
|
|
|
|
|
<div class="propert"><h1>Скорость</h1><br><h2 id="propert-speed"> км/ч</h2></div>
|
|
|
|
|
<div class="propert"><h1>Номерной знак</h1><br><h2 id="propert-plate"></h2></div>
|
|
|
|
|
<div class="propert"><h1>Геопозиция</h1><br><h2 id="propert-geo"></h2></div>
|
|
|
|
|
</div>
|
2023-07-03 22:31:18 +00:00
|
|
|
|
<div id="map"></div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2023-08-21 03:28:58 +00:00
|
|
|
|
<div class="stream-cameras">
|
|
|
|
|
<div class="stream-video-container">
|
2023-08-28 04:40:58 +00:00
|
|
|
|
<video id="camera-1"></video>
|
2023-08-01 11:52:35 +00:00
|
|
|
|
<video id="camera-2"></video>
|
|
|
|
|
<video id="camera-3"></video>
|
|
|
|
|
<video id="camera-4"></video>
|
|
|
|
|
</div>
|
2023-08-28 04:40:58 +00:00
|
|
|
|
<button onclick="switchCameras(-1)">Назад</button>
|
|
|
|
|
<button onclick="switchCameras(1)">Вперед</button>
|
2023-08-01 11:52:35 +00:00
|
|
|
|
</div>
|
|
|
|
|
|
2023-07-03 22:31:18 +00:00
|
|
|
|
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
</section>
|
|
|
|
|
</section>
|
|
|
|
|
</section>
|
|
|
|
|
|
2023-08-01 11:52:35 +00:00
|
|
|
|
<script src="../scripts/jquery.min.js"></script>
|
|
|
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/flv.js/1.5.0/flv.min.js"></script>
|
2023-09-04 09:11:22 +00:00
|
|
|
|
<script>
|
|
|
|
|
document.addEventListener('DOMContentLoaded', function () {
|
|
|
|
|
const areaNames = document.querySelectorAll('.area-name');
|
|
|
|
|
|
|
|
|
|
areaNames.forEach(function (areaName) {
|
|
|
|
|
const areaCheckbox = areaName.querySelector('.checkbox-input');
|
|
|
|
|
const deviceCheckboxes = areaName.querySelectorAll('.device .checkbox-input');
|
|
|
|
|
const deviceList = areaName.querySelector('.area-devices');
|
|
|
|
|
|
|
|
|
|
// Функция для скрытия/показа дочерних элементов
|
|
|
|
|
function toggleChildDevices(show) {
|
|
|
|
|
if (show) {
|
|
|
|
|
deviceList.style.display = 'block';
|
|
|
|
|
} else {
|
|
|
|
|
deviceList.style.display = 'none';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Инициализация состояния чекбоксов и скрытия/показа дочерних элементов
|
|
|
|
|
toggleChildDevices(areaCheckbox.checked);
|
|
|
|
|
deviceCheckboxes.forEach(function (deviceCheckbox) {
|
|
|
|
|
deviceCheckbox.checked = areaCheckbox.checked;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
areaCheckbox.addEventListener('change', function () {
|
|
|
|
|
const isChecked = areaCheckbox.checked;
|
|
|
|
|
deviceCheckboxes.forEach(function (deviceCheckbox) {
|
|
|
|
|
deviceCheckbox.checked = isChecked;
|
|
|
|
|
});
|
|
|
|
|
toggleChildDevices(isChecked);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
deviceCheckboxes.forEach(function (deviceCheckbox) {
|
|
|
|
|
deviceCheckbox.addEventListener('change', function () {
|
|
|
|
|
const allUnchecked = Array.from(deviceCheckboxes).every(function (checkbox) {
|
|
|
|
|
return !checkbox.checked;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (allUnchecked) {
|
|
|
|
|
areaCheckbox.checked = false;
|
|
|
|
|
toggleChildDevices(false);
|
|
|
|
|
} else {
|
|
|
|
|
areaCheckbox.checked = true;
|
|
|
|
|
toggleChildDevices(true);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
</script>
|
2023-08-28 04:40:58 +00:00
|
|
|
|
<script>
|
|
|
|
|
var cameraSerials = document.querySelectorAll('.radio-input');
|
|
|
|
|
|
|
|
|
|
cameraSerials.forEach((checkbox) => {
|
|
|
|
|
checkbox.addEventListener('change', function() {
|
|
|
|
|
console.log($("input[name=camera-serial]:checked").val())
|
|
|
|
|
serial = $("input[name=camera-serial]:checked").val()
|
|
|
|
|
stopAllCameras();
|
|
|
|
|
currentCameraGroup = 1
|
|
|
|
|
totalCameras = $(`#channels-${serial}`).val() - 1;
|
|
|
|
|
console.log(totalCameras);
|
|
|
|
|
playNextCamerasInGroup();
|
|
|
|
|
|
2023-09-18 01:58:49 +00:00
|
|
|
|
const markers = document.querySelectorAll('.area-devices .device');
|
|
|
|
|
markers.forEach(marker => {
|
|
|
|
|
const serial = marker.querySelector('.radio-input').value;
|
|
|
|
|
|
|
|
|
|
// Получаем элемент с соответствующим id
|
|
|
|
|
const svgId = `marker-${serial}`;
|
|
|
|
|
const svgElement = document.getElementById(svgId);
|
|
|
|
|
|
|
|
|
|
if (svgElement) {
|
|
|
|
|
// Проверяем serial и устанавливаем цвет
|
|
|
|
|
if (serial === $("input[name=camera-serial]:checked").val()) {
|
|
|
|
|
svgElement.innerHTML = `
|
|
|
|
|
<path fill="#FF6A4B" d="M12.669 24.673c6.565 0 12-5.435 12-12 0-6.553-5.447-12-12.012-12C6.104.673.67 6.12.67 12.673c0 6.565 5.447 12 12 12Z"/>
|
|
|
|
|
<path fill="#fff" fill-opacity=".85" d="m7.104 17.92 4.683-11.93c.33-.823 1.423-.846 1.753-.023l4.682 11.953c.318.788-.553 1.47-1.294.73l-3.953-3.953c-.188-.2-.424-.2-.612 0L8.41 18.65c-.753.74-1.623.059-1.306-.730Z"/>
|
|
|
|
|
`;
|
|
|
|
|
} else {
|
|
|
|
|
svgElement.innerHTML = `
|
|
|
|
|
<path d="M12.9815 25.0195C19.5462 25.0336 24.9931 19.6101 25.0073 13.0454C25.0214 6.49253 19.5861 1.03375 13.0214 1.01961C6.46848 1.00549 1.02147 6.44081 1.00735 12.9937C0.993201 19.5584 6.42852 25.0054 12.9815 25.0195Z" fill="#8086F9"/>
|
|
|
|
|
<path d="M7.43175 18.2547L12.1398 6.33536C12.471 5.51254 13.5652 5.49137 13.8928 6.31561L18.5493 18.2786C18.8653 19.0675 17.9932 19.748 17.2537 19.0052L13.3092 15.0438C13.1215 14.8434 12.8862 14.8429 12.6975 15.0425L8.73605 18.9868C7.98152 19.7264 7.1124 19.0422 7.43175 18.2547Z" fill="white" fill-opacity="0.85"/>
|
|
|
|
|
`;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
2023-09-18 10:00:43 +00:00
|
|
|
|
|
2023-08-28 04:40:58 +00:00
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
</script>
|
|
|
|
|
<script>
|
|
|
|
|
let flvPlayers = [];
|
|
|
|
|
let currentCameraGroup = 1;
|
|
|
|
|
const camerasPerGroup = 4;
|
|
|
|
|
var totalCameras = 12 - 1;
|
|
|
|
|
const baseURL = "http://45.9.42.252:8080/http/live.flv";
|
|
|
|
|
|
|
|
|
|
function stopAllCameras() {
|
|
|
|
|
flvPlayers.forEach(player => {
|
|
|
|
|
player.pause();
|
|
|
|
|
player.unload();
|
|
|
|
|
player.detachMediaElement();
|
|
|
|
|
player.destroy();
|
|
|
|
|
});
|
|
|
|
|
flvPlayers = [];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function playNextCamerasInGroup() {
|
|
|
|
|
const startCamera = (currentCameraGroup - 1) * camerasPerGroup + 2;
|
|
|
|
|
const endCamera = startCamera + camerasPerGroup - 1;
|
|
|
|
|
|
|
|
|
|
if (startCamera > totalCameras) {
|
|
|
|
|
// currentCameraGroup = 1;
|
|
|
|
|
// playNextCamerasInGroup();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
stopAllCameras();
|
|
|
|
|
|
|
|
|
|
let videoElementIndex = 1;
|
|
|
|
|
|
|
|
|
|
for (let i = startCamera; i <= endCamera && i <= totalCameras; i++) {
|
|
|
|
|
const videoElement = document.getElementById(`camera-${videoElementIndex}`);
|
|
|
|
|
const flvPlayer = flvjs.createPlayer({
|
|
|
|
|
type: 'flv',
|
|
|
|
|
isLive: true,
|
|
|
|
|
cors: true,
|
2023-09-10 16:36:39 +00:00
|
|
|
|
url: `${baseURL}?serial=${serial}&channel=${i}&quality=1`,
|
2023-08-28 04:40:58 +00:00
|
|
|
|
}, {
|
|
|
|
|
enableWorker: true,
|
|
|
|
|
enableStashBuffer: false,
|
|
|
|
|
autoCleanupSourceBuffer: true,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
flvPlayer.attachMediaElement(videoElement);
|
|
|
|
|
flvPlayer.load();
|
|
|
|
|
flvPlayer.play();
|
|
|
|
|
|
|
|
|
|
flvPlayers.push(flvPlayer);
|
|
|
|
|
|
|
|
|
|
videoElementIndex++;
|
|
|
|
|
|
2023-09-18 10:00:43 +00:00
|
|
|
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
2023-08-28 04:40:58 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function switchCameras(direction) {
|
|
|
|
|
if ((currentCameraGroup === 1 && direction === -1) || (currentCameraGroup === Math.ceil(totalCameras / camerasPerGroup) && direction === 1)) {
|
|
|
|
|
// Если текущая группа - первая и переключаемся назад, или текущая группа - последняя и переключаемся вперед, не переключаемся
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
currentCameraGroup += direction;
|
|
|
|
|
if (currentCameraGroup < 1) {
|
|
|
|
|
currentCameraGroup = Math.ceil(totalCameras / camerasPerGroup);
|
|
|
|
|
} else if (currentCameraGroup > Math.ceil(totalCameras / camerasPerGroup)) {
|
|
|
|
|
currentCameraGroup = 1;
|
|
|
|
|
}
|
|
|
|
|
playNextCamerasInGroup();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Запустить воспроизведение видео при загрузке страницы
|
|
|
|
|
playNextCamerasInGroup();
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2023-08-01 11:52:35 +00:00
|
|
|
|
|
|
|
|
|
|
2023-07-18 01:32:15 +00:00
|
|
|
|
<script>
|
|
|
|
|
window.addEventListener('DOMContentLoaded', function() {
|
|
|
|
|
var signalsList = document.querySelector('.signals-list');
|
|
|
|
|
var list = document.getElementById('list');
|
|
|
|
|
|
2023-07-24 04:53:11 +00:00
|
|
|
|
list.style.height = (signalsList.clientHeight - 50 - 75) + 'px';
|
|
|
|
|
});
|
|
|
|
|
window.addEventListener('resize', function() {
|
|
|
|
|
var signalsList = document.querySelector('.signals-list');
|
|
|
|
|
var list = document.getElementById('list');
|
|
|
|
|
|
2023-07-18 01:32:15 +00:00
|
|
|
|
list.style.height = (signalsList.clientHeight - 50 - 75) + 'px';
|
|
|
|
|
});
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
|
|
|
|
|
var checkboxes = document.querySelectorAll('.checkbox-input');
|
|
|
|
|
const form = document.getElementById('devices-1');
|
|
|
|
|
|
|
|
|
|
form.addEventListener('change', () => {
|
2023-08-08 17:46:12 +00:00
|
|
|
|
fetchAndShowMarkers();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<script>
|
2023-08-13 17:52:23 +00:00
|
|
|
|
|
2023-08-28 04:40:58 +00:00
|
|
|
|
var map = L.map('map').setView([59.855198, 30.282995], 12);
|
2023-08-21 03:28:58 +00:00
|
|
|
|
|
2023-08-22 15:29:23 +00:00
|
|
|
|
L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}').addTo(map);
|
2023-08-13 17:52:23 +00:00
|
|
|
|
|
2023-08-22 15:29:23 +00:00
|
|
|
|
map.zoomControl.remove();
|
2023-08-13 17:52:23 +00:00
|
|
|
|
|
2023-08-22 15:29:23 +00:00
|
|
|
|
map.attributionControl.remove();
|
2023-08-08 17:46:12 +00:00
|
|
|
|
|
2023-08-22 15:29:23 +00:00
|
|
|
|
let markers = [];
|
2023-08-08 17:46:12 +00:00
|
|
|
|
{{#if ifDBError}}
|
|
|
|
|
{{else}}
|
|
|
|
|
|
2023-08-21 03:28:58 +00:00
|
|
|
|
const selectedDevices = Array.from(checkboxes)
|
|
|
|
|
.filter(checkbox => checkbox.checked && checkbox.value !== 'on')
|
|
|
|
|
.map(checkbox => checkbox.value);
|
|
|
|
|
|
|
|
|
|
checkboxes.forEach(checkbox => {
|
2023-09-04 09:11:22 +00:00
|
|
|
|
checkbox.addEventListener('change', async function() {
|
|
|
|
|
await new Promise(resolve => setTimeout(resolve, 100));
|
2023-08-21 03:28:58 +00:00
|
|
|
|
selectedDevices.length = 0; // Очищаем массив
|
|
|
|
|
selectedDevices.push(...Array.from(checkboxes)
|
|
|
|
|
.filter(checkbox => checkbox.checked && checkbox.value !== 'on')
|
|
|
|
|
.map(checkbox => checkbox.value));
|
|
|
|
|
|
|
|
|
|
console.log(selectedDevices); // Вывести выбранные устройства в консоль
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2023-07-18 01:32:15 +00:00
|
|
|
|
|
2023-08-08 17:46:12 +00:00
|
|
|
|
function addMarker(device) {
|
|
|
|
|
const { serial, status, longitude, latitude, direction, speed } = device;
|
2023-07-18 01:32:15 +00:00
|
|
|
|
|
2023-08-22 15:29:23 +00:00
|
|
|
|
|
2023-08-08 17:46:12 +00:00
|
|
|
|
if (serial === $("input[name=camera-serial]:checked").val()) {
|
2023-08-22 15:29:23 +00:00
|
|
|
|
var marker = L.divIcon({
|
|
|
|
|
className: 'marker',
|
|
|
|
|
html: `<div class="marker-name active-${status}">${serial}</div>
|
2023-08-08 17:46:12 +00:00
|
|
|
|
<svg class="active-${status}" id="marker-${serial}" style="transform: rotate(${direction}deg)" xmlns="http://www.w3.org/2000/svg" width="26" height="26" viewBox="0 0 26 26" fill="none">
|
|
|
|
|
<path fill="#FF6A4B" d="M12.669 24.673c6.565 0 12-5.435 12-12 0-6.553-5.447-12-12.012-12C6.104.673.67 6.12.67 12.673c0 6.565 5.447 12 12 12Z"/>
|
|
|
|
|
<path fill="#fff" fill-opacity=".85" d="m7.104 17.92 4.683-11.93c.33-.823 1.423-.846 1.753-.023l4.682 11.953c.318.788-.553 1.47-1.294.73l-3.953-3.953c-.188-.2-.424-.2-.612 0L8.41 18.65c-.753.74-1.623.059-1.306-.73Z"/>
|
2023-08-22 15:29:23 +00:00
|
|
|
|
</svg>`
|
|
|
|
|
});
|
2023-08-08 17:46:12 +00:00
|
|
|
|
} else {
|
2023-08-22 15:29:23 +00:00
|
|
|
|
var marker = L.divIcon({
|
|
|
|
|
className: 'marker',
|
|
|
|
|
html: `<div class="marker-name active-${status}">${serial}</div>
|
2023-08-08 17:46:12 +00:00
|
|
|
|
<svg class="active-${status}" id="marker-${serial}" style="transform: rotate(${direction}deg)" xmlns="http://www.w3.org/2000/svg" width="26" height="26" viewBox="0 0 26 26" fill="none">
|
|
|
|
|
<path d="M12.9815 25.0195C19.5462 25.0336 24.9931 19.6101 25.0073 13.0454C25.0214 6.49253 19.5861 1.03375 13.0214 1.01961C6.46848 1.00549 1.02147 6.44081 1.00735 12.9937C0.993201 19.5584 6.42852 25.0054 12.9815 25.0195Z" fill="#8086F9"/>
|
|
|
|
|
<path d="M7.43175 18.2547L12.1398 6.33536C12.471 5.51254 13.5652 5.49137 13.8928 6.31561L18.5493 18.2786C18.8653 19.0675 17.9932 19.748 17.2537 19.0052L13.3092 15.0438C13.1215 14.8434 12.8862 14.8429 12.6975 15.0425L8.73605 18.9868C7.98152 19.7264 7.1124 19.0422 7.43175 18.2547Z" fill="white" fill-opacity="0.85"/>
|
2023-08-22 15:29:23 +00:00
|
|
|
|
</svg>`
|
|
|
|
|
});
|
2023-08-08 17:46:12 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-08-22 15:29:23 +00:00
|
|
|
|
var markerObj = L.marker([latitude, longitude], { icon: marker });
|
|
|
|
|
markerObj.addTo(map);
|
|
|
|
|
markers.push(markerObj);
|
2023-08-08 17:46:12 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function clearMarkers() {
|
2023-08-22 15:29:23 +00:00
|
|
|
|
markers.forEach(marker => map.removeLayer(marker));
|
|
|
|
|
markers = [];
|
|
|
|
|
}
|
2023-08-08 17:46:12 +00:00
|
|
|
|
|
|
|
|
|
function fetchAndShowMarkers() {
|
2023-08-21 03:28:58 +00:00
|
|
|
|
console.log(selectedDevices);
|
2023-08-08 17:46:12 +00:00
|
|
|
|
fetch('/devices-geo', {
|
2023-07-18 01:32:15 +00:00
|
|
|
|
method: 'POST',
|
|
|
|
|
headers: {
|
|
|
|
|
'Content-Type': 'application/json',
|
|
|
|
|
},
|
|
|
|
|
body: JSON.stringify({ devices: selectedDevices }),
|
|
|
|
|
})
|
2023-08-08 17:46:12 +00:00
|
|
|
|
.then(response => response.json())
|
|
|
|
|
.then(data => {
|
|
|
|
|
console.log(data.devicesData);
|
|
|
|
|
clearMarkers();
|
|
|
|
|
data.devicesData.forEach(device => {
|
|
|
|
|
addMarker(device);
|
2023-08-22 15:29:23 +00:00
|
|
|
|
console.log(device);
|
2023-08-08 17:46:12 +00:00
|
|
|
|
});
|
2023-08-14 04:11:03 +00:00
|
|
|
|
|
|
|
|
|
// Поиск устройства с выбранным серийным номером
|
|
|
|
|
const selectedDevice = data.devicesData.find(device => device.serial === $("input[name=camera-serial]:checked").val());
|
|
|
|
|
|
|
|
|
|
// Получение ссылок на элементы для заполнения данных
|
|
|
|
|
const groupElement = document.getElementById('propert-group');
|
|
|
|
|
const speedElement = document.getElementById('propert-speed');
|
|
|
|
|
const plateElement = document.getElementById('propert-plate');
|
|
|
|
|
const geoElement = document.getElementById('propert-geo');
|
|
|
|
|
|
|
|
|
|
const propertiesDiv = document.getElementById('properties');
|
|
|
|
|
|
2023-08-21 03:28:58 +00:00
|
|
|
|
console.log(selectedDevice);
|
|
|
|
|
|
2023-08-14 04:11:03 +00:00
|
|
|
|
if (selectedDevice) {
|
2023-09-04 09:11:22 +00:00
|
|
|
|
groupElement.textContent = selectedDevice.group;
|
2023-08-14 04:11:03 +00:00
|
|
|
|
speedElement.textContent = selectedDevice.speed + ' км/ч';
|
|
|
|
|
plateElement.textContent = selectedDevice.plate;
|
|
|
|
|
geoElement.textContent = `${selectedDevice.latitude.toFixed(6)}, ${selectedDevice.longitude.toFixed(6)}`;
|
|
|
|
|
|
|
|
|
|
propertiesDiv.style.display = 'inline-flex';
|
|
|
|
|
} else {
|
2023-09-06 19:07:19 +00:00
|
|
|
|
propertiesDiv.style.display = 'none';
|
2023-08-14 04:11:03 +00:00
|
|
|
|
console.log('Устройство с выбранным серийным номером не найдено.');
|
|
|
|
|
}
|
2023-08-08 17:46:12 +00:00
|
|
|
|
})
|
|
|
|
|
.catch(error => {
|
|
|
|
|
console.error('Ошибка при получении данных:', error);
|
2023-08-14 04:11:03 +00:00
|
|
|
|
|
|
|
|
|
const propertiesDiv = document.getElementById('properties');
|
|
|
|
|
propertiesDiv.style.display = 'none';
|
2023-07-18 01:32:15 +00:00
|
|
|
|
});
|
2023-08-08 17:46:12 +00:00
|
|
|
|
|
|
|
|
|
}
|
2023-07-18 01:32:15 +00:00
|
|
|
|
|
2023-08-08 17:46:12 +00:00
|
|
|
|
// Инициализация карты
|
|
|
|
|
fetchAndShowMarkers();
|
|
|
|
|
// Обновление маркеров каждые 12 секунд (12000 миллисекунд)
|
|
|
|
|
setInterval(fetchAndShowMarkers, 12000);
|
2023-07-18 01:32:15 +00:00
|
|
|
|
|
2023-08-08 17:46:12 +00:00
|
|
|
|
{{/if}}
|
2023-07-18 01:32:15 +00:00
|
|
|
|
|
2023-08-08 17:46:12 +00:00
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
2023-08-22 15:29:23 +00:00
|
|
|
|
|
2023-07-18 01:32:15 +00:00
|
|
|
|
|
2023-07-03 22:31:18 +00:00
|
|
|
|
<script>
|
|
|
|
|
// Скрытие/Показ дополнительных меню аккаунта
|
|
|
|
|
const accountMain = document.getElementById('account-main');
|
|
|
|
|
const accountAdditional = document.getElementById('account-additional');
|
|
|
|
|
const accountUp = document.getElementById('up');
|
|
|
|
|
const accountDown = document.getElementById('down');
|
|
|
|
|
accountAdditional.style.display = 'none';
|
|
|
|
|
accountUp.style.display = 'none';
|
|
|
|
|
|
|
|
|
|
accountMain.addEventListener('click', () => {
|
|
|
|
|
if (accountAdditional.style.display === 'none') {
|
|
|
|
|
accountAdditional.style.display = 'flex';
|
|
|
|
|
accountUp.style.display = 'unset';
|
|
|
|
|
accountDown.style.display = 'none';
|
|
|
|
|
} else {
|
|
|
|
|
accountAdditional.style.display = 'none';
|
|
|
|
|
accountUp.style.display = 'none';
|
|
|
|
|
accountDown.style.display = 'unset';
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
</script>
|
|
|
|
|
|
2023-08-21 03:28:58 +00:00
|
|
|
|
<script>
|
|
|
|
|
// Получаем ссылки на элементы
|
|
|
|
|
const videoContainers = document.querySelectorAll('.stream-video-container video');
|
|
|
|
|
const popup = document.getElementById('video-popup');
|
|
|
|
|
const popupVideo = document.getElementById('popup-video');
|
|
|
|
|
const closePopup = document.getElementById('close-popup');
|
|
|
|
|
const popupVideoContainer = document.getElementById('popup-video-container');
|
|
|
|
|
const popupContainer = document.getElementById('video-popup-content');
|
|
|
|
|
|
|
|
|
|
let originalVideo = null; // Сохраняем оригинальное видео элемент
|
|
|
|
|
|
|
|
|
|
// Функция для открытия попапа с видео
|
|
|
|
|
function openVideoPopup(video) {
|
|
|
|
|
// Сохраняем оригинальное видео
|
|
|
|
|
originalVideo = video;
|
|
|
|
|
|
|
|
|
|
// Меняем стили видео
|
|
|
|
|
video.style.position = 'fixed';
|
|
|
|
|
video.style.top = '10%';
|
|
|
|
|
video.style.left = '0';
|
|
|
|
|
video.style.width = '100%';
|
|
|
|
|
video.style.height = '80%';
|
|
|
|
|
video.style.zIndex = '1000';
|
|
|
|
|
|
|
|
|
|
popup.style.display = 'block';
|
|
|
|
|
popupContainer.style.width = '100%';
|
|
|
|
|
popupContainer.style.height = '80%';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Функция для закрытия попапа с видео
|
|
|
|
|
function closeVideoPopup() {
|
|
|
|
|
// Восстанавливаем оригинальные стили видео
|
|
|
|
|
if (originalVideo) {
|
|
|
|
|
originalVideo.style.position = '';
|
|
|
|
|
originalVideo.style.top = '';
|
|
|
|
|
originalVideo.style.left = '';
|
|
|
|
|
originalVideo.style.width = '';
|
|
|
|
|
originalVideo.style.height = '';
|
|
|
|
|
originalVideo.style.zIndex = '';
|
|
|
|
|
|
|
|
|
|
// Очищаем контейнер попапа
|
|
|
|
|
popup.style.display = 'none';
|
|
|
|
|
|
|
|
|
|
// Сбрасываем оригинальное видео
|
|
|
|
|
originalVideo = null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Добавляем обработчики событий для клика на видео и кнопку закрытия
|
|
|
|
|
videoContainers.forEach((video) => {
|
|
|
|
|
video.addEventListener('click', () => {
|
|
|
|
|
openVideoPopup(video);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
closePopup.addEventListener('click', () => {
|
|
|
|
|
closeVideoPopup();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Закрыть попап при клике вне его области
|
|
|
|
|
window.addEventListener('click', (event) => {
|
|
|
|
|
if (event.target === popup) {
|
|
|
|
|
closeVideoPopup();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Закрыть попап при нажатии на клавишу Esc
|
|
|
|
|
window.addEventListener('keydown', (event) => {
|
|
|
|
|
if (event.key === 'Escape') {
|
|
|
|
|
closeVideoPopup();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
</script>
|
|
|
|
|
|
2023-09-04 09:11:22 +00:00
|
|
|
|
|
|
|
|
|
|
2023-07-03 22:31:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</body>
|
|
|
|
|
</html>
|