Anhand eines Wertes vermtl. Restdauer und Dateigröße finden

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
Barabbas
User
Beiträge: 349
Registriert: Dienstag 4. März 2008, 14:47

Hallo,

ich spiele gerade etwas mit dem mencoder herum und lese dessen Output aus. Leider stimmen die Angaben von mencoder in bestimmten Situationen nicht, so dass ich vorraussichtliche Dateigröße und Restzeit selbst ermitteln muss.
Glücklicherweise habe ich einen zutreffenden Prozentwert des Fortschrittes, so dass ich mit diesem und dem Zeitdelta ermitteln kann, wie lange mencoder vermutlich noch läuft.

Meine Frage: Gibt es dafür irgendwelche pythonischen Werkzeuge? Mein Problem ist, dass ich beispielsweise die Dateigröße mit dem Zeit-, Größendelta und der zuvor errechneten vermuteten Restdauer berechne: Ich schaue also, wieviel Zeit vergangen ist, wieviel Zeit mencoder noch läuft und kann dadurch die Dateigröße prognostizieren.

Natürlich schwanken die Werte alle recht stark, weshalb ich Listen mit den letzten 100 Werten erstelle und die Summe dieser Werte durch 100 teile - insgesamt also eine ziemlich hässliche Sache.

Darum meine Frage: Hat jemand von euch eine Idee, wie man sowas elegant löst?

Danke schomal und schönen Gruß,

brb
Benutzeravatar
snafu
User
Beiträge: 6744
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Man kann bei solchen Prozessen im Gegensatz zu Kopiervorgängen halt nicht sagen, wie groß das Ergebnis am Ende sein wird. Man kann nur sagen, wieviel von der Eingangsdatei schon bearbeitet wurde und muss das eben hochrechnen. Nichts anderes tun MEncoder und du ja auch. Ich wüsste nicht, wie man da an einen exakten Wert kommen soll.
Barabbas
User
Beiträge: 349
Registriert: Dienstag 4. März 2008, 14:47

Ja, ist schon richtig. Für die Hochrechnung benötigt man ja zwei Werte: Zeit und irgendeinen Fortschritt. Die beiden Werte habe ich. Die jeweils immer 512 Bytes vom mencoder-Output in einer Schleife lese, habe ich pro Sekunde (geschätzt) 50 Schleifendurchläufe (nennen wir mal "Ticks").

Wenn ich in jedem Tick einmal die Dateigröße und Restzeit berechne, schwanken die Werte extrem stark, besonders weil die Datei ja nur in großen Abständen geschrieben wird (sie wird natürlich kontinuierlich geschrieben, aber das OS "flush"t ja nur in bestimmten Intervallen (nicht jeder Schreibzugriff wird also direkt auf die HD geschrieben). Vielleicht buffert mencoder auch noch zustätzlich. Dadurch hat man natürlich den Effekt, dass die Werte extrem stark schwanken. Ein Beispiel:

Die Datei ist nach 5 Sekunden 50 Megabyte groß, die Verarbeitung wird noch weitere 5 Sekunden laufen. Jetzt ein paar Berechnungsstufen:

Code: Alles auswählen

nach 5von10 Sekunden, Datei 50 MB groß: Prognostizierte Größe 100 MB
nach 6von10 Sekunden, Datei 50 MB groß: Prognostizierte Größe 83 MB
nach 7von10 Sekunden, Datei 50 MB groß: Prognostizierte Größe 71,4 MB
FLUSH - Gebufferte Daten werden auf den Datenträger geschrieben
nach 8von10 Sekunden, Datei 90 MB groß: Prognostizierte Größe 112,5 MB
nach 9von10 Sekunden, Datei 90 MB groß: Prognostizierte Größe 100 MB
Wenn man sich nun noch vorstellt, dass ich nicht einmal pro Sekunde sondern 50 Mal pro Sekunde berechne, kann man die Auswirkungen auf die Stabilität der Berechnung leicht absehen: Nach einem Flush sind die Werte extrem hoch, sinken dann während der folgenden Durchläufe kontinuerlich ab. Dann kommt wieder ein Flush, die Werte springen wieder auf einen (ztu hohen) Wert und sinken erneut ab etc. pp.


Ganz kurz also: Um solche Berechnungen also machen zu können, braucht man a) eine zeitliche Verzögerung und b) die Möglichkeit, Extremwerte rauszufiltern und den Durchschnitt zu berechnen. Und da suche ich halt nach einer generischen Lösung. Sowas wie das "Python Estimation Module" (Name erfunden). Ich habe zwar schon eine Implementierung versucht, die ist aber einfach nur "krank".

Ich hoffe, ich konnte mich verständlich machen.

Besten Gruß,

brb
Benutzeravatar
snafu
User
Beiträge: 6744
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Wieso nicht das Problem an der Wurzel packen? Du wirst die Ausgabe von Mencoder ja sicher über eine Pipe lesen. Bei Pipes wird leider blockweise gepuffert. Welche Auswirkungen das für eine Art Live-Ausgabe hat, merkst du selbst. Meines Wissens kann man dies nur beeinflussen, wenn man anstatt der Pipe dem Programm vorgaukelt, dass es in ein Terminal schreiben würde. Auf der Homepage von Pexpect wird die Thematik IMHO ganz gut beschrieben (Link). Meine Empfehlung daher: Nutze entweder Pexpect als Abhängigkeit oder implementiere die Funktionsweise selbt.

Für die Anzeige eines Fortschritts in Python existiert übrigens das Tool ProgressBar. Desweiteren möchte ich bescheiden anmerken, dass ich momentan an Callisto arbeite, welches komfortabler, konfigurierbarer und umfangreicher als ProgressBar sein soll/wird. Für eine spätere Version ist auch das livemäßige Parsen von fremden Output geplant. Nur derzeit ist die Entwicklung dabei etwas eingeschlafen...
Barabbas
User
Beiträge: 349
Registriert: Dienstag 4. März 2008, 14:47

Hallo snafu,

vielen Dank für deine Antwort - Pexpect könnte - sowie es unter dem Link beschrieben wird - das Problem tatsächlich an der Wurzel packen. Ich werde mir das mal genauer ansehen.

Auf Callisto bin ich hier im Forum tatsächlich auch schonmal gestoßen. Sieht wirklich ganz gut aus, allerdings habe ich meine ProgressBar mit PyGTK realisiert.

Wie gesagt: Vielen Dank für deine Hilfe,

brb

//edit:
Ich habe übrigens ein wunderbares Workarround gefunden: Mencoder spuckt wie gesagt bisweilen gehlerhafte Werte aus (so wie ich das sehe, häufig dann, wenn er direkt von einer DVD lesen soll). Korrekt sind aber die Angaben von Position (in Sekunden) und FPS. Weil in den FPS bereits eine Sekunde drinsteckt, kann man daraus die vermutete Restzeit berechnen, ohne irgendwelche Timer zu benötigen:

Code: Alles auswählen

total_frames = VIDEO_LENGTH_IN_SECONDS*25
frames_to_go = total_frames - (int(CURRENT_POSITION) * 25)
eta = (frames_to_go  / int(FPS)) /60
CURRENT_POSITION und FPS gibt der mencoder - wie gesagt - richtig zurück. Vielleicht hilft es ja irgendwem; eigentlich echt trivial, aber wenn man erstmal auf dem Falschen Weg ist... ;)
Antworten