#!/usr/bin/perl -w

use lib '/usr/local/bin';
use slutil;
use FileHandle;

######################################################################
### Voreinstellungen
######################################################################

# Bei alter Version der ffmpeg wird mencoder genommen.
# Liste der "alten" ffmpeg-Versionen:
%too_old_ffmpeg = (
		   'SVN-r26400' => 0,
		  );

#$QUALITY = 1231;

#$MENCODER_OPTS_HQ = "-fafmttag 0x55 -oac mp3lame -lameopts preset=standard -lavcopts vcodec=mpeg4:vbitrate=$QUALITY:mbd=1:lumi_mask=0.5:scplx_mask=0.1:cmp=256:vqmin=2:vqmax=6:mbqmin=2:mbqmax=10:autoaspect=1 -vf pp=lb";

# "-idx ist nötig, damit im AVI ein Index zu Springen drin ist!
#$MENCODER_OPTS_CENTRIX = "-idx -vf scale -zoom -xy 320 -fafmttag 0x55 -oac mp3lame -lameopts preset=standard -lavcopts vcodec=mpeg4:vbitrate=600";

# Video: skaliert auf Breite 640, 500 kBit mp4
# Audio: 128 kBit
# Alte, langsamere Optionen: subq=5 und me=umh
# subq=1 me=dia
$MENCODER ="mencoder -alang deu -af volnorm -msglevel all=4 -oac faac -ovc x264 -sws 9 -x264encopts nocabac:level_idc=30:bframes=0:global_header:threads=auto:subq=1:frameref=6:partitions=all:trellis=1:chroma_me:me=dia:bitrate=500 -lavfopts format=mp4 -faacopts mpeg=4:object=2:raw:br=128 -of lavf -vf scale=640:-10,harddup";

# ffmpeg-Optionen:
# Alt: -c:a libvo_aacenc
# Alt: bitrate=500, Neu: bitrate=1000
$OPTIONS = "-y -c:v libx264 -ac 2 -c:a aac -profile:v baseline -level 3.0 -f mp4 -s 640x368 -x264opts nocabac:level_idc=30:bframes=0:global_header:threads=auto:subq=1:frameref=6:partitions=all:trellis=1:chroma_me:me=dia:bitrate=1000";


######################################################################
### Hauptprogramm
######################################################################

$info = $FALSE;
if ( (defined $ARGV[0]) && ($ARGV[0] eq '--info') )
{
  shift;
  $info = $TRUE;
}

$OUT = pop @ARGV || Hilfe();
$IN  = join(' ',@ARGV);

Hilfe() if $IN eq '';

$use_ffmpeg = $TRUE;
$tmp = Get_ffmpeg_Version();
print "ffmpeg-Version: '$tmp'\n";
if (defined $too_old_ffmpeg{$tmp})
{
  print "Zu alte ffmpeg, verwende mencoder.\n";
  $use_ffmpeg = $FALSE;
}
else
{
  print "Verwende ffmpeg.\n";
}

print "'$IN' -> '$OUT'\n";

$IN_TEMP = "$OUT.$$";

$IN_ESC      = $IN;
$OUT_ESC     = $OUT;
$IN_TEMP_ESC = $IN_TEMP;
# "&" escapen
$IN_ESC      =~ s/\&/\\\&/g;
$OUT_ESC     =~ s/\&/\\\&/g;
$IN_TEMP_ESC =~ s/\&/\\\&/g;
# "'" escapen
$IN_ESC      =~ s/\'/\\\'/g;
$OUT_ESC     =~ s/\'/\\\'/g;
$IN_TEMP_ESC =~ s/\'/\\\'/g;
# "(" escapen
$IN_ESC      =~ s/\(/\\\(/g;
$OUT_ESC     =~ s/\(/\\\(/g;
$IN_TEMP_ESC =~ s/\(/\\\(/g;
# ")" escapen
$IN_ESC      =~ s/\)/\\\)/g;
$OUT_ESC     =~ s/\)/\\\)/g;
$IN_TEMP_ESC =~ s/\)/\\\)/g;
# "!" escapen
$IN_ESC      =~ s/\!/\\\!/g;
$OUT_ESC     =~ s/\!/\\\!/g;
$IN_TEMP_ESC =~ s/\!/\\\!/g;

system("touch ${OUT_ESC}.encoding_running");

if ($use_ffmpeg)
{
#  $input_options = $IN_ESC;
#  $input_options =~ s/ / -i /g;
#  $input_options = '-i ' . $input_options;
  $input_list_file = CreateInputFileList($IN);
  # ffmpeg ~3.3.6 braucht "-safe 0", wenn absolute Pfade angegeben werden!
  $input_options = "-f concat -safe 0 -i $input_list_file";

  print "Input-List-File-Inhalt:\n";
  system("cat $input_list_file");

  $db = GetVolumeGain($input_options);

  print "ffmpeg $input_options $OPTIONS -af 'volume=${db}dB' $OUT_ESC\n";
  ($ret, $sig) = xsystem("ffmpeg $input_options $OPTIONS -af 'volume=${db}dB' $OUT_ESC");
  unlink $input_list_file;
}
else
{
  print "$MENCODER -o $OUT_ESC $IN_ESC\n";
  ($ret, $sig) = xsystem("$MENCODER -o $OUT_ESC $IN_ESC");
}

system("/bin/rm ${OUT_ESC}.encoding_running");
print"### Return-Code: $ret\n";
print"### Signal:      $sig\n";
if ( ($ret > 0) || ($sig > 0) )
{
  system("echo RET=$ret:SIG=$sig > ${OUT_ESC}.encoding_ended_with_error.txt");
}
else
{
  if ($info)
  {
    $IN_ESC =~ s/^(\S+)\/[^\/]+.*/$1/;
    warn "### GREP: grep --text ^D $IN_ESC/info\n";
    system("grep --text ^D $IN_ESC/info | cut -c 3-5000 > ${OUT_ESC}.txt");
  }
}


######################################################################
### Unterprogramme
######################################################################

sub CreateInputFileList
{
  my $list = shift;
  my @files = split(/ /,$list);
  my $file;
  my $filename = "/tmp/vdr2mp4-input-$$";
  my $fh = FileHandle->new();
  open($fh, ">$filename") || die "Kann $filename nicht zum Schreiben öffnen!\n";
  foreach $file (@files)
  {
    # _'_ escapen -> _'\''_
    $file =~ s/'/'\\''/g;
    print $fh "file '".$file."'\n";
  }
  close $fh;
  return $filename;
}


sub Get_ffmpeg_Version
{
  my $tmp = `ffmpeg -version 2>&1 | grep -i '^ffmpeg version'`;
  chomp($tmp);
  $tmp =~ s/^ffmpeg version ([^,]+)[,\s]+Copyright.+/$1/i;
  return $tmp;
}


sub GetVolumeGain
{
  my $input = shift;
  print "Ermittle LautstXXrkenanhebung...\n";
  print "ffmpeg $input -af volumedetect -vn -f null /dev/null\n";
  my $line = `ffmpeg $input -af volumedetect -vn -f null /dev/null 2>&1 | grep max_volume | tail -1`;
  chomp($line);
  $line =~ s/^.*\s+max_volume:\s+-?([0-9\.]+)\s+dB/$1/;
  print "Ergebnis: '$line'\n";
  return $line;
}


sub xsystem
{
  my $command = shift;
  print "$command\n";
  system($command);
  my $ret = ($? >> 8);
  my $sig = ($? & 127);
  return ($ret, $sig);
}


sub Hilfe
{
  die "Aufruf: $0 Quellfiles Zielfile
Quellfiles müssen mit absoluten Pfaden angegeben werden!
Beispiel:
$0 /video/Film/2007-04-07.10.57.50.99.rec/0*.ts ~/work/Film.mp4
";
}
