1 # Author: Martin Matusiak <numerodix@gmail.com>
2 # Licensed under the GNU Public License, version 3.
12 our @EXPORT_OK = qw($suite $defaults $tools);
31 examine_dvd_for_titlecount
48 # autoflush write buffer globally
54 tool_name
=> basename
(resolve_symlink
($0)),
62 dvd_device
=> "/dev/dvd",
63 disc_image
=> "disc.iso",
64 mencoder_source
=> "disc.iso",
66 framesize_baseline
=> 720*576*(2/3)^2, # frame size in pixels
68 h264_1pass_bpp
=> .195,
69 h264_2pass_bpp
=> .150,
71 xvid_1pass_bpp
=> .250,
72 xvid_2pass_bpp
=> .200,
77 postscale
=> ",harddup",
81 my @videoutils = qw(lsdvd mencoder mplayer);
82 my @shellutils = qw(awk bash bc grep egrep getopt mount ps sed xargs);
83 my @coreutils = qw(cat date dd dirname head mkdir mv nice readlink rm seq sleep sort tail tr true);
84 my @extravideoutils = qw(mp4creator mkvmerge ogmmerge vobcopy);
86 my @mencoder_acodecs = qw(copy faac lavc mp3lame);
87 my @mencoder_vcodecs = qw(copy lavc x264 xvid);
89 my @mplayer_acodecs = qw(ac3);
90 my @mplayer_vcodecs = qw(mpeg-2);
106 while ($s =~ m/(%%%.*?%%%)/g) {
107 $ms .= $p->(substr($s, 0, @
-[0]));
109 $s = substr($s, @
+[0]);
114 print $p->("Error:") . " $ms\n";
125 my ($width, $side, $s, $fill) = @_;
127 my $trunc_len = length($s) - $width;
128 $s = substr($s, 0, $width);
130 substr($s, length($s) - length($fill), length($fill), $fill)
131 if (($trunc_len > 0) and $fill);
133 my $pad_len = abs($width - length($s));
134 my $pad = " " x
$pad_len;
136 $s = $pad . $s if $side == -1;
137 $s = $s . $pad if $side == 1;
145 foreach my $this (@these) {
146 if (ref $this eq "ARRAY") {
147 print "\ndump: ".join(" , ", @
$this)."\n";
150 print "\n".Dumper
($this);
156 sub resolve_symlink
{
157 return (grep(-l
, $_[0]) ?
readlink $_[0] : $_[0]);
165 } elsif (ref $this eq "ARRAY") {
166 [map deep_copy
($_), @
$this];
167 } elsif (ref $this eq "HASH") {
168 +{map { $_ => deep_copy
($this->{$_}) } keys %$this};
169 } else { die "what type is $_?" }
173 # create directory for logging
175 if (! -e
$defaults->{logdir
} and ! mkdir($defaults->{logdir
})) {
176 fatal
("Could not write to %%%$ENV{PWD}%%%, exiting");
177 } elsif (-e
$defaults->{logdir
} and ! -w
$defaults->{logdir
}) {
178 fatal
("Logging directory %%%".$defaults->{logdir
}."%%% is not writable");
186 foreach my $dir (split(":", $ENV{PATH
})) {
187 return ("$dir/$bin", 0) if (-x
"$dir/$bin");
192 # launch command waiting for output and exit
194 my ($args, $nowait) = @_;
196 print STDERR
join(' ', @
$args)."\n" if $ENV{"DEBUG"};
200 my($writer, $reader, $error);
201 my $pid = open3
($writer, $reader, $error, @
$args);
204 return ($pid, $reader, $error);
207 # read from pipes as output comes
208 my ($out, $exit, $err);
209 while ((my $stdout = <$reader>) or (my $stderr = <$error>)) {
214 # wait for pid and capture exit value
221 return ($out, $exit, $err);
224 # aggregate invocation results
226 my ($invokes, $logfile) = @_;
229 open($fh_logfile, ">", $logfile);
232 foreach my $args (@
$invokes) {
233 my ($o, $x, $e) = run
($args);
235 print $fh_logfile join(" ", @
$args)."\n";
236 print $fh_logfile $o.$e."\n";
244 # check for missing dependencies
248 print " * Checking for tool support...\n" if $verbose;
249 foreach my $tool (@videoutils, @shellutils, @coreutils, @extravideoutils) {
250 my ($tool_path, $exit) = which
($tool);
251 $tools->{$tool} = $tool_path;
253 print " " . s_ok
("*") . " $tool_path\n" if $verbose;
255 print " " . s_wa
("*") . " $tool missing\n" if $verbose;
265 print " * Checking for $tool $type codec support...\n";
267 unshift(@args, $tools->{$tool});
268 my ($out, $exit, $err) = run
(\
@args);
269 foreach my $codec (@
$codecs) {
270 if ($out . $err =~ /$codec/i) {
271 print " " . s_ok
("*") . " $codec\n";
273 print " " . s_wa
("*") . " $codec missing\n";
279 codec_check
("audio", \
@mplayer_acodecs, "mplayer", qw(-ac help));
280 codec_check
("video", \
@mplayer_vcodecs, "mplayer", qw(-vc help));
281 codec_check
("audio", \
@mencoder_acodecs, "mencoder", qw(-oac help));
282 codec_check
("video", \
@mencoder_vcodecs, "mencoder", qw(-ovc help));
286 # print standard common banner
287 sub print_tool_banner
{
288 print "{( --- " . $suite->{tool_name
} . " " . $suite->{version
} . " --- )}\n";
291 # print package version and versions of tools
298 my ($tool_path, $exit) = which
($tool);
300 print " [" . s_err
("!") . "] $tool missing\n";
302 unshift(@args, $tool_path);
303 my ($out, $exit, $err) = run
(\
@args);
304 my $version = $1 if ($out . $err) =~ /$re/ms;
305 print " [" . s_ok
("*") . "] $tool $version\n";
308 print $suite->{name
} . " " . $suite->{version
} . "\n";
309 check_tool
("mplayer", "^MPlayer ([^ ]+)", qw());
310 check_tool
("mencoder", "^MEncoder ([^ ]+)", qw(-oac help));
311 check_tool
("lsdvd", "^lsdvd ([^ ]+)", qw(-V));
312 check_tool
("vobcopy", "^Vobcopy ([^ ]+)", qw(--version));
313 check_tool
("mp4creator", ".* version ([^ ]+)", qw(-version));
314 check_tool
("mkvmerge", "^mkvmerge ([^ ]+)", qw(--version));
315 check_tool
("ogmmerge", "^ogmmerge ([^ ]+)", qw(--version));
319 # compute bits per pixel
325 my $video_size = shift; # in mb
326 my $bitrate = shift; # kbps
329 $bitrate = $bitrate * 1024;
331 $video_size = $video_size * 1024 * 1024;
332 $bitrate = (8 * $video_size)/( $length != 0 ?
$length : 1 );
334 my $bpp = ($bitrate)/( $width*$height*$fps != 0 ?
$width*$height*$fps : 1);
339 # set bpp based on the codec and number of passes
341 my ($video_codec, $passes) = @_;
344 if ($video_codec eq "h264") {
345 $bpp = $defaults->{h264_1pass_bpp
} if $passes == 1;
346 $bpp = $defaults->{h264_2pass_bpp
} if $passes > 1;
348 $bpp = $defaults->{xvid_1pass_bpp
} if $passes == 1;
349 $bpp = $defaults->{xvid_2pass_bpp
} if $passes > 1;
355 # set the number of passes based on codec and bpp
357 my ($video_codec, $bpp) = @_;
360 if ($video_codec eq "h264") {
361 $passes = 2 if $bpp < $defaults->{h264_1pass_bpp
};
363 $passes = 2 if $bpp < $defaults->{xvid_1pass_bpp
};
369 # compute video bitrate based on title length
370 sub compute_vbitrate
{
371 my ($width, $height, $fps, $bpp) = @_;
373 my $bitrate = int( ($width * $height * $fps * $bpp) / 1024);
378 # prepend with int key if int, otherwise with string key
379 sub ternary_int_str
{
380 my ($value, $int_key, $str_key) = @_;
383 if ($value =~ /^[0-9]+$/) {
384 push(@args, $int_key, $value);
386 push(@args, $str_key, $value);
392 # clone disc to iso image
394 my ($dvd_device, $img) = @_;
396 my @args = ("time", "nice", "-n20");
397 push(@args, $tools->{dd
}, "if=$dvd_device", "of=$img.partial");
399 my $exit = run_agg
(\
@a, $defaults->{logdir
} . "/clone.log");
404 rename("$img.partial", $img);
409 # clone encrypted disc to directory
411 my ($dvd_device, $dir) = @_;
413 $dvd_device = resolve_symlink
($dvd_device);
415 my @args = ($tools->{mount
});
416 my ($mount_table, $exit, $err) = run
(\
@args);
419 fatal
("Failed to lookup mount table");
422 my $mnt_point = (map { /$dvd_device on ([^ ]+)/ } split('\n', $mount_table))[0];
425 print "\n" . s_wa
("=>") . " Your dvd device " . s_bb
($dvd_device)
426 . " has to be mounted for this.\n";
427 print s_wa
("=>") . " Mount the dvd and supply the device to " .
428 $suite->{tool_name
} . ", eg:\n";
429 print " " . s_b
("sudo mount") . " " . s_bb
($dvd_device) . " " .
430 s_b
("/mnt/dvd") . " " . s_b
("-t") . " " . s_b
("iso9660") . "\n";
431 print " " . s_b
($suite->{tool_name
}) . " " . s_b
("-d") . " " .
432 s_bb
($dvd_device) . " [" . s_b
("other options") . "]\n";
441 my @args = ("time", "nice", "-n20");
442 push(@args, $tools->{vobcopy
}, "-f", "-l", "-m", "-F", "64");
443 push(@args, "-i", $mnt_point, "-t", $dir);
446 my $exit = run_agg
(\
@a, $defaults->{logdir
} . "/clone.log");
451 # extract number of titles from dvd
452 sub examine_dvd_for_titlecount
{
455 my @args = ($tools->{mplayer
}, "-ao", "null", "-vo", "null");
456 push(@args, "-frames", "0", "-identify");
457 push(@args, "-dvd-device", $source, "dvd://");
459 my ($out, $exit, $err) = run
(\
@args);
460 my $titles = $1 if ($out . $err) =~ /^ID_DVD_TITLES=([^\s]+)/ms;
465 # extract information from file or dvd title
468 my $dvd_device = shift;
470 my @source = ($file);
472 push (@source, "-dvd-device", $dvd_device);
474 my @args = ($tools->{mplayer
}, "-ao", "null", "-vo", "null");
475 push(@args, "-frames", "0", "-identify");
476 push(@args, @source);
478 my ($out, $exit, $err) = run
(\
@args);
485 my @match = map { /^${re}$/ } split('\n', $s);
487 @match = sort {$b <=> $a} @match;
488 return shift(@match);
489 } else { return $default; }
495 width
=> find
(0, $s, "ID_VIDEO_WIDTH=(.+)"),
496 height
=> find
(0, $s, "ID_VIDEO_HEIGHT=(.+)"),
497 fps
=> find
(0, $s, "ID_VIDEO_FPS=(.+)"),
498 length => find
(0, $s, "ID_LENGTH=(.+)"),
499 abitrate
=> find
(0, $s, "ID_AUDIO_BITRATE=(.+)"),
500 aformat
=> lc(find
(0, $s, "ID_AUDIO_CODEC=(.+)")),
501 vbitrate
=> find
(0, $s, "ID_VIDEO_BITRATE=(.+)"),
502 vformat
=> lc(find
(0, $s, "ID_VIDEO_FORMAT=(.+)")),
505 $data->{abitrate
} = int($data->{abitrate
} / 1024); # to kbps
506 $data->{vbitrate
} = int($data->{vbitrate
} / 1024); # to kbps
507 $data->{bpp
} = compute_bpp
($data->{width
}, $data->{height
}, $data->{fps
},
508 $data->{len
}, 0, $data->{vbitrate
});
511 $data->{filesize
} = int(
512 ($data->{abitrate
} + $data->{vbitrate
}) * $data->{length} / 8 / 1024);
514 $data->{filesize
} = int( (stat($file))[7] / 1024 / 1024 );
520 # estimate cropdetect duration
522 my ($length, $fps) = @_;
524 return int($length * $fps / 250 / 60);
527 # figure out how much to crop
529 my ($file, $dvd_device) = @_;
531 my @source = ($file);
533 push (@source, "-dvd-device", $dvd_device);
535 my @args = ($tools->{mplayer
}, "-quiet", "-ao", "null", "-vo", "null");
536 push(@args, "-fps", "10000", "-vf", "cropdetect");
537 push(@args, @source);
539 my ($out, $exit, $err) = run
(\
@args);
541 my @cropdata = map { /^(\[CROP\].*)$/ } split("\n", $out . $err);
542 my $cropline = pop(@cropdata);
544 my ($w, $h, $x, $y) =
545 map { /-vf crop=([0-9]+):([0-9]+):([0-9]+):([0-9]+)/ } $cropline;
547 my $cropfilter = "crop=$w:$h:$x:$y,";
549 return ($w, $h, $cropfilter);
552 # set formatting of bpp output depending on value
555 my $video_codec = shift;
557 if (($video_codec =~ "(h264|avc)")) {
558 if ($bpp < $defaults->{h264_2pass_bpp
}) {
560 } elsif ($bpp > $defaults->{h264_1pass_bpp
}) {
565 } elsif (($video_codec =~ "xvid")) {
566 if ($bpp < $defaults->{xvid_2pass_bpp
}) {
568 } elsif ($bpp > $defaults->{xvid_1pass_bpp
}) {
580 # print one line of title display, whether header or not
581 sub print_title_line
{
582 my $is_header = shift;
585 my ($dim, $fps, $length, $bpp, $passes, $vbitrate, $vformat, $abitrate, $aformat);
586 my ($filesize, $filename);
594 $vbitrate = "vbitrate";
596 $abitrate = "abitrate";
601 my $x = $data->{width
} > 0 ?
$data->{width
} : "";
602 my $y = $data->{height
} > 0 ?
$data->{height
} : "";
603 $dim = $x."x".$y ne "x" ?
$x."x".$y : "";
604 $fps = $data->{fps
} > 0 ?
$data->{fps
} : "";
605 $length = $data->{length} > 0 ?
int($data->{length} / 60) : "";
606 $bpp = $data->{bpp
} > 0 ?
$data->{bpp
} : "";
607 $passes = $data->{passes
} > 0 ?
$data->{passes
} : "";
608 $vbitrate = $data->{vbitrate
} > 0 ?
$data->{vbitrate
} : "";
609 $vformat = $data->{vformat
} ne "0" ?
$data->{vformat
} : "";
610 $abitrate = $data->{abitrate
} > 0 ?
$data->{abitrate
} : "";
611 $aformat = $data->{aformat
} ne "0" ?
$data->{aformat
} : "";
612 $filesize = $data->{filesize
};
613 $filename = $data->{filename
};
616 $dim = trunc
(9, -1, $dim);
617 $fps = trunc
(6, -1, $fps);
618 $length = trunc
(3, -1, $length);
619 $bpp = trunc
(5, 1, $bpp);
620 $passes = trunc
(1, -1, $passes);
621 $vbitrate = trunc
(4, -1, $vbitrate);
622 $vformat = trunc
(4, -1, $vformat);
623 $abitrate = trunc
(4, -1, $abitrate);
624 $aformat = trunc
(4, -1, $aformat);
625 $filesize = trunc
(4, -1, $filesize);
627 if ($filename =~ /dvd:\/\
//) {
628 $filesize = s_est
($filesize);
631 $bpp = markup_bpp
($bpp, $vformat) unless $is_header;
633 my $line = "$dim $fps $length $bpp $passes $vbitrate $vformat "
634 . "$abitrate $aformat $filesize $filename";
635 $line = s_b
($line) if $is_header;
639 # compute title scaling
641 my ($width, $height, $custom_scale) = @_;
643 my ($nwidth, $nheight) = ($width, $height);
645 if ($custom_scale ne "off") { # scaling isn't disabled
647 # scale to the width given by user (upscaling permitted)
652 if ($custom_scale =~ /^([0-9]+)$/) {
654 } elsif ($custom_scale =~ /^([0-9]*):([0-9]*)$/) {
655 ($nwidth, $nheight) = ($1, $2);
657 fatal
("Failed to read a pair of positive integers from scaling "
658 . "%%%$custom_scale%%%");
661 if ( $nwidth > 0 and ! $nheight > 0) {
662 $nheight = int($height * $nwidth / ($width > 0 ?
$width : 1) );
663 } elsif (! $nwidth > 0 and $nheight > 0) {
664 $nwidth = int($width * $nheight / ($height > 0 ?
$height : 1) );
667 # apply default scaling heuristic
669 # compute scaling factor based on baseline value
670 my $framesize = $width*$height > 0 ?
$width*$height : 1;
671 my $factor = sqrt($defaults->{framesize_baseline
}/$framesize);
673 # scale by factor, do not upscale
675 $nwidth = int($width*$factor);
676 $nheight = int($height*$factor);
680 # dimensions have been changed, make sure they are multiples of 16
681 ($nwidth, $nheight) = scale_by_x
($width, $height, $nwidth, $nheight);
683 # make sure the new dimensions are sane
684 if ($nwidth * $nheight <= 0) {
685 ($nwidth, $nheight) = ($width, $height);
689 return ($nwidth, $nheight);
692 # scale dimensions to nearest (lower/upper) multiple of 16
694 my ($orig_width, $orig_height, $width, $height) = @_;
697 # if the original dimensions are not multiples of 16, no amount of scaling
698 # will bring us to an aspect ratio where the smaller dimensions are
699 if (($orig_width % $divisor) + ($orig_height % $divisor) != 0) {
700 $width = $orig_width;
701 $height = $orig_height;
705 while (! $completed) {
708 my $up_step = $width + ($step * $divisor);
709 my $down_step = $width - ($step * $divisor);
710 foreach my $x_step ($up_step, $down_step) {
711 my $x_width = int($x_step - ($x_step % $divisor));
712 my $x_height = int($x_width *
713 ($orig_height/ ($orig_width > 0 ?
$orig_width : 1) ));
714 if (($x_width % $divisor) + ($x_height % $divisor) == 0) {
723 return ($width, $height);
726 # compute size of media given length and bitrate
727 sub compute_media_size
{
728 my ($length, $bitrate) = @_;
729 return ($bitrate / 8) * ($length / 1024);
732 # get container options and decide on codecs
733 sub set_container_opts
{
734 my ($acodec, $vcodec, $container) = @_;
736 my $audio_codec = "mp3";
737 my $video_codec = "h264";
741 if ($container =~ /(avi|mkv|ogm)/) {
742 } elsif ($container eq "mp4") {
743 $audio_codec = "aac";
744 $video_codec = "h264";
748 if ($container =~ "(asf|au|dv|flv|ipod|mov|mpg|nut|rm|swf)") {
750 @opts = ("lavf", "-lavfopts", "format=$container");
752 if ($container eq "flv") {
753 $audio_codec = "mp3";
754 $video_codec = "flv";
757 fatal
("Unrecognized container %%%$container%%%");
761 $audio_codec = $acodec if $acodec;
762 $video_codec = $vcodec if $vcodec;
764 return ($audio_codec, $video_codec, $ext, @opts);
767 # get audio codec options
768 sub set_acodec_opts
{
769 my ($container, $codec, $orig_bitrate, $get_bitrate) = @_;
772 if ($container eq "flv"){
773 push(@opts, "-srate", "44100"); # flv supports 44100, 22050, 11025
777 if ($codec eq "copy") {
778 $bitrate = $orig_bitrate;
779 unshift(@opts, "copy");
780 } elsif ($codec eq "mp3") {
782 unshift(@opts, "mp3lame", "-lameopts", "vbr=3:abr=$bitrate:q=3");
783 } elsif ($codec eq "aac") {
785 unshift(@opts, "faac", "-faacopts", "br=$bitrate:mpeg=4:object=2",
790 $bitrate = 224; # mencoder manpage default
791 my $cs = "ac3|flac|g726|libamr_nb|libamr_wb|mp2|roq_dpcm|sonic|sonicls|"
792 . "vorbis|wmav1|wmav2";
793 if ($codec =~ /($cs)/) {
794 unshift(@opts, "lavc", "-lavcopts",
795 "abitrate=$bitrate:acodec=$codec");
797 fatal
("Unrecognized audio codec %%%$codec%%%");
808 # get video codec options
809 sub set_vcodec_opts
{
810 my ($codec, $passes, $pass, $bitrate) = @_;
813 if ($codec eq "copy") {
816 } elsif ($codec eq "h264") {
817 my $local_opt = "subq=5:frameref=2";
819 if ($pass < $passes) {
820 $local_opt = "pass=$pass:subq=1:frameref=1";
822 $local_opt = "pass=$pass:$local_opt";
825 push(@opts, "x264", "-x264encopts",
826 "$local_opt:partitions=all:weight_b:bitrate=$bitrate:threads=auto");
828 } elsif ($codec eq "xvid") {
831 if ($pass < $passes) {
832 $local_opt = "pass=$pass:";
834 $local_opt = "pass=$pass:";
837 push(@opts, "xvid", "-xvidencopts",
838 "${local_opt}bitrate=$bitrate");
844 if ($pass < $passes) {
845 $local_opt = "vpass=$pass:";
847 $local_opt = "vpass=$pass:";
851 my $cs = "asv1|asv2|dvvideo|ffv1|flv|h261|h263|h263p|huffyuv|libtheora|"
852 . "ljpeg|mjpeg|mpeg1video|mpeg2video|mpeg4|msmpeg4|msmpeg4v2|"
853 . "roqvideo|rv10|snow|svq1|wmv1|wmv2";
854 if ($cs =~ /($cs)/) {
855 push(@opts, "lavc", "-lavcopts",
856 "${local_opt}vbitrate=$bitrate:vcodec=$codec");
859 fatal
("Unrecognized video codec %%%$codec%%%");
866 # run encode and print updates
868 my ($args, $file, $title_name, $ext, $length, $passes, $pass) = @_;
870 # Set output and logging depending on number of passes
872 my $output_file = "$title_name.$ext.partial";
873 my $base = basename
($title_name);
874 my $logfile = $defaults->{logdir
}."/$base.log";
877 $logfile = "$logfile.pass$pass";
878 if ($pass < $passes) {
879 $output_file = "/dev/null";
885 unshift(@
$args, "time", "nice", "-n20", $tools->{mencoder
}, "-v");
886 push(@
$args, "-o", $output_file, $file);
888 # Print initial status message
890 my $status = trunc
(19, 1, "[$pass] Encoding");
893 # Execute encoder in the background
896 open($fh_logfile, ">", $logfile);
897 print $fh_logfile join(" ", @
$args)."\n";
898 my ($pid, $reader, $error) = run
(\@
$args, 1);
900 # Write mencoder's ETA estimate
902 my $line = trunc
(59, 1, $status);
903 my $start_time = time();
904 my ($exit, $perc, $secs, $fps, $size, $ela, $eta);
906 use POSIX
":sys_wait_h";
907 while ((my $kid = waitpid($pid, WNOHANG
)) != -1) {
908 sysread($reader, my $s, 1024*1024);
910 print $fh_logfile $s;
912 if (int(time()) % $defaults->{timer_refresh
} == 0) {
913 $perc = s_it2
( trunc
(4, -1, $1) ) if ($s =~ /\(([0-9 ]{2}%)\)/);
914 $secs = trunc
(6, -1, "$1s") if ($s =~ /Pos:[ ]*([0-9]+)\.[0-9]*s/);
915 $fps = s_it
( trunc
(7, -1, $1) ) if ($s =~ /([0-9]+fps)/);
916 $size = trunc
(6, -1, $1) if ($s =~ /([0-9]+mb)/);
917 $ela = s_ela
( "+".int((time() - $start_time) / 60 )."min" ) if $perc;
918 $eta = s_eta
( "-$1" ) if ($s =~ /Trem:[ ]*([0-9]+min)/);
919 $line = "$status $perc $secs $fps $size " if $perc;
920 print "${line}$ela $eta \r";
925 # Flush pipe and close logfile
927 while (<$reader>) { print $fh_logfile $_; }
933 print $line . "[ " . s_ok
("done") . trunc
(14, 1, " ]") . "\n";
935 print $line . "[ " . s_err
("failed") . trunc
(12, 1, " ] check log") . "\n";
939 # run remux and print updates
940 sub remux_container
{
941 my ($root, $ext, $fps, $container, $acodec, $vcodec) = @_;
943 if ($container =~ /(mp4|mkv|ogm)/) {
947 my $base = basename
($root);
948 my $logfile = $defaults->{logdir
} . "/$base.remuxlog";
951 if (-f
"$root.$container") {
952 unlink("$root.$container");
954 my @args1 = ($tools->{mplayer
}, "$root.$ext",
955 "-dumpaudio", "-dumpfile", "$root.$acodec");
956 my @args2 = ($tools->{mplayer
}, "$root.$ext",
957 "-dumpvideo", "-dumpfile", "$root.$vcodec");
958 return (\
@args1, \
@args2);
962 unlink "$root.$acodec";
963 unlink "$root.$vcodec";
969 if ($container eq "mp4") {
971 my @args1 = ($tools->{mp4creator
}, "-create", "$root.$acodec",
973 my @args2 = ($tools->{mp4creator
}, "-create", "$root.$vcodec",
974 "-rate=$fps", "$root.$container");
975 my @args3 = ($tools->{mp4creator
}, "-hint=1", "$root.$container");
976 my @args4 = ($tools->{mp4creator
}, "-hint=2", "$root.$container");
977 my @args5 = ($tools->{mp4creator
}, "-optimize", "$root.$container");
979 my @a = (pre
, \
@args1, \
@args2, \
@args3, \
@args4, \
@args5);
980 my ($out, $exit, $err) = run_agg
(\
@a, $logfile);
982 return ($out, $exit, $err);
984 } elsif ($container eq "mkv") {
986 my @args = ($tools->{mkvmerge
}, "-o", "$root.$container",
990 my ($out, $exit, $err) = run_agg
(\
@a, $logfile);
991 unlink("$root.$ext");
992 return ($out, $exit, $err);
994 } elsif ($container eq "ogm") {
996 my @args = ($tools->{ogmmerge
}, "-o", "$root.$container",
1000 my ($out, $exit, $err) = run_agg
(\
@a, $logfile);
1001 unlink("$root.$ext");
1002 return ($out, $exit, $err);
1006 # Print initial status message
1008 my $status = trunc
(59, 1, "[.] Remuxing");
1011 # Execute remux in the background
1013 my $exit = &$remux();
1018 print "${status}[ " . s_ok
("done") . trunc
(15, 1, " ]") . "\n";
1020 print "${status}[ " . s_err
("failed") . " ] check log" . "\n";