#!/usr/local/bin/perl -w
###########################################
# video-title-add
# 2009, Mike Schilli <m@perlmeister.com>
###########################################
use strict;
use Sysadm::Install qw(:all);
use Imager;
use Imager::Fill;
use Log::Log4perl qw(:easy);
use Video::FrameGrab;
use File::Temp qw(tempdir tempfile);

sub shell;

my $title_length  = 2; # length in seconds
my $FONT_FILENAME = "/usr/share/fonts/" .
  "truetype/ttf-bitstream-vera/VeraSe.ttf";

Log::Log4perl->easy_init($ERROR);

my($video_file, $upper, $lower) = @ARGV;
die "usage: $0 ",
    "video_file upper_text lower_text" 
    unless defined $upper;

(my $video_out = $video_file) =~ 
                s/(\.[^.]+$)/-withtitle$1/;

my $video_mum   = throwaway_file(".avi");
my $video_title = throwaway_file(".avi");
my $audio_title = throwaway_file(".wav");
my $audio_total = throwaway_file(".wav");

my $grabber = Video::FrameGrab->new(
                     video => $video_file);

my $meta = $grabber->meta_data();

my $height = $meta->{video_height};
my $width  = $meta->{video_width};

my $dir = jpeg_dir_create( 
    $width, $height, $upper, $lower,
    $meta->{video_fps} * $title_length);

shell qw(mencoder -nosound),
      "mf://$dir/*.jpg",
      qw(-mf fps=30 -o),
      $video_title,
      qw(-ovc lavc -lavcopts vcodec=mjpeg);

my $sample_size = $meta->{audio_bitrate} /
 $meta->{audio_rate} / 
 $meta->{audio_nch} / 8;

silent_wav( $title_length, $audio_title, 
  $meta->{audio_rate}, $meta->{audio_nch},
  $sample_size );

shell qw(mplayer -vc null -vo null -ao 
         pcm), $video_file;

shell "sox", $audio_title, 
      "audiodump.wav", "-o", $audio_total;

shell "mencoder", "-nosound", $video_title, 
      $video_file, qw(-ovc lavc -lavcopts 
      vcodec=mjpeg -o), $video_mum;

    # add sound
shell "mencoder", $video_mum, qw(-oac copy 
      -audiofile), $audio_total, 
      qw(-ovc copy -o), $video_out;

###########################################
sub throwaway_file {
###########################################
    my($suffix) = @_;

    my($fh, $file) = tempfile(
        UNLINK => 1, 
        SUFFIX => $suffix,
    );
    return $file;
}

###########################################
sub shell {
###########################################
    my($stdout, $stderr, $rc) = tap @_;

    if($rc) {
        die "Command @_ failed: $stderr";
    }
}

###########################################
sub jpeg_dir_create {
###########################################
  my($w, $h, $upper, $lower, $n) = @_;

  my $img = Imager->new(xsize => $width, 
                        ysize => $height);

  my $black = Imager::Color->new( 0,0,0 );
  $img->box(color=> $black, filled => 1);


  my $font = Imager::Font->new( file =>
    $FONT_FILENAME) or die Imager->errstr;

  $font->align(string => $upper, 
    size => 38, color => "white", 
    x => $width/2, y => $height/3,
    halign => "center", valign => "center",
    image => $img );

  $font->align(string => $lower, 
    size => 38, color => "white", 
    x => $width/2, y => $height*2/3,
    halign => "center", valign => "center",
    image => $img );

  my($dir) = tempdir( CLEANUP => 1 );

  my $img_file = "$dir/c.jpg";

  $img->write(file => $img_file) or 
    die "Cannot write ($!)";

  for (1..$n-1) {
      cd $dir;
      (my $link = $img_file) =~ s/\./$_./;
      link $img_file, $link or die $!;
      cdback;
  }

  return $dir;
}

###########################################
sub silent_wav {
###########################################
  my($secs, $outfile, $rate, $channels, 
     $sample_size) = @_;

  my($fh, $tempfile) = 
    tempfile( UNLINK => 1, 
              SUFFIX => ".dat" );

  print $fh "; SampleRate $rate\n";
  my $samples = $secs * $rate;

  for (my $i = 0; ($i < $samples); $i++) {
      print $fh $i / $rate, "\t0\n";
  }
  close $fh;

  shell "sox", $tempfile, "-r", $rate, 
        "-u", "-$sample_size", "-c", 
        $channels, $outfile;
}
