Script verhaelt sich unter Windows anders als am Mac, warum?

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

Tach!

Ich habe ein kleines Teilscript, das mittels 'ffprobe' (gehoert zu ffmpeg und gibt Infos/Metadaten ueber jegliches Medien-File aus) ein Quicktime-File analysiert und die gefundenen Werte in nem Dictionary speichert. Das hat bisher am Mac wunderbar funktioniert. Das gleiche Script funktioniert nun unter Windows nicht mehr identisch, was ich einfach nicht verstehe.

ffprobe spuckt folgende Infos bei meinen Beispiel-QTs aus, wenn man es im Terminal mit '-show_streams' aufruft (auf wesentliche Teile reduziert):
ffprobe version 0.7-rc8
[...]
[STREAM]
index=0
codec_name=dnxhd
codec_long_name=VC3/DNxHD
codec_type=video
[...]
TAG:language=eng
TAG:codec_name=Lavc55.66.100 dnxhd
[/STREAM]
[STREAM]
index=1
codec_name=unknown
codec_type=data
[...]
nb_frames=1
TAG:language=eng
[/STREAM]
sprich fuer jeden im QT enthaltenen Stream so nen [STREAM][/STREAM]-Teil und darin fuer jeden Wert eben eine Zeile.

holen tu ich mir diesen Output so:

Code: Alles auswählen

cmnd = [ffprobe, '-show_streams', movpath]
p = subprocess.Popen(cmnd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = p.communicate()
und das parsen der Zeilen funktioniert dann so:

Code: Alles auswählen

movinfo = {}
for line in out.split('\n'):
    if '=' in line:
        linekey, linevalue = line.split('=')
        movinfo[linekey] = linevalue
    if '[/STREAM]' in line and movinfo['codec_type'] == 'video':
        break
return(movinfo)
dabei fange ich ueber die Zeile 6 eben ab ob erstens ein Stream-Block fertig ist und zweitens ob ich den Stream erwischt habe mit codec_type=video. Wenn ja hab ich alle Werte richtig erfasst und hoere auf und spucke das Dictionary aus.

Soweit funktioniert das unter OS X wunderbar. Unter Windows ergibt die Zeile 6 aber leider nicht True nachdem der erste Stream fertig ist, sondern macht einfach weiter und fuellt die gleichen Felder dann mit den Werten aus dem naechsten Stream, die aber falsch sind.

Kann mir irgendjemand erklaeren, warum das so ist bzw. wie ich da drauf kommen koennte? Hat es irgendwas mit unterschiedlichen Zeilenenden zu tun? Ist der Inhalt von 'out' aus dem subprocess unterschiedlich bei verschiedenen Plattformen? Per 'print' angeschaut sind sie gleich, aber das ist ja schon 'schoen gemacht'.

Danke fuer jegliche Ideen, ich versteh es grad einfach ueberhaupt nicht mehr!
BlackJack

@shakebox: Schau Dir die `repr()`-Darstellung von den jeweiligen Daten an, dann siehst Du genauer was die enthalten.
shakebox
User
Beiträge: 175
Registriert: Montag 31. März 2008, 17:01

@Blackjack: stimmt, die unterscheiden sich. Am Mac steht als Zeilentrenner '\n' drin, unter Windows '\r\n'. Das heisst ich muss die Zeile 'for line in out.split('\n'):' abhaengig vom OS mit unterschiedlichen Werten fuettern? Kuemmert sich Python um so was nicht selbst? Ui, jetzt bin ich verbluefft. Muss ich ausprobieren, danke!
nfb503
User
Beiträge: 19
Registriert: Donnerstag 5. Juni 2014, 14:26

1 Kann es an Camel-/Pascal Case liegen?
2 Hast du schon mal probiert aus dem zweiten if ein elif zu machen ?

Ich würde in so einem Fall das erste if mal auskommentieren und das zweite if einmal mit der ersten und einmal mit der zweiten Bedingung laufen lassen, um zu sehen
ob irgendwann eine der Bedingungen überhaupt erfüllt wird.

Sorry, ich bin nicht wirklich eine Hilfe aber manchmal sind es ja auch Kleinigkeiten, die mit dem eigentlichem Problem nichts zu tun haben.
BlackJack

@shakebox: Wie soll sich Python in dem Fall da denn selbst drum kümmern? Die Daten die vom externen Programm über die Pipe kommen werden nicht verändert. Das Geschrei wäre ziemlich gross wenn das einfach so passieren würde. Du könntest statt `split()` vielleicht mal die `splitlines()`-Methode versuchen und falls das nicht hilft, müsstest Du Dich in der Tat selber darum kümmern, dass die richtige Art von Trenner beim Aufteilen verwendet wird.
shakebox
User
Beiträge: 175
Registriert: Montag 31. März 2008, 17:01

ok. Ich bin davon ausgegangen dass in Python '\n' einfach allgemein fuer "neue Zeile" steht, das dann bei jeder Plattform entsprechend interpretiert wird. Wenn ich andersrum folgende Zeile eingebe in nem Interpreter:

Code: Alles auswählen

print '123\n456'
bekomme ich ja auch auf allen Plattformen folgendes Ergebnis:

123
456

und muss nicht unter Windows '123\r\n456' schreiben. Und da ich bisher vor allem diese Richtung verwendet hab, war mein Rueckschluss eben dass es dann andersrum auch einheitlich sein muesste. Aber ok, wieder was gelernt.

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

ach ja: .splitlines() funktioniert natuerlich wunderbar und ist dann genau das was ich eigentlich von Anfang haette verwenden sollen. Und da es das gibt ist es natuerlich sehr sinnvoll dass der normale .split sich wirklich stur um genaue Uebereinstimmung kuemmert.
Benutzeravatar
Whitie
User
Beiträge: 216
Registriert: Sonntag 4. Juni 2006, 12:39
Wohnort: Schulzendorf

Hallo,
du könntest dir auch mal die Option -print_format ansehen. Ich benutze immer -print_format json und kann das Ganze dann prima weiterverarbeiten.

Gruß Whitie
Antworten