Samstag, 6. Oktober 2012

Time Machine Failing - Get alerted by Growl

I had it now 2 times that my Time Machine backups were failing. First because of a dead hard drive, which I didn't notice for more than a month, second because of - I don't know. It simply failed.

Unfortunately there is no notification at all if this happens. No mail, no hint, no nothing.

So I had the idea to write a small perl script which is checking every hour (by cron) how old the last successful backup is, and give me a growl notification if it's older than 2 hours.

So without any further ado, this is the script. Copy and Paste it into a file called "time-machine-check.pl", make it executable and put into your crontab something like this:

7 * * * * /Users/shk/bin/time-machine-check.pl

to make it execute every 7 minutes after the hour.

#!/usr/bin/perl
use strict;
use warnings;
use Time::Local;
use File::Basename;
use Getopt::Long qw(:config no_ignore_case);
use Pod::Usage;

my $MAXAGO= 2;
my $DEFAULTS    = '/usr/bin/defaults';
my $LOCK_FILE   = '/private/tmp/.'.(basename $0);
my $TM_FILE     = '/private/var/db/.TimeMachine.Results';
my $KEY=          'BACKUP_COMPLETED_DATE';
my @READ_BACKUP = ($DEFAULTS, 'read',  $TM_FILE, $KEY);
my @GROWL_NOTIFY= ('/usr/local/bin/growlnotify',
    '-t' => 'Last backup too long ago!',
    '-n' => 'Time Machine',
    '-a' => 'Time Machine',
    '-w',
);

my (
    $test,
    $age,
);

help() unless GetOptions(
    't'          => \$test,
    'a=i'        => \$age,
    'h|help'     => \&help,
    'm|man'      => \&man,
);
$age||= $MAXAGO;

sub help { pod2usage(-verbose=>1); exit; }
sub man  { pod2usage(-verbose=>2); exit; }

# Get date of last successful backup
my $lastbackup= execute(@READ_BACKUP);

my ($y,$m,$d,$H,$M,$S)= ($lastbackup=~ /^(\d+)-(\d+)-(\d+)\s+(\d+):(\d+):(\d+)\s/);
my $ago= time - timelocal($S, $M, $H, $d, $m-1, $y);

# Convert to hours
$ago/= 3600;

# Prepare the message
my $msg;
if ($ago >= 24) {
    $msg= plural(int($ago/24), "%d day", "%d days");
}
elsif ($ago >= 1) {
    $msg= plural(int($ago), "%d hour", "%d hours");
}
else {
    $msg= plural(int($ago*60), "%d minute", "%d minutes");
}

# Do we already have a message and is it younger than 1 day?
my $second_message;
if (-e $LOCK_FILE) {
    my $second_message= 1;
    if (-M $LOCK_FILE < 1) {
        undef $msg unless $test;
    }
}

# Make the message sticky by default
my $sticky= '-s';
if ($ago < $age) {
    # unless it's a test message and not an alert
    $sticky= '';
    undef $msg unless $test;
}

# Now display the message
my $lf;
if ($sticky) {
    open $lf, '>>', $LOCK_FILE;
    print $lf $$,$/;
    close $lf;
    $lf= $LOCK_FILE unless $second_message;
    END {
        unlink $lf if defined $lf;
    }
}
execute(@GROWL_NOTIFY, $sticky, '-m' => "The last successful backup was done more than $msg ago.") if $msg;


sub plural {
    my($num, $singular, $plural, $zero)= @_;
    if ($num == 1) {
        return sprintf($singular, $num);
    }
    if ($zero and not $num) {
        return $zero;
    }
    return sprintf($plural, $num);
}

sub execute {
    open my $in, '-|', @_ or die "Failed to execute\n\t".join(' ',@_).": $!\n";
    $_= do { local $/; <$in> };
    close $in;
    return $_;
}

=head1 NAME

time-machine-check.pl - a small script to notify via growl when no backup was done.

=head1 SYNOPSIS

time-machine-check.p -a hours -t

=head1 DES‎CRIP‎TION

This is a small perl script to be used as a cronjob like so:

7 * * * * /usr/local/bin/time-machine-check.pl -a 2

which will give a growl notification in case the last backup is older than 2 hours.

=head1 OPTIONS

=over 4

=item B<-a> hours

Maximum allowed backup age before notifying.

=item B<-t>

Test option. Notify in any case.

=back

=head1 BUGS

none yet

=head1 TODO

let's see...

=author

time-machine-check-2012.mail.skeeve@xoxy.net

=cut

Samstag, 4. August 2012

MP4 Filme skalieren

Manchmal sind Filme, die ich mit meinem M750S aufgenommen habe, falsch skaliert. Mit mp4box lassen sie sich ziemlich einfach neu skalieren.

Zuerst mit mp4box die aktuellen Maße prüfen:


$ mp4box -info Ab\ durch\ die\ Hecke.mp4 
* Movie Info *
Timescale 1000 - Duration 01:17:24.880
Fragmented File no - 2 track(s)
File Brand isom - version 512
Created: GMT Thu Jan  1 00:00:00 1970


File has no MPEG4 IOD/OD


iTunes Info:
Name: Ab durch die Hecke
Comment: Convertified by iSquint - http://www.isquint.org
Encoder Software: Lavf50.5.0


Track # 1 Info - TrackID 1 - TimeScale 25 - Duration 01:17:24.880
Media Info: Language "Undetermined" - Type "vide:mp4v" - 116122 samples
Visual Track layout: x=0 y=0 width=640 height=480
MPEG-4 Config: Visual Stream - ObjectTypeIndication 0x20
MPEG-4 Visual Size 640 x 480 - Simple Profile @ Level 1
Pixel Aspect Ratio 1:1 - Indicated track size 640 x 480
Self-synchronized


Track # 2 Info - TrackID 2 - TimeScale 44100 - Duration 01:17:24.664
Media Info: Language "Undetermined" - Type "soun:mp4a" - 200029 samples
MPEG-4 Config: Audio Stream - ObjectTypeIndication 0x40
MPEG-4 Audio MPEG-4 Audio AAC LC - 2 Channel(s) - SampleRate 44100
Synchronized on stream 1

Eigentlich sollte der Film in 16:9 sein. Am Einfachsten wird skaliert, indem man die gewünschte Breite errechnet: 480/9*16=853,333...

Ich wähle hier 856 als neue Breite.


$ mp4box -par 1=856:640 Ab\ durch\ die\ Hecke.mp4 





Mittwoch, 11. Juli 2012

MP4 Dateien asynchron

Ich habe ab und an mal ein paar asynchrone MP4 Dateien. Mit mp4box läßt sich das relativ einfach wieder beheben.

Zuerst mit mp4box info async.mp4 prüfen, welche Streams vorhanden sind.


* Movie Info *
Timescale 1000 - Duration 01:29:34.640
Fragmented File no - 2 track(s)
File Brand isom - version 512
Created: GMT Thu Jan  1 00:00:00 1970


File has no MPEG4 IOD/OD


iTunes Info:
Name: Ein Skandal in Belgravia
Artist: Sherlock
Album: Sherlock, Staffel 2
Comment: Convertified by iSquint - http://www.isquint.org
Album Artist: Sherlock
Encoder Software: Lavf50.5.0


Track # 1 Info - TrackID 1 - TimeScale 25 - Duration 01:29:34.640
Media Info: Language "Undetermined" - Type "vide:mp4v" - 134366 samples
Visual Track layout: x=0 y=0 width=640 height=352
MPEG-4 Config: Visual Stream - ObjectTypeIndication 0x20
MPEG-4 Visual Size 640 x 352 - Simple Profile @ Level 1
Pixel Aspect Ratio 1:1 - Indicated track size 640 x 352
Self-synchronized


Track # 2 Info - TrackID 2 - TimeScale 44100 - Duration 01:29:30.450
Media Info: Language "Undetermined" - Type "soun:mp4a" - 231286 samples
MPEG-4 Config: Audio Stream - ObjectTypeIndication 0x40
MPEG-4 Audio MPEG-4 Audio AAC LC - 2 Channel(s) - SampleRate 44100
Synchronized on stream 1


Dann den video track und den (oder die) Audiotracks, letztere mit passendem delay, zu einem neuen Video zusammenfügen:

mp4box -add async.mp4#1=1 -add async.mp4#2=2:delay=1000 -new sync.mp4