#!/usr/bin/perl use POSIX qw(mkfifo); use Fcntl; use IO::Handle; use strict; $|=1; print "############\n"; my %prog; my $infile=$ARGV[0]; my $outfile=$ARGV[1]; # get some stats my $frametotal,$fwide,$fhigh; open(IN,"ffprobe -show_streams '$infile' 2>/dev/null |") || die "$infile: $!"; while() { chomp; $frametotal=$1 if(/^nb_frames=(\d+)/); $fwide=$1 if(/^width=(\d+)/); $fhigh=$1 if(/^height=(\d+)/); last if(/^\[\/STREAM\]/); } close(IN); my @acmd; @acmd=("-acodec","libfaac","-ac","2","-ab","160k"); my @vcmd=qw/-c:v libx264 -vprofile main -preset slow -tune film -level 3.1 -crf 28 -threads 0/; if($fwide > 1280 || $fhigh > 720) { @vcmd=(@vcmd,"-vf","scale=min(1280\\,iw):-1"); } pipe(IN, OUT); # We read from IN, ffmpeg writes to OUT. OUT->autoflush(1); # Autoflush on, close-on-exec off my $val=fcntl(OUT,F_GETFD,0) || die "Error: fcntl GET: $!"; $val &= ~FD_CLOEXEC; fcntl(OUT,F_SETFD,$val) || die "Error: fcntl SET: $!"; my $fd=fileno OUT; my @cmd=("ffmpeg","-progress","pipe:$fd","-v","panic", "-i",$infile, @acmd,@vcmd,@metadata,$outfile); my $pid=fork(); # Fork the kid unless($pid) { die "Can't fork! $!" unless defined $pid; close(IN); exec @cmd or die "Can't exec! $!"; } # parent. close(OUT); while() { chomp; my ($a,$b)=split /=/; $prog{$a}=$b; if($a eq "progress") { my $pcent=$prog{"frame"}/$frametotal*100; my $hcent=int($pcent/2); my $bar="[".("#" x $hcent).(" " x (50-$hcent))." ] "; $bar .=sprintf("%.2f",$pcent)."% fps=".$prog{"fps"}; print "\r$bar"; } } print "\nWaiting for finish...\n"; waitpid($pid,0);