From b4578cf523be1e86ed7befc6c993e7a848f3aac2 Mon Sep 17 00:00:00 2001 From: Ludovic <54670129+lbr38@users.noreply.github.com> Date: Tue, 10 Dec 2024 15:54:56 +0100 Subject: [PATCH] patch --- docker/config/nginx/motionui.conf | 6 + www/controllers/Camera/Timelapse.php | 2 +- www/public/resources/js/camera.js | 58 +++++---- www/public/resources/js/motion.js | 26 +++- www/public/resources/js/pre/camera.js | 4 +- www/public/resources/styles/motionui.css | 51 +++++--- www/views/includes/camera/timelapse.inc.php | 116 +++++++++--------- .../includes/containers/cameras/list.inc.php | 4 - .../containers/motion/events/list.inc.php | 2 +- 9 files changed, 153 insertions(+), 116 deletions(-) diff --git a/docker/config/nginx/motionui.conf b/docker/config/nginx/motionui.conf index ac4ec265..cfa55022 100644 --- a/docker/config/nginx/motionui.conf +++ b/docker/config/nginx/motionui.conf @@ -83,6 +83,7 @@ server { fastcgi_request_buffering off; } + # Go2rtc stream access location ~ /api/stream.mjpeg { proxy_pass http://127.0.0.1:1984; proxy_http_version 1.1; @@ -92,6 +93,11 @@ server { proxy_read_timeout 86400; } + # Go2rtc main page + location ~ /go2rtc { + proxy_pass http://127.0.0.1:1984/; + } + location ~ \.php$ { root $WWW_DIR/public; include fastcgi_params; diff --git a/www/controllers/Camera/Timelapse.php b/www/controllers/Camera/Timelapse.php index 0dd42a90..92c7e15d 100644 --- a/www/controllers/Camera/Timelapse.php +++ b/www/controllers/Camera/Timelapse.php @@ -130,7 +130,7 @@ public function timelapse() /** * Ignore if it fails to capture image because the camera may not be running 24/7 */ - if ($content === false) { + if ($content === false or empty($content)) { continue; } diff --git a/www/public/resources/js/camera.js b/www/public/resources/js/camera.js index 82853e74..9bedadbb 100644 --- a/www/public/resources/js/camera.js +++ b/www/public/resources/js/camera.js @@ -328,6 +328,9 @@ $(document).on('click','.timelapse-camera-btn',function () { // Execute functions : [ "$('footer').append(jsonValue.message)" ] ); + + // Temporary hide all other stream images to avoid CPU loads + $('.camera-image').hide(); }); /** @@ -380,9 +383,8 @@ $(document).on('click','#timelapse-play-btn',function () { /** * Play timelapse - * @returns */ -async function playTimelapse() +function playTimelapse() { /** * Retrieve camera id, date, max range and all pictures names @@ -587,6 +589,9 @@ $(document).on('click','.hide-camera-configuration-btn',function () { * Event: close timelapse screen */ $(document).on('click','.close-timelapse-btn',function () { + // Show all stream images + $('.camera-image').show(); + $('#timelapse').remove(); }); @@ -594,40 +599,33 @@ $(document).on('click','.close-timelapse-btn',function () { * Event: set a camera on full screen */ $(document).on('click','.full-screen-camera-btn',function () { - var cameraId = $(this).attr('camera-id'); - - /** - * Add full-screen class to set the div on full screen - */ - $('.camera-container[camera-id='+cameraId+']').addClass("full-screen"); - - /** - * Show and hide certain buttons - */ - $('.delete-camera-btn[camera-id='+cameraId+']').hide(); - $('.configure-camera-btn[camera-id='+cameraId+']').hide(); - $('.timelapse-camera-btn[camera-id='+cameraId+']').hide(); - $('.close-full-screen-container[camera-id='+cameraId+']').css('display', 'block'); + var img = $(this); + + html = '<div id="fullscreen">' + + '<div class="flex align-item-center">' + + '<img src="' + img.attr('src') + '" class="fullscreen-image" alt="Camera Image" />' + + '</div>' + + '<div class="flex align-item-center justify-center">' + + '<img src="/assets/icons/close.svg" class="close-fullscreen-btn pointer lowopacity" title="Close fullscreen">' + + '</div>' + + '</div>'; + + // Append the fullscreen div to the body + $('body').append(html); + + // Temporary hide all other stream images to avoid CPU loads + $('.camera-image').hide(); }); /** * Event: close camera full screen */ -$(document).on('click','.close-full-screen-btn',function () { - var cameraId = $(this).attr('camera-id'); +$(document).on('click','.close-fullscreen-btn',function () { + // Show all stream images + $('.camera-image').show(); - /** - * Remove full-screen class to set the div on normal screen - */ - $('.camera-container[camera-id='+cameraId+']').removeClass("full-screen"); - - /** - * Show and hide certain buttons - */ - $('.delete-camera-btn[camera-id='+cameraId+']').show(); - $('.configure-camera-btn[camera-id='+cameraId+']').show(); - $('.timelapse-camera-btn[camera-id='+cameraId+']').show(); - $('.close-full-screen-container[camera-id='+cameraId+']').hide(); + // Remove the fullscreen div + $('#fullscreen').remove(); }); /** diff --git a/www/public/resources/js/motion.js b/www/public/resources/js/motion.js index 96eba13b..ca16adb1 100644 --- a/www/public/resources/js/motion.js +++ b/www/public/resources/js/motion.js @@ -247,8 +247,17 @@ $(document).on('change','.event-date-input',function () { $(document).on('click','.play-picture-btn',function () { var fileId = $(this).attr('file-id'); - $('.event-print-file').html('<img src="/media?id=' + fileId + '" />'); - $('.event-print-file-container').css('display', 'flex'); + html = '<div id="fullscreen">' + + '<div class="flex align-item-center">' + + '<img src="/media?id=' + fileId + '" title="Full screen event picture" />' + + '</div>' + + '<div class="flex align-item-center justify-center">' + + '<img src="/assets/icons/close.svg" class="close-fullscreen-btn pointer lowopacity" title="Close fullscreen">' + + '</div>' + + '</div>'; + + // Append the fullscreen div to the body + $('body').append(html); }); /** @@ -257,8 +266,17 @@ $(document).on('click','.play-picture-btn',function () { $(document).on('click','.play-video-btn',function () { var fileId = $(this).attr('file-id'); - $('.event-print-file').html('<video controls><source src="/media?id=' + fileId + '"><p>You browser does not support embedded videos.</p></video>'); - $('.event-print-file-container').css('display', 'flex'); + html = '<div id="fullscreen">' + + '<div class="flex align-item-center">' + + '<video controls title="Full screen event video"><source src="/media?id=' + fileId + '"><p>You browser does not support embedded videos.</p></video>' + + '</div>' + + '<div class="flex align-item-center justify-center">' + + '<img src="/assets/icons/close.svg" class="close-fullscreen-btn pointer lowopacity" title="Close fullscreen">' + + '</div>' + + '</div>'; + + // Append the fullscreen div to the body + $('body').append(html); }); /** diff --git a/www/public/resources/js/pre/camera.js b/www/public/resources/js/pre/camera.js index 9dbbc21a..7b9b864d 100644 --- a/www/public/resources/js/pre/camera.js +++ b/www/public/resources/js/pre/camera.js @@ -4,7 +4,7 @@ */ function setUnavailable(cameraId) { - $('.camera-container[camera-id=' + cameraId + ']').find('.camera-loading').hide(); - $('.camera-container[camera-id=' + cameraId + ']').find('.camera-image').hide(); + $('.camera-container[camera-id=' + cameraId + ']').find('.camera-loading').remove(); + $('.camera-container[camera-id=' + cameraId + ']').find('.camera-image').remove(); $('.camera-container[camera-id=' + cameraId + ']').find('.camera-unavailable').css('display', 'flex'); } diff --git a/www/public/resources/styles/motionui.css b/www/public/resources/styles/motionui.css index 45727bea..ad3c25c2 100644 --- a/www/public/resources/styles/motionui.css +++ b/www/public/resources/styles/motionui.css @@ -470,7 +470,7 @@ h3 { display: flex; flex-direction: column; justify-content: center; - margin: 20px 15px; + margin: 15px; } .camera-image > img { @@ -507,7 +507,11 @@ h3 { width: 30%; height: 30%; } -#timelapse, .full-screen { + +#fullscreen, #timelapse { + display: grid; + row-gap: 15px; + justify-content: center; position: fixed; top: 0; left: 0; @@ -519,16 +523,29 @@ h3 { -webkit-box-shadow: rgb(0 0 0) 0px 10px 13px -12px, rgb(0 0 0 / 15%) 0px 0px 10px 2px; box-shadow: rgb(0 0 0) 0px 10px 13px -12px, rgb(0 0 0 / 15%) 0px 0px 10px 2px; } +#fullscreen { + grid-template-rows: 80% 20%; +} +#timelapse { + grid-template-rows: 40% 40% 20%; +} #timelapse-picture-container { display: flex; + flex-direction: column; align-items: center; justify-content: center; - max-height: 40vh; - max-width: 100vw; + row-gap: 15px; + height: 100% !important; + max-height: 100% !important; +} +#timelapse-picture-container div:nth-child(1) { + max-height: 100%; } #timelapse-picture { max-height: 100%; - max-width: 100vw; + width: auto; + max-width: 100%; + margin: auto; border-radius: 2px; box-shadow: 0px 1px 5px 0px rgb(13 13 13 / 50%); } @@ -536,17 +553,13 @@ h3 { width: 85vw; } -.close-timelapse-btn, .close-full-screen-btn { +.close-timelapse-btn, .close-fullscreen-btn { width: 50px; height: 50px; - margin: auto; } -.full-screen img { - max-height: 85vh; - max-width: 100vw; - display: block !important; - margin: auto; - border-radius: 2px; +#fullscreen img:first-child, #fullscreen video { + max-height: 100% !important; + max-width: 100% !important; } .hide { @@ -758,10 +771,6 @@ footer #github img { width: 25px; } justify-content: space-around; } - #timelapse-picture-container { - max-height: 70vh; - } - #motion-events-captures-container { grid-template-columns: repeat(2, 45%); justify-content: space-between; @@ -848,6 +857,14 @@ footer #github img { width: 25px; } grid-template-columns: repeat(3, 1fr); } + #timelapse { + grid-template-rows: 65% 20% 15%; + } + + #fullscreen { + grid-template-rows: 85% 15%; + } + .bottom-buttons { justify-content: center; align-items: center; diff --git a/www/views/includes/camera/timelapse.inc.php b/www/views/includes/camera/timelapse.inc.php index 920d36c1..5171f024 100644 --- a/www/views/includes/camera/timelapse.inc.php +++ b/www/views/includes/camera/timelapse.inc.php @@ -1,69 +1,71 @@ <div id="timelapse" class="grid justify-items-center row-gap-10"> <div id="timelapse-picture-container"> - <?php - if (empty($date)) { - $date = date('Y-m-d'); - } - - if (!empty($picture)) { - $picture = $date . '/' . $picture; - } - - /** - * Retrieve timelapse pictures for the specified date - */ - try { - /** - * Timelapse pictures root directory - */ - $timelapseDir = CAMERAS_TIMELAPSE_DIR . '/camera-' . $cameraId; + <div class="flex align-item-center"> + <?php + if (empty($date)) { + $date = date('Y-m-d'); + } - /** - * Check if specified date directory exists - */ - if (!file_exists($timelapseDir . '/' . $date)) { - throw new Exception('No timelapse images for this date yet'); + if (!empty($picture)) { + $picture = $date . '/' . $picture; } /** - * Retrieve pictures name for the specified date + * Retrieve timelapse pictures for the specified date */ - $pictures = array(); - $picturesGlob = glob($timelapseDir . '/' . $date . '/*.jpg'); + try { + /** + * Timelapse pictures root directory + */ + $timelapseDir = CAMERAS_TIMELAPSE_DIR . '/camera-' . $cameraId; - foreach ($picturesGlob as $pictureGlob) { - $pictures[] = basename($pictureGlob); - } + /** + * Check if specified date directory exists + */ + if (!file_exists($timelapseDir . '/' . $date)) { + throw new Exception('No timelapse images for this date yet'); + } - /** - * If there are no pictures, throw an exception - */ - if (empty($pictures)) { - throw new Exception('No timelapse images for this date yet'); - } + /** + * Retrieve pictures name for the specified date + */ + $pictures = array(); + $picturesGlob = glob($timelapseDir . '/' . $date . '/*.jpg'); - /** - * Print first image first - */ - if (empty($picture)) { - $picture = $date . '/' . $pictures[0]; - } + foreach ($picturesGlob as $pictureGlob) { + $pictures[] = basename($pictureGlob); + } - /** - * Print all pictures in a hidden element - */ - echo '<timelapse-data pictures="' . implode(',', $pictures) . '"></timelapse-data>'; + /** + * If there are no pictures, throw an exception + */ + if (empty($pictures)) { + throw new Exception('No timelapse images for this date yet'); + } - /** - * Print picture - */ - echo '<img id="timelapse-picture" src="/timelapse?id=' . $cameraId . '&picture=' . $picture . '" />'; - } catch (Exception $e) { - echo '<p>' . $e->getMessage() . '</p>'; - } ?> + /** + * Print first image first + */ + if (empty($picture)) { + $picture = $date . '/' . $pictures[0]; + } + + /** + * Print all pictures in a hidden element + */ + echo '<timelapse-data pictures="' . implode(',', $pictures) . '"></timelapse-data>'; + + /** + * Print picture + */ + echo '<img id="timelapse-picture" src="/timelapse?id=' . $cameraId . '&picture=' . $picture . '" />'; + } catch (Exception $e) { + echo '<p>' . $e->getMessage() . '</p>'; + } ?> + </div> </div> - <div class="grid justify-space-between row-gap-10 padding-left-15 padding-right-15"> + <div class="flex flex-direction-column row-gap-10 padding-left-15 padding-right-15"> <div> <?php if (!empty($picture)) { @@ -97,7 +99,7 @@ $firstPictureMin = explode('-', $firstPictureTime)[1]; $firstPictureSec = explode('-', $firstPictureTime)[2]; - echo '<div><p class="lowopacity-cst">' . $firstPictureHour . ':' . $firstPictureMin . ':' . $firstPictureSec . '</p></div>'; + echo '<div><p class="lowopacity-cst font-size-13">' . $firstPictureHour . ':' . $firstPictureMin . ':' . $firstPictureSec . '</p></div>'; /** * Print last picture time @@ -107,7 +109,7 @@ $lastPictureMin = explode('-', $lastPictureTime)[1]; $lastPictureSec = explode('-', $lastPictureTime)[2]; - echo '<div><p class="lowopacity-cst">' . $lastPictureHour . ':' . $lastPictureMin . ':' . $lastPictureSec . '</p></div>'; + echo '<div><p class="lowopacity-cst font-size-13">' . $lastPictureHour . ':' . $lastPictureMin . ':' . $lastPictureSec . '</p></div>'; } ?> </div> @@ -172,9 +174,9 @@ </select> </div> </div> + </div> - <div class="flex margin-bottom-40"> - <img src="/assets/icons/close.svg" class="close-timelapse-btn pointer lowopacity" title="Close timelapse screen"> - </div> + <div class="flex align-item-center"> + <img src="/assets/icons/close.svg" class="close-timelapse-btn pointer lowopacity" title="Close timelapse screen"> </div> </div> \ No newline at end of file diff --git a/www/views/includes/containers/cameras/list.inc.php b/www/views/includes/containers/cameras/list.inc.php index 853ceeec..bf02d887 100644 --- a/www/views/includes/containers/cameras/list.inc.php +++ b/www/views/includes/containers/cameras/list.inc.php @@ -126,10 +126,6 @@ </div> </div> </div> - - <div class="close-full-screen-container margin-bottom-30 hide" camera-id="<?= $camera['Id'] ?>"> - <img src="/assets/icons/close.svg" class="close-full-screen-btn pointer lowopacity" camera-id="<?= $camera['Id'] ?>" title="Close full screen" /> - </div> </div> </div> <?php diff --git a/www/views/includes/containers/motion/events/list.inc.php b/www/views/includes/containers/motion/events/list.inc.php index 91852c73..b8eeca5f 100644 --- a/www/views/includes/containers/motion/events/list.inc.php +++ b/www/views/includes/containers/motion/events/list.inc.php @@ -41,6 +41,6 @@ <!-- Close button --> <div class="event-print-file-close-btn margin-bottom-30 hide" style="display: block;"> - <img src="/assets/icons/close.svg" class="close-full-screen-btn pointer lowopacity" title="Close full screen"> + <img src="/assets/icons/close.svg" class="close-fullscreen-btn pointer lowopacity" title="Close full screen"> </div> </div>