2010-08-19 4 views
1

Je souhaite que l'écran affiche uniquement la sortie des informations de mise à jour en continu lors de l'appel du système ffmpeg.exe.Comment modifier la sortie d'écran de ffmpeg.exe en Perl?

Je suis venu avec le script suivant:

use Capture::Tiny qw/capture/; 
use threads; 
use threads::shared; 

my $stderr :shared; 
my $thread1 = threads->create(\&ffmpeg); 
my $threads = threads->create(\&time_info,$thread1); 
$threads->join(); 

sub ffmpeg { 
    ($stdout, $stderr) = capture { 
    system "ffmpeg -i source_video.flv -vcodec wmv2 -acodec wmav2 output_video.wmv"; 
    }; 
} 

sub time_info { 
    while(1){ 
     $|=1; 
     $stderr =~ m{time=(\d+\.\d+)}msg; 
     print $1,"\n"; 
     sleep(1); 
    } 
} 

Je sais que le script est buggy. Mais ma question actuelle est pourquoi le sous-programme time_info ne fonctionne pas simultanément avec le sous-programme ffmpeg? Il semble commencer à fonctionner seulement quand le sous-programme ffmpeg se termine. Et quand le sous-programme ffmpeg se termine, le sous-programme de time_info me donner quelque chose comme ce qui suit:

3.28 
7.56 
11.64 
15.80 
20.88 
25.76 
30.84 
35.88 
40.76 
45.80 
50.88 
55.88 
60.88 
65.88 
71.08 
76.32 
79.46 
3.28 
7.56 

Ici, 79,46 est sur la durée de la vidéo.

Des pointeurs? Merci comme toujours :)

Mise à jour:

Merci à @daxim pour moi d'envoyer sur la bonne voie. Maintenant, en utilisant la pompe d'IPC: Run, j'ai trouvé le script suivant qui est encore bogué mais qui peut faire ce dont j'ai besoin, c'est-à-dire supprimer la sortie de ffmpeg et afficher une barre de progression de la conversion vidéo.

use strict; 
use warnings; 
use IPC::Run qw(start pump); 
use Term::ProgressBar; 

my @cmd = qw(ffmpeg -i source_video.flv -vcodec wmv2 -acodec wmav2 output_video.wmv); 

my ($in, $out, $err); 

my $harness = start \@cmd, \$in, \$out, \$err; 

#Captures the duration of the video... 
#Converts hh:mm:ss format to seconds only 
pump $harness until ($err =~ m{time=(\d+\.\d+)}msg); 
$err =~ m{Duration: (\d+:\d+:\d+\.\d+)}ms; 
my $duration = $1; 
my ($h, $m, $s) = split /:/, $duration; 
$duration = $h * 3600 + $m * 60 + $s; 


my $progress = Term::ProgressBar->new ({count => $duration}); 

#Builds an infinite loop... 
#Stops at intervals to print progress information 
while(1){ 
    pump $harness until ($err =~ m{time=(\d+\.\d+)}msg); 
    my $so_far = $1; 
    $progress->update ($so_far); 
    last if ($duration - $so_far <= 0.5); 
    } 

Répondre

1

Vous voyez ceci parce que capture remplit les variables seulement après que le bloc est terminé. Si vous voulez lire la sortie enfant par morceaux, utilisez pump from IPC::Run.

+0

Merci @daxim, je vais essayer. – Mike

+0

J'ai regardé l'exemple d'utilisation du module ipc :: run mais la pompe ne semble pas être capable de sortir uniquement le contenu désiré. On dirait que tout produit de façon incrémentielle. Y at-il quelque chose que je peux changer dans le code suivant pour sortir sélectivement? Merci. Le script: mon @cmd = qw (ffmpeg -i source_video.flv -vcodec wmv2 -acodec wmav2 output_video.wmv); mon $ h = début \ @cmd, \ $ dans, \ $ out, \ $ err, timeout (10); pompe $ h; – Mike

+0

Filtrez la sortie comme dans votre question ci-dessus afin que seul le contenu désiré soit laissé. – daxim

Questions connexes