diff options
author | Jarle Bjørgeengen <jarle@bjorgeengen.net> | 2011-02-17 06:19:00 +0000 |
---|---|---|
committer | Jarle Bjørgeengen <jarle@bjorgeengen.net> | 2011-02-17 06:19:00 +0000 |
commit | 35507f05a99fda66c5e68534c3085e4134ed1abd (patch) | |
tree | c6b070e83f6d35f651d535ca2bf19eff5d454bee | |
parent | 312eb35716a2b0f3b0ac2569c50599392caeab5c (diff) |
slightly modified script for TED videos
-rwxr-xr-x | tools/gen_ted_video.pl | 318 |
1 files changed, 318 insertions, 0 deletions
diff --git a/tools/gen_ted_video.pl b/tools/gen_ted_video.pl new file mode 100755 index 0000000..fa19a8b --- /dev/null +++ b/tools/gen_ted_video.pl @@ -0,0 +1,318 @@ +#!/usr/bin/perl + +# +#title=Radioamatørenes sporingssystem +#presenter=Øyvind Hanssen +#date=2009-03-17 +#place=Oslo +#venue=Høgskolen i Oslo +#url=http://www.nuug.no/ +#organizer=Petter Reinholdtsen +#introduction=Petter Reinholdtsen +#email=sekretariat@nuug.no +#aspect=4:3 +#camera=Stian Hübener, Hans Petter Fjeld +#videomixer=Ole Kristian Lien +#sound=? +#spokenlanguage=no +# +# PS: IF this script is used on an sshfs mounted filesystem, the option sshfs -o workaround=rename must be used . +# If not, normalize-audio will just silently fail and no audio normalization will take place. + +use strict; +use warnings; + +use Data::Dumper; +use Getopt::Std; + +my %opts; +my $intro_length = 10; +my $pid = $$; + +getopts('di:m:o:b:s:S:', \%opts); +my $debug = $opts{d} || 0; +my $workdir = "./fk-temp-$pid"; +#my $startposter = "$workdir/startposter.png"; +my $startposter = "$workdir/startposter.jpg"; +#my $endposter = "$workdir/endposter.png"; +my $endposter = "$workdir/endposter.jpg"; +my $startposter_dv = "$workdir/startposter.dv"; +my $endposter_dv = "$workdir/endposter.dv"; +my $metafile; +my $srcfile; +my $srtfile; +my $bgfile; +my $outputfile; +my $normalize_cmd = "/usr/bin/normalize-audio"; +# http://normalize.nongnu.org/ +my $soundlevel_dbfs = '-18dBFS'; + +#foreach (keys %opts ) { print "$_\n"; }; +if ( $opts{'m'} ) { + $metafile = $opts{'m'} ; +} else { + usage(); + exit 1; +} + +my $meta = read_meta(); + +if ( $opts{'b'} ) { + $bgfile = $opts{'b'} ; +} else { + usage(); + exit 1; +} + + +`mkdir -p $workdir`; + +if ( $ARGV[0] && $ARGV[0] eq 'front' ) { + create_startposter_png($startposter,$bgfile); + print "Frontpage in $startposter\n"; + print "Check it out !\n"; + exit ; +} + +if ( $opts{'o'} ) { + $outputfile = $opts{'o'} ; +} else { + usage(); + exit 1; +} + +if ( $opts{'i'} ) { + $srcfile = $opts{'i'} ; +} else { + usage(); + exit 1; +} +my $subdelay = ""; + +if ( $opts{'s'} ) { + $srtfile = getsrtfile(); + if ( ! -f $srtfile ) { + print "$srtfile does not exist\n"; + exit 1 ; + } + if ( $opts{'S'} ) { + $subdelay = "-subdelay $opts{'S'}"; + } +} + + + + +#create_startposter_png($startposter,$bgfile); +#create_endposter_png($endposter,$bgfile); +#gen_dv_from_png($startposter,$intro_length,$startposter_dv); +#gen_dv_from_png($endposter,$intro_length,$endposter_dv); +my $normalized_video_body = gen_video_body($srcfile); +glue_dv($opts{'o'},$normalized_video_body,$endposter_dv); + +#### Functions ######### + +sub usage { + print"Usage: $0 -i inputfile.dv -m metafile -o outputfile.avi -b backgroundfile.png [-s /dir/where/srtfiles/are ] \n\n"; + print "If -s is given the script expects a file named <basename_of_raw_file>.srt \n"; + print "located in the path given as arg to -s option\n\n"; +} + +sub read_meta { + my $ret; + + # Set some default values + $ret->{'url'} = 'http://www.nuug.no/'; + $ret->{'email'} = 'sekretariat@nuug.no'; + $ret->{'editor'} = 'Jarle Bjørgeengen'; + + open M, "$metafile" or die "Cannot open $metafile for read :$!"; + while (<M>) { + chomp; + my @l = split("=",$_); + $ret->{$l[0]} = $l[1]; + } + close M; + return $ret; +} + +sub count_words_n_space { + my $word = shift; + my $count = 0; + while ( $word =~ /(.)/g ) { $count++; } + $count++; + return $count; +} + +sub break_title { + my $title = shift; + print $title; + my $cols = 30; + my $count = 0 ; + my $ln = 0; + my @lines; + my @words = split(" ",$title); + foreach my $word (@words) { + $count += count_words_n_space($word); + if ($count < $cols ) { + $lines[$ln] .= "$word "; + } else { + print "$lines[$ln]\n"; + $count = 0; + $ln++; + $count += count_words_n_space($word); + $lines[$ln] .= "$word "; + } + } + return \@lines; +} + +sub create_startposter_png { + my $name = shift; + my $title_lines = break_title($meta->{'title'}); + my $bgfile = shift; + my @cmd = + ("convert", "$bgfile", + "-fill", "white", "-gravity", "NorthWest", + "-pointsize", "36", + "-draw", "\"text 450,167 \'Foreningen NUUG presenterer\'\"", + "-pointsize", "72", + "-draw", "\"text 450,247 \'$meta->{'presenter'}\'\"", + "-pointsize", "60", + "-draw", "\"text 450,380 \'$title_lines->[0]\'\"", + "-draw", "\"text 450,460 \'$title_lines->[1]\'\"", + "-draw", "\"text 450,540 \'$title_lines->[2]\'\"", + "-draw", "\"text 450,620 \'$title_lines->[3]\'\"", + "-pointsize", "36", + "-draw", "\"text 52,790 \'$meta->{'url'}\'\"", + "-draw", "\"text 52,826 \'$meta->{'email'}\'\"", + "-draw", "\"text 750,640 \'$meta->{'place'}, $meta->{'date'}\'\" $name"); + + if ( !runcmd(@cmd) ) { die "Failed to execute system command in" . (caller(0))[3] ."\n"; } +} + +sub create_endposter_png { +# $cmd_body .= " -draw "text $left_margin,$pos \'$n: $meta->{$n}\'" + my %keyword_map = ( + "introduction" => "Introdusert av", + "editor" => "Redaktør", + "venue" => "Lokaler", + "organizer" => "Organisert av", + "camera" => "Kamera", + "sound" => "Lydoppsett", + "videomixer" => "Videomiks", + "teksting" => "Teksting", + ); + my $line_distance = 52; + my $text_size = 40; + my $pos = 180; + my $left_margin = 450; + my $cmd_body = ""; + my @endnotes; + my @endnote_tags = ("introduction","organizer", "venue","camera","sound","videomixer","editor","teksting" ); + foreach my $n ( @endnote_tags ) { + if ($meta->{$n} ) { + +# Only show organizer if introduction and organizer are identical. + next if ("introduction" eq $n && $meta->{$n} eq $meta->{'organizer'}); + + push(@endnotes,"$keyword_map{$n}: $meta->{$n}"); + } + } + foreach my $line ( @endnotes ) { + $cmd_body .= " -draw \"text $left_margin,$pos \'$line \'\""; + $pos += $line_distance; + } + my $name = shift; + my $bgfile = shift; + my @cmd = + ("convert", "$bgfile", + "-pointsize", "$text_size", + "-fill", "white", + "-gravity", "NorthWest", + "$cmd_body", + "-pointsize", "36", + "-draw", "\"text 52,790 \'$meta->{'url'}\'\"", + "-draw", "\"text 52,826 \'$meta->{'email'}\'\"", + "-draw", "\"text 750,640 \'$meta->{'place'}, $meta->{'date'}\'\" $name"); + if ( !runcmd(@cmd) ) { die "Failed to execute system command in" . (caller(0))[3] ."\n"; } +} + +sub gen_dv_from_png { + + my $png_file = shift; + my $length = shift; + my $outputvid = shift; + my $f = "ffmpeg -loop_input -t $length -i $png_file -f image2 -f s16le -i /dev/zero -target pal-dv -padleft 150 -padright 150 -s 420x576 -y $outputvid"; + if ( !runcmd($f) ) { die "Failed to execute system command in" . (caller(0))[3] ."\n"; } +} + +sub gen_video_body { + my $source = shift; + my $mod_dv; + if ( $meta->{'aspect'} eq "4:3" || $opts{'s'} ) { + my $cmd ; + $mod_dv = "$workdir/mod.dv"; + $cmd = "mencoder -oac pcm -of lavf -ovc lavc -lavcopts vcodec=dvvideo:vhq:vqmin=2:vqmax=2:vme=1:keyint=25:vbitrate=2140:vpass=1 "; + if ( $meta->{'aspect'} eq "4:3" ) { + $cmd .= "-vf-add expand=1000::::: -vf-add scale=720:576 "; + } + if ( $srtfile ) { + $cmd .= " -sub $srtfile -utf8 $subdelay -sub-bg-alpha 80 -sub-bg-color 50 -subfont-text-scale 3 -subpos 90 -subwidth 90 "; + } + $cmd .= "-o $mod_dv $source "; + if ( !runcmd($cmd) ) { die "Failed to execute system command in" . (caller(0))[3] ."\n"; } + $source = $mod_dv; + } + my $dest = normalize_sound($source); + return $dest; +} + +sub normalize_sound { + my $dvfile = shift; + my $new_dvfile = "$workdir/normalized-body.dv"; + my $f = "ffmpeg -i $dvfile -ac 2 -vn -f wav -y $workdir/sound.wav"; + if ( !runcmd($f) ) { die "Failed to execute system command in" . (caller(0))[3] ."\n"; } + $f = "$normalize_cmd -a $soundlevel_dbfs $workdir/sound.wav"; + if ( !runcmd($f) ) { die "Failed to execute system command in" . (caller(0))[3] ."\n"; } + $f = "ffmpeg -i $workdir/sound.wav -ac 2 -acodec copy -i $dvfile -vcodec copy -map 1:0 -map 0.0 -f dv -y $new_dvfile"; + if ( !runcmd($f) ) { die "Failed to execute system command in" . (caller(0))[3] ."\n"; } + return $new_dvfile; +} + + +sub glue_dv { + my $outfile = shift; + my $infile = shift; + my $ffmpeg = "ffmpeg -i $infile -aspect 16:9 -acodec pcm_s16le -vcodec dvvideo -y ".$outfile.' -f avi' ; + if ( !runcmd($ffmpeg) ) { die "Failed to execute system command in" . (caller(0))[3] ."\n"; } +# my $cmd = 'cat '.join(' ',@infiles).' | dvgrab -size 0 -stdin -f dv2 -opendml '.$outfile ; +#savetemp(); + if ( -d $workdir ) { + `rm -rf $workdir`; + } +} + + +sub savetemp { + my $outfile_base = $opts{'o'}; + $outfile_base =~ s/.+\.avi$//; + print $outfile_base; + my $f = "mv \"$workdir/startposter.dv\" \"$outfile_base-starposter.dv\""; + if ( !runcmd($f) ) { die "Failed to execute system command in" . (caller(0))[3] ."\n"; } + $f = "mv \"$workdir/endposter.dv\" \"$outfile_base-endposter.dv\""; + if ( !runcmd($f) ) { die "Failed to execute system command in" . (caller(0))[3] ."\n"; } +} + +sub getsrtfile { + $opts{'i'} =~ /.+\/(.+)\..+$/; # Could be .dv or .avi or whatnot. This strips it off anyway. + return "$opts{'s'}/$1.srt"; +} + +sub runcmd { + my $cmd = join(" ", @_); + print "Cmd: $cmd\n" if $debug; + my $f = `$cmd || echo -n -1`; + return 0 if ( $f eq -1 ); + return 1; +} |