Difference between revisions of "Anri-chan/Source/sasami.pl"
From SDA Knowledge Base
(multiple trims mostly done with some caveats, statid totally done except for special cropping (gba etc)) |
(trimming should be totally done - moving to audio now) |
||
(One intermediate revision by the same user not shown) | |||
Line 8: | Line 8: | ||
#system("export DYLD_LIBRARY_PATH=/Volumes/l/anrix"); | #system("export DYLD_LIBRARY_PATH=/Volumes/l/anrix"); | ||
+ | my $really_quiet = ""; | ||
+ | $really_quiet = "-really-quiet"; | ||
#to move to anri config file later | #to move to anri config file later | ||
Line 32: | Line 34: | ||
for (@avs) { | for (@avs) { | ||
chomp; | chomp; | ||
+ | next if m/^#/; | ||
push(@sources,"${1}.VOB") if m/^.*MPEG2source\("(.+)\.d2v".*$/; | push(@sources,"${1}.VOB") if m/^.*MPEG2source\("(.+)\.d2v".*$/; | ||
push(@sources,$1) if m/^.*avisource\("([^"]+)".*$/; | push(@sources,$1) if m/^.*avisource\("([^"]+)".*$/; | ||
Line 53: | Line 56: | ||
} | } | ||
die 'sasami: no sources detected in .avs!' if @sources == 0; | die 'sasami: no sources detected in .avs!' if @sources == 0; | ||
+ | |||
+ | $newframerate = ($pal ? (50/$f) : (59.94/$f)); #required for trimming | ||
@mencoderargslist = (); | @mencoderargslist = (); | ||
− | $previous_sourcelength = 0; | + | my $sourcelength = 0; |
+ | my $previous_sourcelength = 0; | ||
+ | my @trimargsarr = (); | ||
foreach $source (@sources) { | foreach $source (@sources) { | ||
#get vital info about source | #get vital info about source | ||
− | |||
$mplayeridentify = <<SABRAC; | $mplayeridentify = <<SABRAC; | ||
mplayer -identify -vo null -slave ${source} 2>&1 <<ENDOFSCRIPT | mplayer -identify -vo null -slave ${source} 2>&1 <<ENDOFSCRIPT | ||
Line 79: | Line 85: | ||
#build mencoder command to feed fifo | #build mencoder command to feed fifo | ||
− | $mencoderargs = "./mencoder"; | + | $mencoderargs = "./mencoder ${really_quiet}"; |
#trimming | #trimming | ||
Line 85: | Line 91: | ||
# $framerate = 25 if $pal; | # $framerate = 25 if $pal; | ||
− | ### | + | ### BUG: a trim in a later source followed by a trim in an earlier source does not work as expected |
− | + | ||
my $source_intermediate = 1; | my $source_intermediate = 1; | ||
+ | $source_intermediate = 0 if !@trims; | ||
+ | my $ss = 0; | ||
+ | my $sourcecount = 1; #need to immediately cat a source declaration if a trimpoint is identified | ||
+ | my $trimargs = ''; | ||
for (@trims) { | for (@trims) { | ||
m/^(.*),(.*)$/; | m/^(.*),(.*)$/; | ||
if ($1 || $2) { | if ($1 || $2) { | ||
− | $source_intermediate = 0; #for killing trailing unused sources | + | $source_intermediate = 0; #1 for killing trailing unused sources - there are still trim points so don't need to worry about that this time around |
} | } | ||
if ($1) { | if ($1) { | ||
− | $source_intermediate = 1; #this source might have been trimmed out - see if ($2) block below for more | + | if ($1 ne 0) { #no need to do anything if it's the initial frame - unlike in avisynth, mencoder's first trim argument is optional |
− | + | $source_intermediate = 1; #this source might have been trimmed out - see if ($2) block below for more | |
− | + | if ($1 < $sourcelength) { | |
− | + | if ($sourcecount) { | |
+ | push(@trimargsarr, $trimargs) if $trimargs; | ||
+ | $trimargs = ''; | ||
+ | $sourcecount = 0; | ||
+ | } | ||
+ | print "($1 / $framerate) - $previous_sourcelength\n"; | ||
+ | $trimargs .= " -ss ". | ||
+ | ( | ||
+ | $1 - $previous_sourcelength | ||
+ | ) / $framerate; | ||
+ | $ss = ($1 - $previous_sourcelength); #remember how far in we started since -endpos is relative to this | ||
+ | $_ = ",$2"; #wipe this trim point out so we don't accidentally use it twice | ||
+ | $source_intermediate = 0; #this source was not trimmed out | ||
+ | } | ||
+ | } else { | ||
+ | $_ = ",$2"; #wipe this trim point out | ||
$source_intermediate = 0; #this source was not trimmed out | $source_intermediate = 0; #this source was not trimmed out | ||
} | } | ||
Line 105: | Line 129: | ||
if ($2) { | if ($2) { | ||
− | if (!($1)) { | + | if ($2 ne 0) { #no need to do anything if it's final frame - unlike avisynth, mencoder's second trim argument is optional |
− | + | if (!($1)) { | |
− | + | $source_intermediate = 1; #this source was trimmed out | |
− | + | } | |
− | + | if ($2 < $sourcelength) { | |
− | + | #have to insert a conversion factor ($newframerate / $framerate) to handle the fact that the output framerate can differ from the input framerate - -endpos is not based on output framerate while -ss is | |
+ | print "((($2 - $previous_sourcelength) - $ss) / $framerate) * ($newframerate / $framerate)\n"; | ||
+ | $trimargs .= " -endpos ". | ||
+ | ( | ||
+ | ( | ||
+ | ($2 - $previous_sourcelength) - $ss | ||
+ | ) / $framerate | ||
+ | ) | ||
+ | * | ||
+ | ($newframerate / $framerate); | ||
+ | $_ = ","; #wipe this trim point out so we don't accidentally use it twice | ||
+ | $source_intermediate = 0; #this source was not trimmed out | ||
+ | $sourcecount = 1; #this source declaration can't take any more -ss and/or -endpos | ||
+ | } | ||
+ | } else { | ||
+ | $_ = ","; #wipe this trim point out | ||
$source_intermediate = 0; #this source was not trimmed out | $source_intermediate = 0; #this source was not trimmed out | ||
} | } | ||
Line 116: | Line 155: | ||
} | } | ||
− | next if $source_intermediate; | + | $previous_sourcelength = $sourcelength; |
+ | next if $source_intermediate; #this source was trimmed out entirely | ||
+ | push(@trimargsarr, $trimargs) if $trimargs; #in case we had no complete trims | ||
#one pixel bob | #one pixel bob | ||
Line 153: | Line 194: | ||
} | } | ||
− | |||
$x264newframerate = "--fps ${newframerate}"; | $x264newframerate = "--fps ${newframerate}"; | ||
$mp4boxnewframerate = "-fps ${newframerate}"; | $mp4boxnewframerate = "-fps ${newframerate}"; | ||
Line 164: | Line 204: | ||
$mencoderargs .= " -vf-add format=i420 -ovc raw -of rawvideo -nosound"; | $mencoderargs .= " -vf-add format=i420 -ovc raw -of rawvideo -nosound"; | ||
− | $ | + | my $mencoderargstemp = ''; |
− | + | while (my $trimargs = shift(@trimargsarr)) { | |
+ | $mencoderargstemp .= $mencoderargs." ${source}".$trimargs." -o ${avs}\n"; | ||
+ | } | ||
+ | $mencoderargs = $mencoderargstemp; | ||
push(@mencoderargslist,$mencoderargs); | push(@mencoderargslist,$mencoderargs); | ||
− | |||
} | } | ||
Line 189: | Line 231: | ||
} | } | ||
close(MF); | close(MF); | ||
− | $statidmencoderargs = "./mencoder -vf-add scale=${newwidth}:${newheight} -vf-add format=i420 -ovc raw -of rawvideo -nosound -ofps ${newframerate} mf://\@statid.txt -mf fps=${newframerate}:type=tga -o ${avs}"; | + | $statidmencoderargs = "./mencoder ${really_quiet} -vf-add scale=${newwidth}:${newheight} -vf-add format=i420 -ovc raw -of rawvideo -nosound -ofps ${newframerate} mf://\@statid.txt -mf fps=${newframerate}:type=tga -o ${avs}"; |
} | } | ||
} | } |
Latest revision as of 14:08, 18 October 2008
#!/usr/bin/perl #nathan jahnke <njahnke@gmail.com> use warnings; use strict 'subs'; package sasami; #system("export DYLD_LIBRARY_PATH=/Volumes/l/anrix"); my $really_quiet = ""; $really_quiet = "-really-quiet"; #to move to anri config file later $gba_crop_left = 43; $gba_crop_top = 39; $gba_crop_right = 44; $gba_crop_bottom = 41; $gb_crop_left = 80; $gb_crop_top = 48; $gb_crop_right = 80; $gb_crop_bottom = 48; sub pipe_prepare($) { $basename = shift; $avs = "${basename}.pipe"; system("rm ${avs}") if -e $avs; system("mkfifo ${avs}"); open(AVS, "${basename}.avs"); #must be unix text when running sasami under unix ... @avs = <AVS>; close(AVS); @sources = (); @trims = (); for (@avs) { chomp; next if m/^#/; push(@sources,"${1}.VOB") if m/^.*MPEG2source\("(.+)\.d2v".*$/; push(@sources,$1) if m/^.*avisource\("([^"]+)".*$/; push(@sources,$1) if m/^.*directshowsource\("([^"]+)".*$/; $fieldorder = 1 if m/^AssumeTFF\(\)/; $fieldorder = 0 if m/^AssumeBFF\(\)/; $d = 1 if m/^global d1 = true/; $d = 4 if m/^global d1 = false/; $f = $1 if m/^changefps\(f1\/([0-9])\)/; $deflicker = 1 if m/^nate_retard_bob_2/; $vhs = 1 if m/^nate_vhs_head_change_erase/; $onepixel = 1 if m/^nate_1_pixel_bob_fix/; $nes = 1 if m/^nate_nes$/; push(@trims,"$1,$2") if m/trim\(([0-9]+),([0-9]+)\)/; $gba = 1 if m/^nate_gba$/; $gb = 1 if m/^nate_gb$/; $resize = 1 if m/^lanczos4resize\(d1,last\.height\)/; $statidlines[0] = $1 if m/^statid1="""(.*)"""$/; $statidlines[1] = $1 if m/^statid2="""(.*)"""$/; $statidlines[2] = $1 if m/^statid3="""(.*)"""$/; } die 'sasami: no sources detected in .avs!' if @sources == 0; $newframerate = ($pal ? (50/$f) : (59.94/$f)); #required for trimming @mencoderargslist = (); my $sourcelength = 0; my $previous_sourcelength = 0; my @trimargsarr = (); foreach $source (@sources) { #get vital info about source $mplayeridentify = <<SABRAC; mplayer -identify -vo null -slave ${source} 2>&1 <<ENDOFSCRIPT quit ENDOFSCRIPT SABRAC for (qx($mplayeridentify)) { chomp; $width = $_ if s/ID_VIDEO_WIDTH=([0-9]+)/$1/; $height = $_ if s/ID_VIDEO_HEIGHT=([0-9]+)/$1/; $framerate = $_ if s/ID_VIDEO_FPS=([0-9.]+)/$1/; $maxaudiobitrate = $_ if s/ID_AUDIO_BITRATE=([0-9]+)/$1/; $sourcelength += ($framerate * $_) if s/ID_LENGTH=([0-9.]+)/$1/; } # print "$width\n"; # print "$height\n"; # print "$framerate\n"; # print "$maxaudiobitrate\n"; $pal = ($height eq "576"); #build mencoder command to feed fifo $mencoderargs = "./mencoder ${really_quiet}"; #trimming # $framerate = 29.97; # $framerate = 25 if $pal; ### BUG: a trim in a later source followed by a trim in an earlier source does not work as expected my $source_intermediate = 1; $source_intermediate = 0 if !@trims; my $ss = 0; my $sourcecount = 1; #need to immediately cat a source declaration if a trimpoint is identified my $trimargs = ''; for (@trims) { m/^(.*),(.*)$/; if ($1 || $2) { $source_intermediate = 0; #1 for killing trailing unused sources - there are still trim points so don't need to worry about that this time around } if ($1) { if ($1 ne 0) { #no need to do anything if it's the initial frame - unlike in avisynth, mencoder's first trim argument is optional $source_intermediate = 1; #this source might have been trimmed out - see if ($2) block below for more if ($1 < $sourcelength) { if ($sourcecount) { push(@trimargsarr, $trimargs) if $trimargs; $trimargs = ''; $sourcecount = 0; } print "($1 / $framerate) - $previous_sourcelength\n"; $trimargs .= " -ss ". ( $1 - $previous_sourcelength ) / $framerate; $ss = ($1 - $previous_sourcelength); #remember how far in we started since -endpos is relative to this $_ = ",$2"; #wipe this trim point out so we don't accidentally use it twice $source_intermediate = 0; #this source was not trimmed out } } else { $_ = ",$2"; #wipe this trim point out $source_intermediate = 0; #this source was not trimmed out } } if ($2) { if ($2 ne 0) { #no need to do anything if it's final frame - unlike avisynth, mencoder's second trim argument is optional if (!($1)) { $source_intermediate = 1; #this source was trimmed out } if ($2 < $sourcelength) { #have to insert a conversion factor ($newframerate / $framerate) to handle the fact that the output framerate can differ from the input framerate - -endpos is not based on output framerate while -ss is print "((($2 - $previous_sourcelength) - $ss) / $framerate) * ($newframerate / $framerate)\n"; $trimargs .= " -endpos ". ( ( ($2 - $previous_sourcelength) - $ss ) / $framerate ) * ($newframerate / $framerate); $_ = ","; #wipe this trim point out so we don't accidentally use it twice $source_intermediate = 0; #this source was not trimmed out $sourcecount = 1; #this source declaration can't take any more -ss and/or -endpos } } else { $_ = ","; #wipe this trim point out $source_intermediate = 0; #this source was not trimmed out } } } $previous_sourcelength = $sourcelength; next if $source_intermediate; #this source was trimmed out entirely push(@trimargsarr, $trimargs) if $trimargs; #in case we had no complete trims #one pixel bob if ($onepixel) { $mencoderargs .= " -vf-add crop=${width}:".($height-1).":0:0,expand=${width}:${height}:0:1"; $fieldorder = 0 if $fieldorder == 1; $fieldorder = 1 if $fieldorder == 0; } #nes $mencoderargs .= " -vf-add crop=".($width-8).":${height}:8:0,expand=${width}:${height}:8:0" if $nes; #-af channels=6:4:0:0:0:1:0:2:0:3 media.avi #Would change the number of channels to 6 and set up 4 routes that copy channel 0 to channels 0 to 3. Channel 4 and 5 will contain silence. $mencoderargs .= " -vf-add yadif=3 -vf-add mcdeint=1:${fieldorder}" if $d == 1; $tfields = 0; $tfields = 4 if $deflicker; $mencoderargs .= " -vf-add tfields=${tfields}" if $d == 4; #i just eyeballed this - someone will need to sync the avisynth and mencoder sharpen filters $mencoderargs .= " -vf-add unsharp=l3x3:0.6:c3x3:0.6" if $deflicker; $mencoderargs .= " -vf-add crop=${width}:".($height-12).":0:0,expand=0:-12:0:0" if $vhs; if ($gba) { $mencoderargs .= " -vf-add scale=320:240"; $mencoderargs .= " -vf-add crop=".(320-$gba_crop_right-$gba_crop_left).":".(240-$gba_crop_bottom-$gba_crop_top).":${gba_crop_left}:${gba_crop_top}"; $mencoderargs .= " -vf-add scale=240:160"; $newwidth = 240; $newheight = 160; } elsif ($gb) { $mencoderargs .= " -vf-add scale=320:240"; $mencoderargs .= " -vf-add crop=".(320-$gb_crop_right-$gb_crop_left).":".(240-$gb_crop_bottom-$gb_crop_top).":${gb_crop_left}:${gb_crop_top}"; $newwidth = (320-$gb_crop_right-$gb_crop_left); $newheight = (240-$gb_crop_bottom-$gb_crop_top); } $x264newframerate = "--fps ${newframerate}"; $mp4boxnewframerate = "-fps ${newframerate}"; $mencoderargs .= " -vf-add framestep=${f}"; $newwidth = (($d == 1) ? ($pal ? 704 : 640) : ($pal ? 352 : 320)) unless $newwidth; $newheight = (($d == 1) ? ($pal ? 576 : 480) : ($pal ? 288 : 240)) unless $newheight; $mencoderargs .= " -vf-add scale=${newwidth}:${newheight}" if $resize; $mencoderargs .= " -vf-add format=i420 -ovc raw -of rawvideo -nosound"; my $mencoderargstemp = ''; while (my $trimargs = shift(@trimargsarr)) { $mencoderargstemp .= $mencoderargs." ${source}".$trimargs." -o ${avs}\n"; } $mencoderargs = $mencoderargstemp; push(@mencoderargslist,$mencoderargs); } if (defined $statidlines[0]) { use Imager; $img = Imager->new; $img->read(file=>"ntsc_d1.tga") or die "Cannot load statid image: ", $img->errstr; $font = Imager::Font->new(file=>"/Library/Fonts/Verdana.ttf"); #will need to be changed for non-mac unix ... &statid_lines_write($statidlines[0], $img->getheight/2, 36, 'white' ) if defined $statidlines[0]; &statid_lines_write($statidlines[1], 360, 36, 'white' ) if defined $statidlines[1]; &statid_lines_write($statidlines[2], 400, 36, 'white' ) if defined $statidlines[2]; &statid_lines_write("Audio commentary on track 2", 460, 28, '#E1CE8B') if defined $audio_commentary; $img->write(file=>'statid.tga') or die 'Cannot save statid.tga: ', $img->errstr; open(MF,">statid.txt") or die "Could not open statid.txt for appending!"; for (1..5) { #once for each second of the statid for (1..$newframerate) { #once for each frame this second print MF "statid.tga\n"; } } close(MF); $statidmencoderargs = "./mencoder ${really_quiet} -vf-add scale=${newwidth}:${newheight} -vf-add format=i420 -ovc raw -of rawvideo -nosound -ofps ${newframerate} mf://\@statid.txt -mf fps=${newframerate}:type=tga -o ${avs}"; } } sub pipe_write { open(FIFO,">${avs}"); print("$statidmencoderargs\n") if defined $statidlines[0]; system($statidmencoderargs) if defined $statidlines[0]; for (@mencoderargslist) { print("$_\n"); system($_); } print("$statidmencoderargs\n") if defined $statidlines[0]; system($statidmencoderargs) if defined $statidlines[0]; close(FIFO); } $basename='pokemon'; #remove in anri for(my $N = 1; $N <= 2 ; $N++) { &pipe_prepare($basename);# if $os eq 'unix'; #replace with $_[4] or whatever if ($N == 2) { # this is a hack to deal with the fact that sometimes x264 takes a while to finish encoding and write out the statsfile - thanks grenola! while (!(-e "${basename}.stats")) { print("Waiting for stats file ...\n"); sleep(1); } } $x264command = "./x264 --pass ${N} --stats ${basename}.stats --bitrate 5000 --qpmin 0 ${x264newframerate} -o ${basename}.264 ${avs} ${newwidth}x${newheight} &"; print("$x264command\n"); system($x264command); &pipe_write; } $mp4boxcommand = "./mp4box ${mp4boxnewframerate} -new -add ${basename}.264 ${basename}.mp4"; print ("$mp4boxcommand\n"); system($mp4boxcommand); exit 0; #statid line text, y-offset, text size, color sub statid_lines_write { $font->align(string => $_[0], aa => 1, size => $_[2], color => $_[3], x => $img->getwidth/2, y => $_[1], halign => 'center', valign => 'center', image => $img); }