Showing posts with label linux. Show all posts
Showing posts with label linux. Show all posts

2015-07-04

Allow only one program at a time to access a resource in linux

I had several programs I needed to run but I wanted to make sure only one program got access to a resource at the same time.  So I wrote a short and simple perl script that would do this.  This script needs a directory in /var/run that it can write to.  Since the script doesn't run as root, I have to create this directory after each reboot.

The script is invoked like this:

1nstance.pl -d /var/run/once -n com1 -- my-program my-args

It will run my-program if there is no other script accessing the named resource com1.  If there is another script currently running and using com1 then it will just quit.

The script can be downloaded from here.

--------------------------1nstance.pl-------------------



#!/usr/bin/perl -w
#
#(c) copyright 2015 Kim Holburn
# Licensed under GPLv3

use strict;
use Getopt::Long;

my $verbose = 0;
my $help = 0;
my $myname = "";
my $mydir = "/var/run/once";
my $PID = 0;
my $time = 0;
my $timeout = 0;

Getopt::Long::Configure('require_order');
GetOptions ('verbose+' => \$verbose,
            'directory=s' => \$mydir,
            'name=s' => \$myname,
            'timeout=i' => \$timeout,
            'help|?' => \$help);

if ($help) {
  print <<EOM;
one instance - make sure a program only runs one instance.
usage $0:
$0 [options] -- <command> [ARGS]
  options:
    -h|-?|--help - print this screen
    -d|--directory <directory> 
       directory to store run files. 
       Default is /var/run/once
    -t|--timeout <n> 
       time in seconds that a program is allowed to run 
       before being considered hung and will be killed
       -t=0 means no timeout. The running process will 
       be left untouched.
    -v|--verbose - print extra messages
    -n|--name
       name of process or resource to be run once
       The default is the name of the program.    

EOM

  exit;
}

if ($timeout < 0) { die "$0 ERROR: specified timeout less than zero ($timeout)"; }
if (10000 < $timeout) { die "$0 ERROR: ($timeout) too large"; }
if ($mydir !~ m{^/}) { die "$0 ERROR: directory ($mydir) is not an absolute path!"; }
if (! -d $mydir) { die "$0 ERROR: directory ($mydir) does not exist!"; }

# first argument is command to run
my $path = shift;
if (!$path) { die "$0 ERROR: No command "; } 
my $program = $path;
# command must be a full absolute path.  
my $dir = ".";
my $args="";
if ($program =~ m#/#) {
  $program =~ s#^.*/##;
  $dir =~ s#/[^/]*$##;
}
if (!$program) { die "$0 ERROR: program name invalid.  Must be a filename"; } 
if (! -e $path) { die "$0 ERROR: program ($path) does not exist"; }
if (-d $path) { die "$0 ERROR: program ($path) is a directory"; }
if (! -x $path) { die "$0 ERROR: program ($path) not executable"; }
if (!$myname) { $myname=$program; }

my $run1 = "$mydir/$myname";

sub deleterun {
  if ( -e $run1 ) {
    unlink $run1;
    if ( -e $run1 ) { die "$0 ERROR: cannot delete file ($run1)"; }
  }
}

if ($verbose) {
  print "debug timeout=($timeout) dir=($mydir) name=($myname) \n";
  print "debug v=($verbose) 1=($run1) prog=($program) args=(";
  print join (")(",@ARGV);
  print ") \n";
}

if (open(my $fh, '<', "$run1")) {
  while (<$fh>) {
    chomp ;
    if (/^\s*$/) { next; }
    if (/^PID (\d+)$/i) { $PID = $1; }
    elsif (/^TIME (\d+)$/i) { $time = $1; }
  }
  close $fh;
  # no PID or time
  # this shouldn't happen and probably means we have the wrong file
  if (!$PID or !$time) { die "$0 ERROR: run file ($run1) has no PID or time"; }
  chomp (my $proc = `ps hp $PID -o %c`);
  # orphaned run file, delete
  if ($proc eq "") { deleterun; }
  else  {
    # another instance running
    my $timediff = time - $time;
    if (0 == $timeout or $timediff <= $timeout) { die "$0 ERROR: another instance of $myname ($proc) running"; }  
    print STDERR "$0 ERROR: another instance of $myname ($proc) has probably hung\n";
    # another process has probably hung
    # grab its children
    my @PIDS = (`ps h --ppid $PID -o %p`, $PID);
    kill ('TERM', @PIDS);
    chomp ($proc = `ps hp $PID -o %c`);
    # couldn't kill it.  Give up.
    if ($proc) { die "$0 ERROR: can't kill instance ($myname) ($proc) PID ($PID)"; }
    # it died OK.  Delete run file if possible.
    deleterun;
  }
}

if (1 < $verbose) { print STDERR "creating run file ($run1) ... \n"; }
open(my $fh, '>', "$run1") or die "$0 ERROR: opening file ($run1) ($!)" ;
print $fh "PID $$\n";
print $fh "time ", time, "\n";
close $fh;

#If something bad happens delete the run file
sub cleanup {
  if (-e $run1) {
    if (1 < $verbose) { print STDERR "Deleting run file...\n"; }
    unlink $run1;
  }
  exit;
};
$SIG{'INT'}=\&cleanup;
$SIG{'TERM'}=\&cleanup;
$SIG{'QUIT'}=\&cleanup;

if ($verbose) { print STDERR "Starting ....\n"; }

system ($path, @ARGV);

cleanup;

2009-02-03

Notes on video editing

Notes on video editing.

I needed to do some video editing of a school concert. I have never edited video before but I thought it might be interesting to learn and that the current PCs probably were fast enough to do it. I volunteered because I though it might be interesting to learn. There were 3 different cameras involved, one of them shot in 4:3 PAL one in 16:9 PAL and one 4:3 NTSC.

I am running a MacBook Pro (1st intel) running 10.5.6 and a white box running ubuntu Hardy. The white box was a P5LD2 SE Motherboard with a Geforce 8600GT video card so it could do video effects natively. Actually the white box was running kubuntu with gnome. A bit messy and maybe caused some of the problems with kdenlive. (Why can't I have both KDE and Gnome? Hey maybe even other window managers as well?)

I tried various video editing applications.
FinalCut Pro 5.1 on the Mac (Very expensive)

On Ubuntu (using apt):
Avidemux
Kino
Open Movie Editor
Pitivi Movie Editor
kdenlive 0.5
ffmpeg (cli)
mediainfo (info only)

and downloaded directly:
Cinelerra

And for creating the DVD:
iMovie and iDVD on the Mac.

One of the hassles I found with some of the programs is that they read in and converted video when you imported a clip. I found this too annoying and often was a very time consuming process. I tended to give up on programs that did this although in some cases there were ways of telling the program to use a format that was read in quickly. ie if you create an mpeg iMovie project it will convert another video format like say raw video to mpeg. If you import a particular format into an iMovie project of the same format it just copies it. So it's a good idea to convert all the videos to the same format. On the other hand you don't want to convert into a lossy format (like mpeg which is what DVDs have to use) until the last moment or the quality of the final product will suffer terribly.

Before I started I had to convert the videos to the same format. I chose 4:3 PAL.
After trying different programs I used ffmpeg to crop the wide format video to fit with the 4:3 format camera. For some reason this didn't seem to be an available option in any of the GUI programs. Working out the spot to crop was no simple matter either. I had to calculate it by hand.

ffmpeg is also very good for converting NTSC to PAL. (hint: use the deinterlace option).

I used Avidemux for converting between different formats and for trimming files. I found too late that kdenlive does trimming easily and for free (without actually changing the trimmed file).

Kino is very good for some aspects of converting raw dv video. Unfortunately with some of the videos it wasn't apparently able to synchronise the audio correctly so I didn't trusted it with those videos.

Pitivi and Open Movie editor just crashed on me. Cinelerra never really worked. If I opened the settings window I could never get it to go away. The OK button never responded. It also crashed and hung on me a number of times before I gave it up, never having done anything at all on it.

Kdenlive was a gem. I ended up using it exclusively for the editing. It does crash a lot, oh, it's so annoying, sometimes even crashing the video card necessitating a cold reboot and nearly always at least taking out the X server necessitating relogging in. Once it crashes then restarting it just makes it crash again straight away. It leaves special recovery files in several places and these needed to be deleted or it would just continue to crash. I discovered that sometimes if I invoked it with a file name all the recover crud that it creates is bypassed. Sometimes renaming the project file after a really major crash would allow me to open it without kdenlive crashing. One day I had to delete everything it left including the preferences file every time I started it or it would just crash. If they fix the crashing problem it would be a truly great editor.

kdenlive does not import files. It creates a xml file with a list of all your edits. This makes it very fast. Also it could use the video and sound cards to view video and the edited product directly on the fly rather than having to render. This makes editing so easy and fast. I didn't at first understand how to do a cut - the basic transition - and sometimes I would ask it for multiple clip playback and get it and sometimes not. I couldn't work out how to turn off sound for a clip, maybe you have to use a track for each clip. If you zoom the main timeline right in so you can see frames the whole program slows down and becomes almost unuseable. Pity, it would have been useful at times. Overall though, the fact is that without really understanding a lot of the features there was enough flexibilty for me to be able to edit a three camera shoot, cutting and fading between cameras, synchronising the audio etc.

I tried out Final Cut Pro on a friend's system. Final Cut Pro I found almost unusable because I couldn't view or hear a clip without rendering it first and after every editing change, the timeline had to be rerendered. Maybe the latest version doesn't have this problem as it was made with more powerful hardware in mind. FCP also used a lot of disk space on a directly connected hard disk. A USB2 or firewire disk simply wasn't fast enough to watch video. This was partly a problem of the hardware I was using though. I didn't have enough space left on the laptop internal hard disk. Oh and did I mention that FCP is expensive? That might be OK if I were going to do this for a living but for a one off volunteer job for a school play? It simply isn't worth it.

Once the editing was done though, for creating the DVD the simplest thing was using iMovie and iDVD on the Mac. There is nothing like it, although I found the lack of flexibility a bit annoying. Adding chapter marks in iMovie and dragging it to your DVD project automatically created all the scenes menus, so simple.

I did try a couple of linux DVD creators but either I couldn't seem to import videos (qDVDAuthor) or I couldn't understand how to create menus (devede) or I would have had to create some horrendous XML file (dvdauthor).