summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJon duSaint2022-07-18 15:25:05 -0700
committerJon duSaint2022-07-18 15:25:05 -0700
commit781d3c600a4dda806206aa50a3b2ddeea727bf87 (patch)
tree4c75af1f03f9b1a5f33a3aa9000f238abf976c9f
parentc56fb66ca1ce5db7bd28c3383c5a20f1490d856d (diff)

reolink: generate simple slideshow web page

Static page with simple slideshow, generated after each snapshot and respool.

-rwxr-xr-xreolink/reolink163
1 files changed, 161 insertions, 2 deletions
diff --git a/reolink/reolink b/reolink/reolink
index 9e54b30..36bdbb0 100755
--- a/reolink/reolink
+++ b/reolink/reolink
@@ -105,6 +105,7 @@ sub load_params {
package Server;
use Errno qw/EINTR/;
+use File::Basename;
use File::Path 'make_path';
use File::Spec;
use Getopt::Long;
@@ -375,19 +376,177 @@ sub maybe_generate_video {
debug ("launched video process as pid $process_child");
}
-sub respool {
+sub respool_and_generate_slideshow {
# Retain only past 24 hours of stills
my $t = time - $server_params{spooltime} * 60 * 60;
+ # Generate a slideshow web page
+ my $fh;
+ unless (open ($fh, '>', "$server_params{spool_dir}/index.html")) {
+ error ("open(index.html): $!");
+ }
+
+ if ($fh) {
+ print $fh <<"SLIDESHOW";
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Slideshow</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+ <style type="text/css">
+ body {
+ background-color: #008080;
+ color: black;
+ }
+ div.outer {
+ background-color: #004040;
+ border-radius: 1%;
+ position: fixed;
+ padding: 10px;
+ top: 50%;
+ margin-top: -480px;
+ left: 50%;
+ margin-left: -640px;
+ }
+ div.caption {
+ font-size: 2em;
+ display: flex;
+ }
+ div.caption > span {
+ margin: auto;
+ }
+ div.controls {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ font-weight: bold;
+ margin: 8px;
+ cursor: pointer;
+ }
+ span.button {
+ font-size: 4em;
+ border: 2px solid black;
+ border-radius: 10%;
+ flex-grow: 1;
+ margin: 4px;
+ }
+ span.tick {
+ flex-grow: 1;
+ font-weight: bold;
+ }
+ span.bigtick {
+ font-size: 2em;
+ flex-grow: 1;
+ font-weight: bold;
+ }
+ </style>
+
+ <script type="text/javascript">
+ var images = [
+SLIDESHOW
+ }
+
foreach my $image (<"$server_params{spool_dir}/*.jpg">) {
if ($image =~ m/(\d{4})(\d{2})(\d{2})-(\d{2})(\d{2})(\d{2})\.jpg/) {
my $file_time = mktime ($6, $5, $4, $3, $2 - 1, $1 - 1900);
if ($file_time < $t) {
debug ("delete $image ($file_time $t)");
unlink $image;
+ } elsif ($fh) {
+ my $im = basename ($image);
+ print $fh <<"IMAGE";
+ { image: "$im", title: "$1-$2-$3 $4:$5:$6" },
+IMAGE
}
}
}
+
+ if ($fh) {
+ print $fh <<"SLIDESHOW";
+ ];
+
+ var current = 0;
+ var originalTick = null;
+
+ function set_image() {
+ if (current >= 0 && current < images.length) {
+ img = document.getElementById ("photo-display");
+ img.src = images[current].image;
+ cap = document.getElementById ("photo-caption");
+ cap.innerHTML = images[current].title;
+
+ percent = parseInt(current / (images.length - 1) * 100);
+ tick = document.getElementById ("tick" + percent);
+ tick.style.color = "blue";
+ tick.innerHTML = '⋄';
+ if (originalTick != null && originalTick != tick) {
+ originalTick.style.color = "black";
+ originalTick.innerHTML = '|';
+ }
+ originalTick = tick;
+ }
+ }
+
+ function rewind_image() {
+ current = 0;
+ set_image();
+ }
+
+ function previous_image() {
+ if (current > 0) {
+ current--;
+ }
+ set_image();
+ }
+
+ function next_image() {
+ if (current + 1 < images.length) {
+ current++;
+ }
+ set_image();
+ }
+
+ function ffwd_image() {
+ current = images.length - 1;
+ set_image();
+ }
+
+ function seek_image(p) {
+ current = parseInt(p / 100 * (images.length - 1))
+ set_image();
+ }
+ </script>
+ </head>
+ <body onload="ffwd_image();">
+ <div class="outer">
+ <div class="caption">
+ <span id="photo-caption"></span>
+ </div>
+ <div class="inner">
+ <div class="slide"><img id="photo-display" src="" width="1280" height="960"/></div>
+ </div>
+ <div class="controls">
+ <span class="button" onclick="rewind_image()">&lt;&lt;</span>
+ <span class="button" onclick="previous_image()">&lt</span>
+SLIDESHOW
+
+ foreach (0..100) {
+ my $class = ($_ % 10) ? 'tick' : 'bigtick';
+ print $fh <<"SLIDESHOW";
+ <span class="$class" id="tick$_" onclick="seek_image($_);">|</span>
+SLIDESHOW
+ }
+
+ print $fh <<"SLIDESHOW";
+ <span class="button" onclick="next_image()">&gt;</span>
+ <span class="button" onclick="ffwd_image()">&gt;&gt;</span>
+ </div>
+ </div>
+
+ </body>
+</html>
+SLIDESHOW
+ }
}
sub upload {
@@ -442,7 +601,7 @@ sub run {
do {
snapshot;
maybe_generate_video ();
- respool ();
+ respool_and_generate_slideshow ();
for (my $remaining = $server_params{interval}, my $start_time = time; $remaining > 0 && $keep_going;) {
$! = 0;