diff options
| author | Jon duSaint | 2023-08-30 18:48:40 -0700 |
|---|---|---|
| committer | Jon duSaint | 2023-08-30 18:48:40 -0700 |
| commit | bb5f23531b8b13ff65dca2b53eab7e2b04774013 (patch) | |
| tree | ce175893a6f0f53e6297d6067ec6660ff7ff8592 | |
| parent | 1b9a6efa645b342b6b0977c5a9da4c0cf2423119 (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-x | reolink/reolink | 71 |
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; |
