#
# Reolink came out with a new camera "Duo" which has a 180 degree field of view.  It really is two cameras combined
# where their outputs are stitched together to create a wide panoramic video.  Reolink decided that the main feed
# should be encoded with H.265 instead of H.264 as has been used by their prior models.  They have set a dichotomy of
# of 8 megapixel ("MP") feeds use H.265, whereas 4 MP use H.264.
#
# Moonfire currently does not support using H.265, primarily because Firefox & Chrome browsers do not support H.265 due
# to patent restrictions.  So we have Reolink using H.265 and browsers not supporting H.265 and Moonfire-nvr caught in the
# the middle.  This script helps produce results which allow one to compare the quality of the images extracted from
# videos using H.265 vs. H.264.  
#
# After reviewing a video and determining the precise second you want extracted and
# entered below, this script will pull a PNG format image.  Remember to use tabs between fields, not spaces.
#
# Format for data
#[camera]
#[tab][direction]
#[tab][tab][time stamp][tab][distance marker]
#
# where "time stamp" in format of 
#	[Hour]:[Minute]:[Second]
# all with 2 digit values for each component separated by colons
#
# $feed = name of video feed usually differing in quality, 
# in Reolink there are two "main" and "sub"
#
# $direction = the area within the video frame, e.g. left/right, east/west, norht/south
#
# use this command to run:
#
#	perl /home/jlpoole/work/Reolink180/generate_samples_from_videos.pl
#
#

use strict;
use warnings;

my $DEBUG = 0;  # set to 1 to activate
#
# we'll use the codec descriptoter, "H.264/5" in the output despite input being sub/main
#
my $current_feed;        # e.g. "main" , "sub" -- note each must map to a codec
my $current_codec;   	 # H.265 or H.264
my $current_direction;   # e.g. "west" or "east"
my $current_input_video; # the video file determiend from look-up table below

my $video_dir = "/home/jlpoole/work/Reolink180";

#
# look-up table [hash] for video files based on feed name
#
my %files = ( 
	"main" => "$video_dir/Court180-101259-102636.mp4",
	"sub" => "$video_dir/20230417102010-Court180-sub.mp4",
);
#
# QA the data
#
while (<DATA>){
	my $line = $_;
	print "Processing line: $line\n" if $DEBUG == 1;
	#
	# "chomp" is not enough, need to remove carriage returns, too!
	#
	$line =~ s/(\n|\r)//g; # remove carrage return/linefeed
	my ($camera, $direction, $distance) = &parse_line($line);
	next unless defined $camera;
	next if $camera == 1; # definition line only, no station point
	die "Unrecognized DATA format." if $camera == -1;
	my $cmd = &create_command($camera, $direction, $distance);
}

#
# ------------------------------------ subs ---------------------------
#

#
# returns -1 and prints the offending/unrecognized line
# Not vigorously QAing the input since this is a highly specialized script
# presumably being run by someone who fully understands what is going on and
# can detect why there might be errors in the ffmpeg command.
#
sub parse_line {
	my ($line) = @_;
	return undef unless defined $line && $line ne ""; # skip empty lines
	return undef if $line =~ /\#/;  # any line with a hashmark is considered a commen
	my ($feed, $direction, $timestamp, $distance) = split "\t", $line;
	
	if (defined $feed && $feed ne ""){
		#
		# we have a camera definition line
		#
		$current_feed = lc($feed);  # smash to lowercase
		print "Setting current_feed => >>$current_feed<<\n" if $DEBUG == 1;
		if ($feed =~ /main/){
			$current_codec = '265'; 
		} elsif ($feed =~ /sub/) {
			$current_codec = '264';
		} else {
			die "Unexpected feed: >>$feed<<";
		}
		$current_input_video =  $files{$feed};
		die "current_input_video not defined"
			unless defined $current_input_video;
		return 1;
	}
	if (defined $direction  && $direction ne ""){
		#
		# we have a direction definition line
		#
		$current_direction = $direction;
		return 1;
	}
	#
	# QA station point line: there should be 3 tabs
	#
	my @tabs = $line =~/(\t)/g;
	my $tab_count = @tabs;
	#print "tab_count = $tab_count\n";
	die "Incorrect tab count on station point line: $tab_count" unless $tab_count == 3;
	#
	# we have a station point line
	#
	die "codec not defined" unless defined $current_codec;
	print "timestamp: $timestamp\tdistance: $distance\n" if $DEBUG == 1;
	
	my $image = qq{$current_codec\_$current_feed\_$current_direction\_$distance.png};
	#
	# the "-y" parameter overwrites pre-existing files withough prompting you
	#
	my $cmd = qq{ ffmpeg -ss $timestamp -y -i $current_input_video -frames:v 1  $image};
	print "$cmd\n";
	#
	# execute the command
	#
	`$cmd`;
}

=pod
See https://stackoverflow.com/questions/27568254/how-to-extract-1-screenshot-for-a-video-with-ffmpeg-at-a-given-time
=cut


__DATA__
sub
	west
		0:40	25
		1:03	50
		1:26	75
		1:53	100
	east
		2:48	25
		3:09	50
		3:31	75
		4:06	100

main
	west
		6:29	25
		6:51	50
		7:15	75
		7:42	100
	east
		8:37	25
		8:58	50
		9:20	75
		9:54	100
# extra shot
# 12:14   across the street

