Open Source im professionellen Einsatz
Linux-Magazin 03/2017
655

Lambda Go

Die Lambda-Funktion in Listing 2 bekommt die URL der zu analysierenden Videodatei im Parameter-Dictionary »event« unter dem Schlüssel »movie_url« zugespielt. In einer echten Produktionsumgebung darf kein Python-Skript in einem festen Verzeichnis wie »data« operieren und hoffen, dass niemand dazwischenfunkt. Da Amazon-Lambda-Funktionen parallel aufgerufen werden, müssen sie für solche Zwecke mit Pythons »tempfile« -Modul zunächst ein Instanz-eigenes temporäres Verzeichnis anlegen und nach Abschluss der Tätigkeit wieder abräumen.

Damit dies auch passiert, falls eine der Funktionen nach einem Fehler eine Exception auswirft, sollte die letzte Zeile im Produktionsbetrieb in einem Exception-Handler stehen, das unterblieb in der Testversion. Listing 2 ruft in Zeile 10 die Methode »mkdtemp()« auf und nutzt das neue Verzeichnis, um in Zwischenschritten ermittelte Daten für die nächsten Stufen des Skripts abzulegen.

So legt Zeile 16 die per Webrequest eingeholte Videodatei unter dem in der Variablen »movie_file« abgelegten Namen ab, der aus dem letzten Teil des Pfads der URL stammt. Als nächste Stufe ruft Zeile 19 das Skript »max-movement-lk.py« aus dem Listing 3 auf, einen Python-Wrapper um das C++-Programm in Listing 1, und übergibt ihm den Pfad zur Videodatei im temporären Verzeichnis.

Listing 3

max-movement-lk.py

01 #!/usr/bin/python
02 import sys
03 import os
04 import subprocess
05
06 top_dir    = os.getcwd()
07 movie_path = sys.argv[1]
08
09 os.chdir(os.path.dirname(movie_path))
10
11 os.environ["LD_LIBRARY_PATH"] = os.path.join(top_dir,"lib")
12
13 print subprocess.check_output(
14   [ os.path.join(top_dir, "bin/max-movement-lk") ] +
15   [ os.path.basename(movie_path) ] )

Auf Montage

Hinterlässt die Analyse eine Reihe von Jpegs im Format »0001.jpg« , »0002.jpg« , …, kommt in der nächsten Stufe ab Zeile 24 in Listing 2 das Wrapperskript »mk-montage.py« in Listing 4 zum Zuge, das in die Dateinamen eingebettete Sekundenwerte ins Format »SS::MM:ss« umwandelt und die alten Dateinamen sowie die formatierten Labels Imagemagicks »montage« zu fressen gibt:

Listing 4

mk-montage.py

01 #!/usr/bin/python
02 import glob
03 import subprocess
04 import re
05 import time
06 import os
07 import sys
08
09 dir = sys.argv[1]
10 files = glob.glob(
11        os.path.join(dir,'*.jpg'))
12 cmds  = ["bin/montage.py"]
13
14 r = re.compile('.*?(\d+)')
15
16 for file in sorted(files):
17     match = r.match(file)
18     if match:
19         label = time.strftime("%H:%M:%S",
20           time.gmtime(int(match.group(1))))
21         cmds.append("-label")
22         cmds.append(label)
23         cmds.append(file)
24     else:
25         print "no match: " + file
26
27 cmds.append(os.path.join(
28     dir,'montage.jpg'))
29
30 print subprocess.check_output(cmds)
montage.py -label  00:00:01 tmp/001.jpg  [...]

Das Programm baut daraus einen Kontaktabzug in der Datei »montage.jpg« , die später in Amazons S3 landet, damit User sie per Link auf den Client holen können.

Abbildung 4: Gesammelte Shared Libs.

Das Python-Skript in Listing 5 fungiert als Wrapper um das Binary »montage« , dem im Verzeichnis »lib« eine Reihe von Shared Libraries beiliegt, damit das dynamisch gelinkte Binary im Container läuft. Die Umgebungsvariable »LD_LIBRARY_PATH« setzt den Suchpfad für Shared Libs auf dieses nicht standardisierte Verzeichnis, damit das Binary diese zur Laufzeit auch findet.

Listing 5

montage.py

1 #!/usr/bin/python
2 import sys
3 import os
4 import subprocess
5
6 os.environ["LD_LIBRARY_PATH"] = "lib"
7
8 print subprocess.check_output(
9   [ "bin/montage" ] + sys.argv[1:])

Abbildung 4 zeigt die mit Listing 6 gesammelten Shared Libs. Offensichtlich zieht das mit Open-CV gelinkte AI-Programm zur Bewegungsanalyse einen Rattenschwanz an Bibliotheken mit sich. Hinter einem Video steckt eben geballte Kompressionstechnik, die es zu dekodieren gilt, will man an die rohen Frame-Daten heran.

Listing 6

ldd-ls.py

01 #!/usr/bin/python
02 import subprocess;
03 import sys;
04
05 if len(sys.argv) != 2:
06     print("usage: {} file".format(sys.argv[0]))
07     sys.exit(1)
08
09 file = sys.argv[1]
10
11 output = subprocess.check_output(['ldd',file])
12 for line in output.split("\n"):
13     words = line.split()
14     if len(words) > 3:
15         print words[2]

Diesen Artikel als PDF kaufen

Express-Kauf als PDF

Umfang: 5 Heftseiten

Preis € 0,99
(inkl. 19% MwSt.)

Linux-Magazin kaufen

Einzelne Ausgabe
 
Abonnements
 
TABLET & SMARTPHONE APPS
Bald erhältlich
Get it on Google Play

Deutschland

Ähnliche Artikel

  • Snapshot

    Laufen Applikationen in einem Cloudsystem wie den Amazon Web Services, spart sich der Betreiber die Verwaltung und kann sich stattdessen auf das Wesentliche der App konzentrieren. Mike Schilli führt im ersten Teil des Workshops die grundlegende Einrichtung des Webservice aus.

  • Online-Artikel: Funktionale Programmierung in Python

    Python gilt vielen als objektorientierte Sprache, doch unterstützt es auch andere Paradigmen. Rainer Grimm demonstriert in seinem kostenlosen Online-Artikel das funktionale Programmieren in Python.

  • Perl-Snapshot

    Statt auf langweilige Überwachungsvideos zu starren, auf denen zu 90 Prozent nichts passiert, setzt Perlmeister Michael Schilli lieber die Bilderkennungssoftware Open CV ein, die automatisch den Handlungsablauf an den interessantesten Stellen extrahiert.

  • Funktionale Programmierung (2): Python funktional

    Die meisten Entwickler verbinden Python mit dem objektorientierten Programmierstil. Doch die Sprache beschreitet vermehrt auch die Pfade der funktionalen Programmierung. Dieser Artikel zeigt, was Python in Sachen Closures, List Comprehension und Funktionen höherer Ordnung zu bieten hat.

  • C++11

    Lambda-Funktionen sind die praktischen Helfer der Sprache C++11. Schon nach kurzer Zeit möchte kein C++-Entwickler sie missen, denn mit ihnen ist ein Algorithmus rasch und ohne Umschweife formuliert. Außerdem darf er sie wie Objekte behandeln.

comments powered by Disqus

Ausgabe 06/2017

Digitale Ausgabe: Preis € 6,40
(inkl. 19% MwSt.)

Artikelserien und interessante Workshops aus dem Magazin können Sie hier als Bundle erwerben.