Wer kennt das nicht, da hat man einige AVIs oder MKVs auf der Platte und will wissen, wie viel Videomaterial man da gespeichert hat 😉
Bei 3-4 Dateien kann man das ja noch bequem manuell nachgucken. Aber irgendwann ist das nicht mehr sinnvoll.

Nach etwas Suche bin ich da auf das Perl-Modul Image::ExifTool gestoßen. Wie der Name erkennen lässt, ursprünglich nur für das Auslesen von Exif-Daten von Bildern, gedacht, gibt es hier aber einige Erweiterungen mit denen man dann auch andere Dateien auslesen kann:

  • Image::ExifTool::RIFF — Perfekt für AVI-Files, die ja im RIFF (Resource Interchange File Format) gespeichert sind
  • Image::ExifTool::Matroska — Wie der Name erraten ist die Erweiterung für MKVs gedacht

Also wie sieht nun mein Script für das Auslesen und der Berechnung aus?

Eigentlich ziemlich simpel:

#!/usr/bin/perl

use strict;
use warnings;

use Image::ExifTool::RIFF;
use Image::ExifTool::Matroska;

my @zeiten;
my $runtime;
my $path = shift;

print $path,"\n";

my @files = `find $path -type f -size +1200k`;

foreach(@files) {
  chomp $_;
  my $exifTool = new Image::ExifTool;
  my $info = $exifTool->ImageInfo("$_");
  $info = $exifTool->GetInfo('Duration');
  foreach (sort keys %$info) {
    push(@zeiten,$$info{$_});
  }
}

foreach(@zeiten) {
  my ($hour,$min,$sec) = split(":",$_);
  $runtime += $hour*3600 + $min*60 + $sec;
}

print $runtime," sec.\n";
print $runtime/60," min.\n";
print $runtime/3600," hours\n";
print $runtime/(3600*24), " days\n";

Und nun noch ein/zwei Erklärungen für die Leser, damit das ganze auch nachvollziehbar wird.

my @files = `find $path -type f -size +1200k`;

Hier lasse ich über das Linux-Kommando find alle Dateien einer bestimmten Größe finden (im meinem Fall befinden sich in dem Zielverzeichnis auch noch andere Dateien, die aber wesentlich kleiner sind, als die Video-Dateien). Perl schreibt die einzelnen Einträge dann automatisch in die einzelnen Stellen eines Arrays. Der Pfad wird dem Script als Parameter übergeben in der Variable $path gespeichert.

chomp $_

Da Linux hier bei jedem Ergebnis einen Zeilenumbruch anfügt, müssen wir den noch mit chomp von diesem befreien.

$info = $exifTool->GetInfo('Duration');
 foreach (sort keys %$info) {
 push(@zeiten,$$info{$_});

Nun lesen wir die Laufzeit aus, die in einem Hash gespeichert ist und pushen diesen in ein bereits definiertes Array.

my ($hour,$min,$sec) = split(":",$_);
  $runtime += $hour*3600 + $min*60 + $sec;

Da GetInfo(‚Duration‘) die Laufzeit in Stunden:Minuten:Sekunden (z.B. 2:12:15) ausgibt, trenne ich die einzelnen Stellen des Arrays @zeiten mit dem Befehl split auf und addiere diese umgerechnet in Sekunden auf.

Am Ende wird die Laufzeit dann noch in Sekunden, Minuten, Stunden und Tagen ausgegeben.

Das selbe kann man auch mit MP3 bewerkstelligen. Hierzu gibt es das Perl-Modul „MP3::Info“.
Das Script sieht dann eigentlich ziemlich identisch aus:

#!/usr/bin/perl

use strict;
use warnings;

use MP3::Info;

my $runtime;
my $path = shift;

my @files = `find $path -type f -name "*.mp3"`;


foreach(@files) {
  chomp $_;
  my $info = get_mp3info($_);
  $runtime += $info->{SECS};
}

print $runtime," sec.\n";
print $runtime/60," min.\n";
print $runtime/3600," hours\n";
print $runtime/3600*24)," days\n";

Ich suche hier im find-Kommando nur nach der Endung „mp3“ und hier kann man sich direkt die Laufzeit in Sekunden ausgeben lassen, du kann sich daher den Schritt mit dem weiteren Array und split sparen.