Verstehe ein Fremdmodul/programm nicht *Anschlussfrage*

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
shakebox
User
Beiträge: 175
Registriert: Montag 31. März 2008, 17:01

Servus!

Mein eigentliches Ziel ist es, von Quicktime-Files Metadaten auszulesen, um mit diesen Daten (Framerate, Aufloesung, Cliplaenge, etc.) dann weitere Dinge zu tun. Dazu hab ich erstmal ein Modul namens "Videoparser" getestet. Das liefert aber schon bei meinen ersten zwei Test-QTs falsche Werte (z.B. falsche Framerate), so dass ich damit nicht arbeiten kann.

Als naechstes hab ich jetzt hachoir-metadata (https://bitbucket.org/haypo/hachoir/wik ... r-metadata) versucht. Wenn ich meinen Code analog zu diesem Code hier: https://bitbucket.org/haypo/hachoir/wik ... adata/code anlege bekomme ich auch sinnvollen Output, z.B. sowas:
Metadata:
- Duration: 6 sec 791 ms
- Image width: 1920 pixels
- Image height: 1080 pixels
- Creation date: 2013-03-18 14:23:02
- Last modification: 2013-03-18 14:23:12
- Comment: Play speed: 100.0%
- Comment: User volume: 100.0%
- MIME type: video/quicktime
- Endian: Big endian
Soweit schoen. Leider vermisse ich z.B. die Framerate. Was mich aber viel mehr irritiert ist, wie ich sinnvoll mit dem "metadata"-Objekt umgehe, das ich da aus dem Parser bekomme. Ich kann zwar sowas machen:

Code: Alles auswählen

clipheight = metadata.get("height")
duration = metadata.get("duration")
aber wie krieg ich raus, welche Werte (Keys?) dieses Objekt denn ueberhaupt hat? Es gibt zwar ne Methode getItems(), aber irgendwie leider keine Methode getKeys(), womit ich rausfinden koennte, welche Keys ich ueberhaupt ansprechen koennte.

Leider bin ich nur ein lausiger Scripter, der Module zwar halbwegs anwenden kann fuer einfache Scripte. Aber so richtig der Checker in Klassen usw. bin ich leider nicht, so dass ich mir da grad echt schwer tue, dieses Modul und seine Funktionalitaeten zu verstehen. Mich interessiert einfach, ob dieses Modul aus den Quicktimes, die ich so habe, gar nicht mehr an Infos rausziehen kann, ob obige Auflistung an Daten also wirklich alles ist.

Waere sehr nett wenn mir irgendjemand nen kleinen Hinweis geben koennte, wie ich da evtl. weitermache um rauszukriegen, was in dem metadata-Objekt eigentlich ueberhaupt drinsteckt.

Danke, lieben Gruss und schoenes Osterwochenende,

Shakebox
Zuletzt geändert von shakebox am Mittwoch 10. April 2013, 15:49, insgesamt 1-mal geändert.
shakebox
User
Beiträge: 175
Registriert: Montag 31. März 2008, 17:01

Ach ja: ein Tipp fuer ein anderes Modul, das Aehnliches leistet, aber einfacher zu verstehen/nutzen ist, waere natuerlich genauso willkommen!
Faule Socke
User
Beiträge: 11
Registriert: Mittwoch 27. März 2013, 10:57

Mit dir(metadata) bekommst du alle Attribute des Objekts als list (auch die Methoden). Die kannst du dir mal ausgeben lassen, eventuell hilft dir das weiter. Sonst schau doch mal, was das Objekt für ein Typ ist (mit type(metadata)) und schau, ob der eventuell von dict erbt (hab da so ne Vermutung). Dann hast du auf jeden Fall schon eine keys-Methode. Und als letzte Möglichkeit kannst du noch schauen, ob das Objekt iterierbar ist, eventuell kommst du so an die keys ran.
webspider
User
Beiträge: 485
Registriert: Sonntag 19. Juni 2011, 13:41

Irgendwie habe ich die böse Befürchtung, dass die Framerate aus den anderen Metadaten errechnet wird.
shakebox
User
Beiträge: 175
Registriert: Montag 31. März 2008, 17:01

also vom Typ "dict" erbt es nicht. Wenn man komplett rueckwaerts durch den Code durchgeht erbt es urspruenglich von "object". Deshalb auch keine keys-Methode. Verstehe.

Wenn ich mir diesen Code-Ausschnitt aber anschaue:

Code: Alles auswählen

    def processMovieHeader(self, hdr):
        self.creation_date = hdr["creation_date"].value
        self.last_modification = hdr["lastmod_date"].value
        self.duration = timedelta(seconds=float(hdr["duration"].value) / hdr["time_scale"].value)
        self.comment = _("Play speed: %.1f%%") % (hdr["play_speed"].value*100)
        self.comment = _("User volume: %.1f%%") % (float(hdr["volume"].value)*100//255)

    @fault_tolerant
    def processTrackHeader(self, hdr):
        width = int(hdr["frame_size_width"].value)
        height = int(hdr["frame_size_height"].value)
        if width and height:
            self.width = width
            self.height = height
dann wird mir klar dass es gar keinen Framerate-Wert geben kann. Mehr als die obigen Werte werden wohl bei MOVs gar nicht ausgelesen. Es gibt auch noch Klassen zu anderen Video-Fileformaten, da steht teilweise auch die Framerate dabei.

Also bleibt als Fazit: besser ein anderes Modul zum Extrahieren der Metadaten von MOVs suchen. Aber welches? Kennt jemand was Brauchbares?

Danke!
Faule Socke
User
Beiträge: 11
Registriert: Mittwoch 27. März 2013, 10:57

Du könntest selber eins schreiben, so kompliziert wird eine mov-Datei nicht aufgebaut sein :) Schau dir zur Sicherheit noch die get-Methode deines metadata-Objekts an, eventuell hast du ja irgendwo Ladecode übersehen oder sowas :)

Gruß Socke
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Faule Socke hat geschrieben:Du könntest selber eins schreiben, so kompliziert wird eine mov-Datei nicht aufgebaut sein :) Schau dir zur Sicherheit noch die get-Methode deines metadata-Objekts an, eventuell hast du ja irgendwo Ladecode übersehen oder sowas :)
Jaja, man kann prinzipiell alles selber schreiben. Fertige Module sind nur meist besser getestet und (je nach Ausreifungsgrad) auch flexibler in der Anwendung. Zudem erspart man sich eine Menge Denkarbeit. Falls die Schnittstelle des Moduls zu komplex sein sollte oder eine benötigte Funktionalität nicht vorhanden ist, dann würde ich wohl ebenfalls eher nach einem anderen Modul Ausschau halten. Falls es keins gibt, dann würde ich versuchen, mich mit der API des einzig vorhandenen Moduls abzufinden oder aber überdenken, ob nicht vielleicht ich selbst einfach zu doof für die Anwendung bin. Wobei letzteres in diesem Fall wohl eher nicht zutrifft. Vielleicht ist ja Selber-Schreiben am Ende doch die bessere Alternative... *räusper*
Faule Socke
User
Beiträge: 11
Registriert: Mittwoch 27. März 2013, 10:57

@snafu: Ja, ich muss dir da zustimmen, selber schreiben bleibt natürlich letzte Wahl, in der Regel findet man auch (grade bei Python) immer gute, fertige Module. Andererseits: Wer macht schon Videoverarbeitung mit Python...?

@Threadersteller: Halt uns auf dem Laufenden, wenn du was eigenes schreibst :)
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Als Zwischenweg gibt es natürlich immer die Möglichkeit das bestehende Modul zu erweitern, da muss man nicht immer das Rad von neuem erfinden.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
shakebox
User
Beiträge: 175
Registriert: Montag 31. März 2008, 17:01

ok, hab es jetzt ganz anders geloest: nutze das Commandline-Tool ffprobe aus dem ffmpeg-Paket (http://www.ffmpeg.org/ffprobe.html) und parse dessen Output und arbeite damit weiter.

Nicht so elegant wie ne native Python-Loesung, vor allem bei Multiplattform-Umgebungen, aber immerhin spuckt das Tool zuverlaessig viele Daten aus, was mir in dem Fall wichtiger war.

Danke nochmal fuers Mitdenken!
shakebox
User
Beiträge: 175
Registriert: Montag 31. März 2008, 17:01

Anschlussfrage:

bei meinen ersten Test-Quicktimes hat das alles wunderbar funktioniert. Nun hab ich einen neuen mit ner Timecode-Spur drin und da sieht der Output dann so aus: http://www.python-forum.de/pastebin.php?mode=view&s=339 (falls das nicht der richtige Umgang mit Pastebin ist sorry, hab das noch nicht so ganz verstanden wie/wann man das nimmt)

Bisher hatte ich einfach alle Zeilen, die ein = enthielten mit split() getrennt in Key=Value und das eben als Key/Value-Paar in ein dict gepackt. Das hat funktioniert, weil ich nur einen solchen [STREAM]-Block hatte. Nun hab ich zwei (und wenn ich noch eine oder mehrere Audiospuren haette dann noch mehr) von diesen Bloecken. Und da ueberschreib ich mir ja viele der Keys mit neuen Values, weil viele Keys ja mehrfach vorkommen.

So, wie parsed man sowas denn jetzt schlau? Eigentlich brauch ich nur die Werte aus der ersten Videospur, also dem ersten [STREAM]-Block, der die Zeile "codec_type=video" enthaelt. Teilt man da jetzt mit ner RegEx (oder was anderem?) erstmal alles auf in einzelne [STREAM]-Bloecke, macht aus jedem ein dict der ganzen Werte und nimmt dann nur das dict das man braucht? Oder gibt es andere (cleverere?) Methoden?

Danke nochmal fuer Euer Mitdenken und Mir-auf-die-Spruenge-helfen!
BlackJack

@shakebox: Da es sowohl eine Anfangs- als auch eine Endmarkierung gibt, kann man das doch ganz prima Zeilenweise verarbeiten. Immer bei ``[STREAM]`` fängt man ein neues Wörterbuch an und bei ``[/STREAM]`` weiss man, dass man fertig ist. Das macht man in einer Generatorfunktion welche die Wörterbücher liefert — dann kann man sich auch ganz einfach entscheiden nur bis zum ersten Wörterbuch zu parsen und dann abzubrechen.
shakebox
User
Beiträge: 175
Registriert: Montag 31. März 2008, 17:01

hm, klingt einerseits total toll, andererseits versteh ich nur Bahnhof. Ein Generator der die Woerterbuecher liefert? Da beisst es glaub aus bei mir, leider.
BlackJack

@shakebox: Wörterbuch ist das deutsche Wort für „dictionary”. Und für Generatorfunktionen ist die ``yield``-Anweisung zuständig.
shakebox
User
Beiträge: 175
Registriert: Montag 31. März 2008, 17:01

sorry, Woerterbuch ist natuerlich klar. Aber der Schritt, was und wie mir ein Generator beim Erstellen der Dicts helfen kann/soll, der erschliesst sich mir noch nicht. Aber ich werde mal wuehlen und recherchieren, was es mit der yield-Funktion so auf sich hat. Danke Dir!
Antworten