#!/usr/bin/perl -w

# Sreview, a web-based video review and transcoding system
# Copyright (c) 2016-2017, Wouter Verhelst <w@uter.be>
#
# Sreview is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public
# License along with this program.  If not, see
# <http://www.gnu.org/licenses/>.

use strict;
use warnings;

use utf8;
use DBI;
use File::Path qw/make_path/;
use File::Temp qw/tempdir/;
use Mojo::Util qw/xml_escape/;

our $config;
require "./config.pl";

my $dbh = DBI->connect($config->{dbistring}, '', '') or die "Cannot connect to database!";

my $talkid = $ARGV[0];

$dbh->begin_work;

my $started = $dbh->prepare("UPDATE talks SET progress='running', state='transcoding' WHERE id = ?");
$started->execute($talkid);

$dbh->commit;

$dbh->begin_work;

my $talk = $dbh->prepare("SELECT * FROM talks WHERE id = ?");

$talk->execute($talkid);

my $row = $talk->fetchrow_hashref();
my $slug = $row->{slug};

my $data = $dbh->prepare("SELECT eventid, event, room, starttime::date AS startdate, slug, speakers, name, subtitle, apologynote, track FROM talk_list WHERE id = ?");
$data->execute($talkid);
my $drow = $data->fetchrow_hashref();
my $eid = $drow->{eventid};
my $title = $drow->{title};
my $speakers = $drow->{speakers};
my $event = $drow->{event};
my $track = $drow->{track};
my $startdate = $drow->{startdate};
my $pubdir = $config->{pubdir} . "/video/" . $eid . "/" . substr($drow->{room}, 0, 1);
my $outputsub = $config->{outputdir};
my $outputdir = &$outputsub($drow->{event}, $drow->{room}, $drow->{startdate});
make_path($outputdir);
my $tmpdir = tempdir( "transXXXXXX", DIR => $config->{workdir}, CLEANUP => 1);

sub process_template($$) {
	my $input = shift;
	my $output = shift;
	my $outputsvg = "$tmpdir/tmp.svg";
	my $room = xml_escape($drow->{room});
	my $subtitle = xml_escape($drow->{subtitle});
	my $apology = xml_escape($drow->{apologynote});

	open INPUT, "<$input";
	open my $fh, ">:encoding(UTF-8)", $outputsvg;
	$room =~ s/ \(backup\)//;
	while(<INPUT>) {
		s/\@SPEAKERS@/$speakers/g;
		s/\@ROOM@/$room/g;
		s/\@TITLE@/$title/g;
		s/\@SUBTITLE@/$subtitle/g;
		s/\@STARTTIME@/$startdate/g;
		s/\@APOLOGY@/$apology/g;
		print $fh $_;
	}
	close INPUT;
	close $fh;
	system("inkscape --export-png=$output $outputsvg");
}

my $preroll = $pubdir . "/$slug-pre.png";
if ( ! -f $preroll ) {
	process_template($config->{preroll_template}, $preroll);
}

my $postroll = $pubdir . "/$slug-post.png";
if ( ! -f $postroll ) {
	if(exists($config->{postroll_template})) {
		process_template($config->{postroll_template}, $postroll);
	} elsif(exists($config->{postroll})) {
		$postroll = $config->{postroll};
	} else {
		die "need postroll or postroll template!";
	}
}

my $apology = $pubdir . "/$slug-sorry.png";
if(defined($drow->{apologynote}) && length($drow->{apologynote}) > 0) {
	die unless exists($config->{apology_template});
	process_template($config->{apology_template}, $apology);
	system("ffmpeg -y -loop 1 -i $apology -f lavfi -i anullsrc -c:v mpeg2video -pix_fmt yuv422p -framerate 25 -frames:v 125 -b:a 128k -r:a 48000 -ac 1 -map 0:v -map 1:a -shortest $tmpdir/$slug-sorry.ts");
}

# concatenate preroll, apology, main video, postroll
system("ffmpeg -y -loop 1 -i $preroll -f lavfi -i anullsrc -c:v mpeg2video -pix_fmt yuv422p -framerate 25 -frames:v 125 -b:a 128k -r:a 48000 -ac 1 -map 0:v -map 1:a $tmpdir/$slug-preroll.ts");
system("ffmpeg -y -loop 1 -i $postroll -f lavfi -i anullsrc -c:v mpeg2video -pix_fmt yuv422p -framerate 25 -frames:v 125 -b:a 128k -r:a 48000 -ac 1 -map 0:v -map 1:a $tmpdir/$slug-postroll.ts");
if( -f "$tmpdir/$slug-sorry.ts") {
	system("ffmpeg -y -i \"concat:$tmpdir/$slug-preroll.ts|$tmpdir/$slug-sorry.ts|$pubdir/$slug.ts|$tmpdir/$slug-postroll.ts\" -c copy $outputdir/$slug.ts");
} else {
	system("ffmpeg -y -i \"concat:$tmpdir/$slug-preroll.ts|$pubdir/$slug.ts|$tmpdir/$slug-postroll.ts\" -c copy $outputdir/$slug.ts");
}
# VP8
system("ffmpeg -y -i $outputdir/$slug.ts -pass 1 -passlogfile $tmpdir/passlog-vp8 -c:v libvpx -crf 10 -qmin 0 -qmax 20 -b:v 1M -c:a libvorbis $outputdir/$slug.vp8.webm");
system("ffmpeg -y -i $outputdir/$slug.ts -pass 2 -passlogfile $tmpdir/passlog-vp8 -c:v libvpx -crf 10 -qmin 0 -qmax 20 -b:v 1M -c:a libvorbis -metadata \"title=$title\" -metadata \"event=$event\" -metadata \"language=eng\" -metadata \"speakers=$speakers\" -metadata \"track=$track\" -metadata \"date=$startdate\" $outputdir/$slug.vp8.webm");
# VP9
system("ffmpeg -y -i $outputdir/$slug.ts -pass 1 -passlogfile $tmpdir/passlog-vp9 -c:v libvpx-vp9 -crf 32 -b:v 1024k -minrate 512k -maxrate 1485k -c:a libopus -quality good -speed 4 -g 240 -pix_fmt yuv420p -tile-columns 2 -threads 4 $outputdir/$slug.vp9.webm");
system("ffmpeg -y -i $outputdir/$slug.ts -pass 2 -passlogfile $tmpdir/passlog-vp9 -c:v libvpx-vp9 -crf 32 -b:v 1024k -minrate 512k -maxrate 1485k -c:a libopus -quality good -speed 2 -g 240 -pix_fmt yuv420p -tile-columns 2 -threads 4 -metadata \"title=$title\" -metadata \"event=$event\" -metadata \"language=eng\" -metadata \"speakers=$speakers\" -metadata \"track=$track\" -metadata \"date=$startdate\" $outputdir/$slug.vp9.webm");

my $update = $dbh->prepare("UPDATE talks SET progress = 'done' WHERE id = ? AND state = 'transcoding' AND progress = 'running'");
$update->execute($talkid);
$dbh->commit;
