update for our registrators
This commit is contained in:
parent
7f90f51499
commit
fb53bddd37
22
server.js
22
server.js
@ -829,7 +829,7 @@ async function live(req, res) {
|
||||
|
||||
// Выполняем запрос, чтобы получить все данные из таблицы registrars
|
||||
const queryRegistrars = `
|
||||
SELECT id, serial, channels, lastkeepalive, "group", name, plate, sim, ip, port, number
|
||||
SELECT id, serial, channels, lastkeepalive, "group", name, plate, sim, ip, port, number, our_registrator
|
||||
FROM registrars ${!templateData.isAdmin ? "WHERE serial = ANY($1)" : ""}
|
||||
ORDER BY id
|
||||
`;
|
||||
@ -858,6 +858,7 @@ async function live(req, res) {
|
||||
ip: registrar.ip,
|
||||
port: registrar.port,
|
||||
number: registrar.number,
|
||||
ourreg: registrar.our_registrator,
|
||||
});
|
||||
});
|
||||
|
||||
@ -2578,6 +2579,7 @@ app.get("/devices/device/:serial", async (req, res) => {
|
||||
Installer: "",
|
||||
Installation: "",
|
||||
Description: "",
|
||||
OurRegistrator: "",
|
||||
};
|
||||
|
||||
try {
|
||||
@ -2637,6 +2639,7 @@ app.get("/devices/device/:serial", async (req, res) => {
|
||||
templateData.Installer = rowData.installer;
|
||||
templateData.Installation = rowData.installation;
|
||||
templateData.Description = rowData.description;
|
||||
templateData.OurRegistrator = rowData.our_registrator;
|
||||
}
|
||||
|
||||
const source = fs.readFileSync(
|
||||
@ -3965,8 +3968,15 @@ app.post("/updatedevice", async (req, res) => {
|
||||
equipmentInstaller,
|
||||
equipmentInstalled,
|
||||
equipmentDescription,
|
||||
ourRegistrator,
|
||||
} = req.body;
|
||||
|
||||
if (ourRegistrator == "on") {
|
||||
ourRegistrator = true;
|
||||
} else {
|
||||
ourRegistrator = false;
|
||||
}
|
||||
|
||||
try {
|
||||
const query = `
|
||||
UPDATE registrars
|
||||
@ -4002,8 +4012,9 @@ app.post("/updatedevice", async (req, res) => {
|
||||
installation = $29,
|
||||
description = $30,
|
||||
number = $31,
|
||||
vin = $32
|
||||
WHERE serial = $33
|
||||
vin = $32,
|
||||
our_registrator = $33
|
||||
WHERE serial = $34
|
||||
RETURNING *;
|
||||
`;
|
||||
|
||||
@ -4040,6 +4051,7 @@ app.post("/updatedevice", async (req, res) => {
|
||||
equipmentDescription,
|
||||
deviceNumber,
|
||||
vinNumber,
|
||||
ourRegistrator,
|
||||
serialNumber,
|
||||
];
|
||||
|
||||
@ -4849,7 +4861,7 @@ async function videos(req, res) {
|
||||
|
||||
// Выполняем запрос, чтобы получить все данные из таблицы registrars
|
||||
const queryRegistrars = `
|
||||
SELECT id, serial, channels, lastkeepalive, "group", name, plate, sim, ip, port, number
|
||||
SELECT id, serial, channels, lastkeepalive, "group", name, plate, sim, ip, port, number, our_registrator
|
||||
FROM registrars ${!templateData.isAdmin ? "WHERE serial = ANY($1)" : ""}
|
||||
ORDER BY id
|
||||
`;
|
||||
@ -4878,6 +4890,7 @@ async function videos(req, res) {
|
||||
ip: registrar.ip,
|
||||
port: registrar.port,
|
||||
number: registrar.number,
|
||||
ourreg: registrar.our_registrator,
|
||||
});
|
||||
});
|
||||
|
||||
@ -4893,6 +4906,7 @@ async function videos(req, res) {
|
||||
sim: registrar.sim,
|
||||
ip: registrar.ip,
|
||||
port: registrar.port,
|
||||
ourreg: registrar.our_registrator,
|
||||
}));
|
||||
|
||||
templateData.Groups = Object.keys(groupedRegistrars).map((groupName) => ({
|
||||
|
@ -351,7 +351,7 @@ header img {
|
||||
font-weight: 400;
|
||||
opacity: 50%;
|
||||
font-size: 16px;
|
||||
margin: 10px 0 0 44px;
|
||||
margin: 10px 44px 0 44px;
|
||||
}
|
||||
|
||||
.whole-width button {
|
||||
@ -1823,7 +1823,7 @@ input[type="datetime-local"] {
|
||||
}
|
||||
|
||||
.speedometr .speed-bg {
|
||||
z-index: 10;
|
||||
z-index: 2;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -20px;
|
||||
@ -2164,6 +2164,7 @@ input[type="datetime-local"] {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
/* border-radius: 29px; */
|
||||
}
|
||||
|
||||
@ -2677,6 +2678,105 @@ input[type="time"]:focus {
|
||||
height: 30px !important;
|
||||
}
|
||||
|
||||
.heart-container {
|
||||
--heart-color: #8086f9;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
transition: 0.3s;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
font-weight: 400;
|
||||
font-size: 20px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.heart-container .checkbox {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
opacity: 0;
|
||||
z-index: 20;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.heart-container .svg-container {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.heart-container .svg-outline,
|
||||
.heart-container .svg-filled {
|
||||
fill: var(--heart-color);
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.heart-container .svg-filled {
|
||||
animation: keyframes-svg-filled 1s;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.heart-container .svg-celebrate {
|
||||
position: absolute;
|
||||
animation: keyframes-svg-celebrate 0.5s;
|
||||
animation-fill-mode: forwards;
|
||||
display: none;
|
||||
stroke: var(--heart-color);
|
||||
fill: var(--heart-color);
|
||||
stroke-width: 2px;
|
||||
}
|
||||
|
||||
.heart-container .checkbox:checked ~ .svg-container .svg-filled {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.heart-container .checkbox:checked ~ .svg-container .svg-celebrate {
|
||||
display: block;
|
||||
}
|
||||
|
||||
@keyframes keyframes-svg-filled {
|
||||
0% {
|
||||
transform: scale(0);
|
||||
}
|
||||
|
||||
25% {
|
||||
transform: scale(1.2);
|
||||
}
|
||||
|
||||
50% {
|
||||
transform: scale(1);
|
||||
filter: brightness(1.5);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes keyframes-svg-celebrate {
|
||||
0% {
|
||||
transform: scale(0);
|
||||
}
|
||||
|
||||
50% {
|
||||
opacity: 1;
|
||||
filter: brightness(1.5);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: scale(1.4);
|
||||
opacity: 0;
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
#playback-camera {
|
||||
width: 500px;
|
||||
margin-left: 44px;
|
||||
background: #f7f7fa;
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media (max-width: 1950px) {
|
||||
/* при разрешении монитора до 1950 пикселей */
|
||||
|
||||
|
@ -226,6 +226,31 @@
|
||||
</div>
|
||||
|
||||
|
||||
<div class="heart-container">
|
||||
<input name="ourRegistrator" id="parameters-our-registrator" class="checkbox" type="checkbox">
|
||||
<div class="svg-container">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="svg-outline" viewBox="0 0 24 24">
|
||||
<path d="M17.5,1.917a6.4,6.4,0,0,0-5.5,3.3,6.4,6.4,0,0,0-5.5-3.3A6.8,6.8,0,0,0,0,8.967c0,4.547,4.786,9.513,8.8,12.88a4.974,4.974,0,0,0,6.4,0C19.214,18.48,24,13.514,24,8.967A6.8,6.8,0,0,0,17.5,1.917Zm-3.585,18.4a2.973,2.973,0,0,1-3.83,0C4.947,16.006,2,11.87,2,8.967a4.8,4.8,0,0,1,4.5-5.05A4.8,4.8,0,0,1,11,8.967a1,1,0,0,0,2,0,4.8,4.8,0,0,1,4.5-5.05A4.8,4.8,0,0,1,22,8.967C22,11.87,19.053,16.006,13.915,20.313Z">
|
||||
</path>
|
||||
</svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="svg-filled" viewBox="0 0 24 24">
|
||||
<path d="M17.5,1.917a6.4,6.4,0,0,0-5.5,3.3,6.4,6.4,0,0,0-5.5-3.3A6.8,6.8,0,0,0,0,8.967c0,4.547,4.786,9.513,8.8,12.88a4.974,4.974,0,0,0,6.4,0C19.214,18.48,24,13.514,24,8.967A6.8,6.8,0,0,0,17.5,1.917Z">
|
||||
</path>
|
||||
</svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="100" width="100" class="svg-celebrate">
|
||||
<polygon points="10,10 20,20"></polygon>
|
||||
<polygon points="10,50 20,50"></polygon>
|
||||
<polygon points="20,80 30,70"></polygon>
|
||||
<polygon points="90,10 80,20"></polygon>
|
||||
<polygon points="90,50 80,50"></polygon>
|
||||
<polygon points="80,80 70,70"></polygon>
|
||||
</svg>
|
||||
</div>
|
||||
Является самым лучшим регистратором в мире
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="horizontal-line"></div>
|
||||
@ -508,6 +533,8 @@
|
||||
$("#parameters-device-installer").val("{{Installer}}");
|
||||
$("#parameters-equipment-installed").val(formatDate("{{Installation}}"));
|
||||
$("#parameters-device-description").val("{{Description}}");
|
||||
$('#parameters-our-registrator').prop('checked', {{OurRegistrator}});
|
||||
|
||||
|
||||
document.getElementById('parameters-bg').style.display = 'flex';
|
||||
|
||||
|
@ -94,6 +94,7 @@
|
||||
<div class="checkmark"></div>
|
||||
</label>
|
||||
<input type="number" id="channels-{{this.serial}}" value="{{this.channels}}" hidden>
|
||||
<input type="text" id="ourreg-{{this.serial}}" value="{{this.ourreg}}" 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}}">
|
||||
<span class="text">
|
||||
@ -364,8 +365,18 @@
|
||||
}
|
||||
|
||||
async function playNextCamerasInGroup() {
|
||||
const startCamera = currentCameraGroup === 1 ? 2 : (currentCameraGroup - 1) * camerasPerGroup;
|
||||
const endCamera = startCamera + camerasPerGroup - 1;
|
||||
|
||||
let startCamera;
|
||||
let endCamera;
|
||||
|
||||
serial = $("input[name=camera-serial]:checked").val()
|
||||
if ($(`#ourreg-${serial}`).val() == "true") {
|
||||
startCamera = currentCameraGroup === 1 ? 1 : (currentCameraGroup - 1) * camerasPerGroup;
|
||||
endCamera = startCamera + camerasPerGroup - 1;
|
||||
} else {
|
||||
startCamera = currentCameraGroup === 1 ? 2 : (currentCameraGroup - 1) * camerasPerGroup + 1;
|
||||
endCamera = startCamera + camerasPerGroup - 1;
|
||||
}
|
||||
|
||||
if (startCamera > totalCameras) {
|
||||
// currentCameraGroup = 1;
|
||||
@ -443,7 +454,7 @@
|
||||
}
|
||||
|
||||
// Запустить воспроизведение видео при загрузке страницы
|
||||
playNextCamerasInGroup();
|
||||
// playNextCamerasInGroup();
|
||||
</script>
|
||||
|
||||
|
||||
@ -664,10 +675,10 @@ originalVideo = video;
|
||||
// Меняем стили видео
|
||||
video.style.position = 'fixed';
|
||||
video.style.top = '10%';
|
||||
video.style.left = '0';
|
||||
video.style.width = '100%';
|
||||
video.style.right = '0';
|
||||
video.style.width = '90%';
|
||||
video.style.height = '80%';
|
||||
video.style.zIndex = '1000';
|
||||
video.style.zIndex = '1001';
|
||||
|
||||
popup.style.display = 'block';
|
||||
popupContainer.style.width = '100%';
|
||||
|
@ -8,10 +8,24 @@
|
||||
<link rel="stylesheet" href="../styles/main.css" />
|
||||
<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>
|
||||
<style>
|
||||
.stream-cameras {
|
||||
width: 100%;
|
||||
max-height: 450px;
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<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>
|
||||
|
||||
<header>
|
||||
<img src="../img/argus.png">
|
||||
@ -107,6 +121,7 @@
|
||||
<img>
|
||||
<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>
|
||||
<input type="text" id="ourreg-{{this.serial}}" value="{{this.ourreg}}" hidden>
|
||||
<label for="radio-{{this.serial}}" class="radio-label active-{{this.status}}">
|
||||
{{#if this.number}}
|
||||
{{this.number}}
|
||||
@ -124,8 +139,6 @@
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
<section class="table" style="position: relative;">
|
||||
|
||||
<div class="map">
|
||||
@ -135,7 +148,7 @@
|
||||
<div style="background: white;" class="cameras">
|
||||
<section style="border: 0;" class="whole-width">
|
||||
<h1>Запустить запись с камеры</h1>
|
||||
<h3>Выберите камеру, время и нажмите кнопку "Запустить запись"</h3>
|
||||
<h3 id="cameras-title">Выберите камеру, время и нажмите кнопку "Запустить запись"</h3>
|
||||
<form id="edit-group-form">
|
||||
<div class="parameters-input">
|
||||
<label for="group-id">Камера</label>
|
||||
@ -161,8 +174,20 @@
|
||||
<div style="margin-left: 44px; margin-right: 72px; width: calc(100% - 44px - 72px);" class="horizontal-line"></div>
|
||||
|
||||
<button style="margin-top: 15px;" id="group-edit" class="button-purple" type="button" onclick="playVideo();">Запустить запись</button>
|
||||
<h3>Могут возникнуть проблемы с блокировкой всплывающих окон в браузере, при возникновении проблем проверьте что открытие новых окон из этого сайта у вас работает (обычно иконка отображается в правом верхнем углу).</h3>
|
||||
|
||||
<h3 id="warning">Могут возникнуть проблемы с блокировкой всплывающих окон в браузере, при возникновении проблем проверьте что открытие новых окон из этого сайта у вас работает (обычно иконка отображается в правом верхнем углу).</h3>
|
||||
<br>
|
||||
<!-- <video id="playback-camera"></video> -->
|
||||
<div id="playback-cameras" class="stream-cameras">
|
||||
<div class="stream-video-container">
|
||||
<video id="camera-1"></video>
|
||||
<video id="camera-2"></video>
|
||||
<video id="camera-3"></video>
|
||||
<video id="camera-4"></video>
|
||||
<video style="display: none;" id="camera-5"></video>
|
||||
</div>
|
||||
<button onclick="switchCameras(-1)">Назад</button>
|
||||
<button onclick="switchCameras(1)">Вперед</button>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
@ -200,7 +225,10 @@
|
||||
</div>
|
||||
|
||||
<div class="video-time">
|
||||
<!-- <span id="from-time-label" style="margin-left: 15px; display: none;">с</span> -->
|
||||
<input name="videoTime" type="time" id="video-time" step="1">
|
||||
<!-- <span id="end-time-label" style="display: none;">до</span> -->
|
||||
<!-- <input name="videoEndTime" type="time" id="video-end-time" step="1" style="display: none;"> -->
|
||||
</div>
|
||||
|
||||
|
||||
@ -236,6 +264,7 @@
|
||||
|
||||
<script src="../scripts/jquery.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/flv.js/1.5.0/flv.min.js"></script>
|
||||
|
||||
<script>
|
||||
|
||||
@ -367,6 +396,25 @@ let HasData;
|
||||
var selectedChannel = 1;
|
||||
|
||||
async function sendPostRequest() {
|
||||
stopAllCameras();
|
||||
let serial = $("input[name=camera-serial]:checked").val()
|
||||
if ($(`#ourreg-${serial}`).val() == "true") {
|
||||
$("#warning").hide();
|
||||
$("#playback-cameras").show();
|
||||
$("#edit-group-form").hide();
|
||||
$("#cameras-title").hide();
|
||||
// $("#from-time-label").show();
|
||||
// $("#end-time-label").show();
|
||||
// $("#video-end-time").show();
|
||||
} else {
|
||||
$("#warning").show();
|
||||
$("#playback-cameras").hide();
|
||||
$("#edit-group-form").show();
|
||||
$("#cameras-title").show();
|
||||
// $("#from-time-label").hide();
|
||||
// $("#end-time-label").hide();
|
||||
// $("#video-end-time").hide();
|
||||
}
|
||||
updateCameraOptions();
|
||||
document.getElementById("dataLoading").style.display = 'flex';
|
||||
// Получение данных из полей ввода
|
||||
@ -588,12 +636,26 @@ videoTimeInput.addEventListener("blur", sendPostRequest);
|
||||
</script>
|
||||
|
||||
|
||||
<script>
|
||||
<script>
|
||||
var now = new Date();
|
||||
now.setHours(now.getHours() - 1);
|
||||
var formattedTime = now.toISOString().substr(11, 8);
|
||||
document.getElementById("video-time").value = formattedTime;
|
||||
</script>
|
||||
// const startTimeInput = document.getElementById('video-time');
|
||||
// const endTimeInput = document.getElementById('video-end-time');
|
||||
|
||||
// const startTime = new Date(`1970-01-01T${startTimeInput.value}Z`);
|
||||
|
||||
// startTime.setHours(startTime.getHours() - 3);
|
||||
// startTime.setSeconds(startTime.getSeconds() + 60);
|
||||
|
||||
// const hours = startTime.getHours().toString().padStart(2, '0');
|
||||
// const minutes = startTime.getMinutes().toString().padStart(2, '0');
|
||||
// const seconds = startTime.getSeconds().toString().padStart(2, '0');
|
||||
// const endTimeString = `${hours}:${minutes}:${seconds}`;
|
||||
|
||||
// endTimeInput.value = endTimeString;
|
||||
</script>
|
||||
|
||||
|
||||
<script>
|
||||
@ -696,6 +758,7 @@ videoTimeInput.addEventListener("blur", sendPostRequest);
|
||||
return formatTime(`${hours}:${minutes}:${seconds}`);
|
||||
}
|
||||
|
||||
|
||||
function playVideo() {
|
||||
const channel = document.getElementById("group-id").value;
|
||||
const selectedDevice = document.querySelector('input[name="camera-serial"]:checked');
|
||||
@ -703,14 +766,7 @@ videoTimeInput.addEventListener("blur", sendPostRequest);
|
||||
alert('Пожалуйста, выберите устройство из списка.');
|
||||
return;
|
||||
}
|
||||
if (channel === "") {
|
||||
alert('Пожалуйста, выберите камеру из списка.');
|
||||
return;
|
||||
}
|
||||
if (!HasData) {
|
||||
alert('Пожалуйста, выберите другой временной период.');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const startTimeInput = document.getElementById('video-time');
|
||||
@ -724,9 +780,148 @@ videoTimeInput.addEventListener("blur", sendPostRequest);
|
||||
|
||||
selectedChannel = channel;
|
||||
|
||||
if ($(`#ourreg-${serial}`).val() == "true") {
|
||||
|
||||
playNextCamerasInGroup();
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
if (channel === "") {
|
||||
alert('Пожалуйста, выберите камеру из списка.');
|
||||
return;
|
||||
}
|
||||
if (!HasData) {
|
||||
alert('Пожалуйста, выберите другой временной период.');
|
||||
return;
|
||||
}
|
||||
const url = `http://localhost:8081/playback?url=https%3A%2F%2F{{VIRTUAL_HOST}}%2Fhttp%2Fplayback.flv%3Fserial%3D${serial}%26channel%3D${channel}%26quality%3D1%26queryTime%3D${selectedDate}%26startTime%3D${startTime}%26endTime%3D${endTime}`;
|
||||
window.open(url, '_blank');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
let flvPlayers = [];
|
||||
let currentCameraGroup = 1;
|
||||
const camerasPerGroup = 5;
|
||||
var totalCameras = 12 - 1;
|
||||
const isSecure = window.location.protocol === "https:";
|
||||
const baseURL = "https://{{VIRTUAL_HOST}}/http/playback.flv";
|
||||
|
||||
function stopAllCameras() {
|
||||
flvPlayers.forEach(player => {
|
||||
player.pause();
|
||||
player.unload();
|
||||
player.detachMediaElement();
|
||||
player.destroy();
|
||||
});
|
||||
flvPlayers = [];
|
||||
}
|
||||
|
||||
async function playNextCamerasInGroup() {
|
||||
|
||||
const channel = document.getElementById("group-id").value;
|
||||
const selectedDevice = document.querySelector('input[name="camera-serial"]:checked');
|
||||
|
||||
const startTimeInput = document.getElementById('video-time');
|
||||
// const endTimeInput = document.getElementById('video-end-time');
|
||||
const selectedDateInput = document.getElementById('selectedDate');
|
||||
const startTime = formatTime(startTimeInput.value);
|
||||
// const endTime = formatTime(endTimeInput.value);
|
||||
const selectedDate = formatDate(selectedDateInput.value);
|
||||
|
||||
// const endTime = addOneHourToTime(startTimeInput.value);
|
||||
|
||||
const serial = selectedDevice.value;
|
||||
|
||||
selectedChannel = channel;
|
||||
|
||||
let startCamera;
|
||||
let endCamera;
|
||||
|
||||
if ($(`#ourreg-${serial}`).val() == "true") {
|
||||
startCamera = currentCameraGroup === 1 ? 1 : (currentCameraGroup - 1) * camerasPerGroup;
|
||||
endCamera = startCamera + camerasPerGroup - 1;
|
||||
} else {
|
||||
startCamera = currentCameraGroup === 1 ? 2 : (currentCameraGroup - 1) * camerasPerGroup + 1;
|
||||
endCamera = startCamera + camerasPerGroup - 1;
|
||||
}
|
||||
|
||||
if (startCamera > totalCameras) {
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
stopAllCameras();
|
||||
|
||||
let videoElementIndex = 1;
|
||||
|
||||
for (let i = startCamera; i <= endCamera && i <= totalCameras; i++) {
|
||||
const videoElement = document.getElementById(`camera-${videoElementIndex}`);
|
||||
let flvPlayer = flvjs.createPlayer({
|
||||
type: 'flv',
|
||||
isLive: true,
|
||||
cors: true,
|
||||
url: `${baseURL}?serial=${serial}&channel=${i}&quality=1&queryTime=${selectedDate}&startTime=${startTime}`,
|
||||
}, {
|
||||
enableWorker: true,
|
||||
enableStashBuffer: false,
|
||||
autoCleanupSourceBuffer: true,
|
||||
});
|
||||
|
||||
flvPlayer.attachMediaElement(videoElement);
|
||||
flvPlayer.load();
|
||||
flvPlayer.play();
|
||||
|
||||
flvPlayers.push(flvPlayer);
|
||||
|
||||
let hasStarted = false;
|
||||
|
||||
const checkStarted = () => {
|
||||
if (!hasStarted && videoElement.readyState >= 2) {
|
||||
hasStarted = true;
|
||||
console.log(`Трансляция началась для камеры ${i}`);
|
||||
}
|
||||
};
|
||||
|
||||
const checkInterval = setInterval(checkStarted, 1000);
|
||||
|
||||
setTimeout(() => {
|
||||
clearInterval(checkInterval);
|
||||
if (!hasStarted) {
|
||||
console.log(`Трансляция для камеры ${i} не началась, запрашиваем повторно...`);
|
||||
flvPlayer.unload();
|
||||
flvPlayer.load();
|
||||
flvPlayer.play();
|
||||
// if (i > 0) {
|
||||
// i--;
|
||||
// }
|
||||
}
|
||||
}, 3000);
|
||||
|
||||
videoElementIndex++;
|
||||
|
||||
await new Promise(resolve => setTimeout(resolve, 2000));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
@ -874,6 +1069,80 @@ options: speedOptions,
|
||||
});
|
||||
</script>
|
||||
|
||||
<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.right = '0';
|
||||
video.style.width = '90%';
|
||||
video.style.height = '80%';
|
||||
video.style.zIndex = '1001';
|
||||
|
||||
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>
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
|
Loading…
Reference in New Issue
Block a user