summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJon duSaint2023-08-30 18:48:40 -0700
committerJon duSaint2023-08-30 18:48:40 -0700
commitbb5f23531b8b13ff65dca2b53eab7e2b04774013 (patch)
treece175893a6f0f53e6297d6067ec6660ff7ff8592
parent1b9a6efa645b342b6b0977c5a9da4c0cf2423119 (diff)

reolink: Change video format

The state of video in the browser is a hot mess. And not in a good way.

Google and Mozilla support the fancy VP9 encoding. Apple does not. Sadly, since the videos have reasonably good quality and small size.

Apple supports H.265, also a fancy encoding. But neither Google nor Mozilla support that.

What they all can agree on is H.264. Which isn’t bad, but isn’t great either. But since those dorks can’t get their act together, then H.264 it is for the rest of us. The “front end” people do stupid tricks like encode each video in several different formats and let the browser choose, but come on, really?

-rwxr-xr-xreolink/reolink71
1 files changed, 55 insertions, 16 deletions
diff --git a/reolink/reolink b/reolink/reolink
index 8a1a76b..37aeca4 100755
--- a/reolink/reolink
+++ b/reolink/reolink
@@ -25,6 +25,7 @@ my ($min_interval, $interval, $max_interval) = (10, 30, 600);
# Retain images in the spool 24 hours by default
my $spool_retention_time = 24;
my $default_video_range = '0530-2130';
+my ($video_format, $video_extension) = ('h264', 'mp4'); # ('vp9', 'webm') also supported
my %commands = (
interval => {
@@ -348,7 +349,7 @@ sub maybe_generate_video {
my $video_prefix = @_ >= 1 ? $_[0] : sprintf ('%04d%02d%02d', $t[5]+1900, $t[4]+1, $t[3]);
- my @videos = <$server_params{spool_dir}/$video_prefix*.webm>;
+ my @videos = <$server_params{spool_dir}/$video_prefix*.$video_extension>;
if (@videos) {
debug ("already generated for $video_prefix");
@@ -578,7 +579,7 @@ IMAGE
op = document.getElementById ("video-menu");
stem = op.options[op.selectedIndex].value;
vb = document.getElementById ("videobox");
- vb.src = stem + ".webm";
+ vb.src = stem + ".$video_extension";
vb.poster = stem + "_kf.jpg";
}
@@ -607,15 +608,15 @@ IMAGE
SLIDESHOW
my @videos;
- foreach my $video (<"$server_params{spool_dir}/*.webm">) {
- if ($video =~ m,/(\d{4})(\d{2})(\d{2})\.webm$,) {
+ foreach my $video (<"$server_params{spool_dir}/*.$video_extension">) {
+ if ($video =~ m,/(\d{4})(\d{2})(\d{2})\.$video_extension$,) {
push @videos, [$1, $2, $3];
}
}
print $fh $_ foreach map { qq( <option value="$_->[0]$_->[1]$_->[2]">$_->[0]-$_->[1]-$_->[2]</option>\n) } reverse @videos;
- my ($video, $keyframe) = ("$videos[-1]->[0]$videos[-1]->[1]$videos[-1]->[2].webm",
+ my ($video, $keyframe) = ("$videos[-1]->[0]$videos[-1]->[1]$videos[-1]->[2].$video_extension",
"$videos[-1]->[0]$videos[-1]->[1]$videos[-1]->[2]_kf.jpg");
print $fh <<"SLIDESHOW";
@@ -856,25 +857,25 @@ sub validate_video_times {
return ();
}
-sub process {
+sub process_pass {
my $quality = shift;
my $size = shift;
+ my $lib = shift;
+ my $bitrate = shift;
my $pass = shift;
my $outfile = shift;
my @files = @_;
- # Two pass VP9 webm constant quality encoding
my $cmd = ("ffmpeg"
." -y"
." -framerate 24"
." -f image2pipe -i -"
." -vf scale=$size"
- ." -c:v libvpx-vp9"
- ." -b:v 0"
+ ." -c:v $lib"
+ ." -b:v $bitrate"
." -quality good"
- ." -crf $quality"
- ." -pass $pass"
- ." -speed ".($pass == 1 ? 4 : 2)
+ ." $quality"
+ .($pass ? (" -pass $pass"." -speed ".($pass == 1 ? 4 : 2)) : '')
." -an"
.' '.$outfile);
@@ -903,10 +904,50 @@ sub process {
}
close ($ffmpeg);
+}
+
+# Two pass VP9 webm constant quality encoding
+sub process_vp9 {
+ my $basefile = shift;
+ my @files = @_;
+ my $outfile = "$basefile.webm";
+
+ process_pass ('-crf '.$video_params[$v->{index}]->{crf}, $video_params[$v->{index}]->{size}, 'libvpx-vp9', '0', $_, $outfile, @files) for (1..2);
+
+ return $outfile;
+}
+
+# H.264
+# This is nearly twice the size of VP9, but apple products don't support that or AV1, and firefox doesn't support MP4/HEVC. Lame.
+sub process_h264 {
+ my $basefile = shift;
+ my @files = @_;
+ my $outfile = "$basefile.mp4";
+
+ process_pass ('-preset veryslow', $video_params[$v->{index}]->{size}, 'libx264', 0, 0, $outfile, @files);
+
+ return $outfile;
+}
+
+
+sub process {
+ my $v = shift;
+ my $spool = shift;
+ my @files = @_;
+ my $basefile = File::Spec->catfile ($process_params{spool_dir}, $spool, $ARGV[0]$v->{suffix});
+ my $outfile;
+
+ if ($video_format eq 'vp9') {
+ $outfile = process_vp9 ($basefile, @files);
+ } elsif ($video_format eq 'h264') {
+ $outfile = process_h264 ($basefile, @files);
+ } else {
+ die "Video format '$video_format' not supported";
+ }
# "Key frame" is the still to show for the video. Use the middle image.
my ($keyframe_in, $keyframe) = ($files[int (@files / 2)], $outfile);
- $keyframe =~ s/\.webm$/_kf.jpg/;
+ $keyframe =~ s/\.$video_extention$/_kf.jpg/;
print ("generating keyframe $keyframe_in $keyframe\n");
my $geometry = $size;
$geometry =~ s/:/x/g;
@@ -952,10 +993,8 @@ sub run {
my @times;
my @fps;
foreach my $v (@videos) {
- my $outfile = "$process_params{spool_dir}/$ARGV[0]$v->{suffix}.webm";
my $t1 = time;
- process ($video_params[$v->{index}]->{crf}, $video_params[$v->{index}]->{size}, 1, $outfile, @filelist);
- process ($video_params[$v->{index}]->{crf}, $video_params[$v->{index}]->{size}, 2, $outfile, @filelist);
+ my $outfile = process ($v, @filelist);
my $t2 = time;
push @outfiles, $outfile;
push @times, $t2 - $t1;