Anfänger(immer noch)-Frage zu Syntax und Kommentarzeilen

  • Avisynth(esizer) benutze ich zwar regelmäßig, aber immer nur ein und dasselbe Skript für die immer gleiche Routine. Meine Videos (MPEG2-Aufnahmen) sind größtenteils wie progressiv zu behandeln, nur hier und da tauchen - warum auch immer - Kammeffekte bzw. "Blends" auf, wo sich zwei Szenenbilder überschneiden. Es sollen kleine Avi's daraus werden (XviD).

    Nun würde ich gerne Kommentarzeilen einfügen, tue mich aber mit der Syntax schwer und weiss nicht, ob das Ergebnis noch dasselbe sein wird. Hier mein Übungsskript mit Kommentarzeilen:

    Warum muß man hinter der Klammer nach dem ersten ApplyRange "Video" schreiben, bei den folgenden ApplyRange aber nicht? Habe es ausprobiert und es kommt die Fehlermeldung "Invalid argument function ApplyRange line ...".

    Ist das Skript so plausibel? Ist es zu umständlich? Kann ich Kommentare schreiben wie ich will oder gibt es dafür auch bestimmte Regeln, an die man sich halten sollte?

  • Warum muß man hinter der Klammer nach dem ersten ApplyRange "Video" schreiben, bei den folgenden ApplyRange aber nicht?

    Doch, musst du. Weil du explizit die Clip-Variable "Video" verwendest, und ihr immer wieder eine weiter gefilterte Version des Videos zuweist, musst du auch allen Filterfunktionen mitteilen, dass sie die jeweils letzte Version des Clips "Video" als Quelle verwenden sollen.

    Wenn du als ersten Parameter in Filter-Funktionen, die das erlauben (in deren Dokumentation "...([clip,] ..." mit eckigen Klammern um "clip" steht), keine Clip-Variable verwendest, dann geht AviSynth davon aus, dass die interne spezielle Variable "last" das Video enthält, das als Quelle verwendet werden soll. Weil du zuvor aber das Zwischenergebnis immer schön brav an die Variable "Video" übergeben hast, hat "last" bisher gar keinen Videoinhalt.

    Das heißt: Du hast geschrieben

    PHP
    Video = ApplyRange(Video, 1234, 1234, "Yadif").ApplyRange(4321, 4321, "Yadif").ApplyRange(5000, 5000, "Yadif")

    was ausführlich eigentlich bedeutet

    PHP
    Video = ApplyRange(Video, 1234, 1234, "Yadif").ApplyRange(last, 4321, 4321, "Yadif").ApplyRange(last, 5000, 5000, "Yadif")

    aber du wolltest eigentlich

    PHP
    Video = ApplyRange(Video, 1234, 1234, "Yadif").ApplyRange(Video, 4321, 4321, "Yadif").ApplyRange(Video, 5000, 5000, "Yadif")

    Manchmal ist es einfacher (wenn auch nicht so schön eindeutig und ausführlich), gerade bei einer längeren Kette von Filtern auf die Clipvariable zu verzichten, und nur ab und zu dort "last" zu verwenden, wo eine notwendig ist:


    Wenn "return" fehlt, dann passiert das gleiche, als hätte man "return last" geschrieben. Eventuell ist AviSynth ein paar Millisekunden schneller, wenn alles explizit dasteht, aber das sollen die Profis dir erklären. Da ginge es dann nur noch um den kleinen Unterschied zwischen "effektiv" (funktioniert) und "effizient" (ist schnell).

    Auf gute Zusammenarbeit:

    REGELN befolgen | SUCHE benutzen | FAQ lesen | STICKIES beachten

    2 Mal editiert, zuletzt von LigH (3. November 2008 um 11:47)

  • Das mit dem impliziten Clip "last" hatte ich vorher nie so ganz verstanden, jetzt doch, danke. Wäre es also so korrekt aufgeschrieben:

    Version 1 (mit "last"):

    Code
    # Plugin ladenLoadCPlugin("C:\Programme\AviSynth 2.5\Externe Plugins\yadif09\yadif.dll")# Video ladenlast = Mpeg2Source("Pfad zur Projektdatei.d2v")# Resizenlast = Lanczos4Resize(last, 720, 576)# Deinterlace Anfanglast = ApplyRange(last, 0, 749, "Yadif")# Deinterlace nur einzelne Frameslast = ApplyRange(last, 1234, 1234, "Yadif"). \last = ApplyRange(last, 4321, 4321, "Yadif"). \last = ApplyRange(last, 5000, 5000, "Yadif")# Audio ladenAudio = NicMPASource("Pfad zur .mp2-Datei")# Video und Audio zusammenführenAudioDub(last, Audio)

    ... ist dasselbe wie Version 2 (ohne "last"):

    Code
    # Plugin ladenLoadCPlugin("C:\Programme\AviSynth 2.5\Externe Plugins\yadif09\yadif.dll")# Video ladenMpeg2Source("Pfad zur Projektdatei.d2v")# ResizenLanczos4Resize(720, 576)# Deinterlace AnfangApplyRange(0, 749, "Yadif")# Deinterlace nur einzelne FramesApplyRange(1234, 1234, "Yadif"). \ApplyRange(4321, 4321, "Yadif"). \ApplyRange(5000, 5000, "Yadif")# Audio ladenAudio = NicMPASource("Pfad zur .mp2-Datei")# Video und Audio zusammenführenAudioDub(last, Audio)

    ... ist dasselbe wie Version 3 (kurz und bündig, ohne Kommentarzeilen):

    PHP
    LoadCPlugin("C:\Programme\AviSynth 2.5\Externe Plugins\yadif09\yadif.dll")
    Video = MPEG2Source("...").ApplyRange(123,123,"Yadif").ApplyRange(1234,1234,"Yadif")
    Audio = NicMPASource("...")
    AudioDub(Video,Audio)

    Die letzte Version gefällt mir doch noch am besten, wenn sie denn richtig ist.

    Würde mir sehr helfen, wenn du nochmal drüberschaust.

  • 1) ist falsch: Nach einer Zeile, die mit ". \" aufhört, darf in der folgenden Zeile nicht noch mal "last = " am Anfang stehen, weil der Backslash am Ende eine Zeilenverkettung ist (zieht den Inhalt der folgenden Zeile hoch).

    2) klappt wahrscheinlich. Jedoch würde ich die beiden ". \" am Ende weglassen. Die sind nicht notwendig.

    3) sieht gut aus.

    __


    Aber es geht noch verketteter:

    PHP
    LoadCPlugin("C:\Programme\AviSynth 2.5\Externe Plugins\yadif09\yadif.dll")
    AudioDub(MPEG2Source("...").ApplyRange(123,123,"Yadif").ApplyRange(1234,1234,"Yadif"), NicMPASource("..."))

    Ich bezweifle allerdings, dass das noch "nützlich" ist. Vor allem das spätere Bearbeiten nach mehreren Monaten dürfte dann riskant werden. ;)

  • Den Punkt und Backslash ". \" habe ich gelöscht, jetzt muss es aber richtig sein. :) Gerade als Anfänger sollte ich wohl doch besser dieses ausführliche Skript mit dem expliziten Aufführen der Variablen "last" verwenden als die doch sehr verkettete Version.

    Es gefällt mir, weil es so übersichtlich ist. Da ich meine AVS-Dateien nicht lösche, weiss ich dann auch später noch, wie ich die Videos bearbeitet habe.

  • Wie verbindet man eigentlich mehrere Videodateien (Trailer und Film)? Es gäbe dann ja z.B. je zweimal Mpeg2Source und Audio. Auf die erste der Videodateien soll ein Resizer und ein Deinterlacer angewendet werden, auf die zweite aber nicht. Wie geht das mit der Variablen "last"?

    Ich könnte auch jedes Video einzeln bearbeiten und anschliessend zusammenfügen, aber ich wüsste gerne, wie es geht, habe aber bei meinen Selbstversuchen bisher keinen Erfolg.

    Hier mein Skript für nur ein einzelnes Video. Wo genau muß das zweite Video hin und wie erreiche ich, daß der Resizer und der Deintelacer nur das 1. Video bearbeiten?

  • "last" würde ich bei zwei Filmen vermeiden, und wirklich mit Variablen arbeiten. Insbesondere wenn nicht allzu viele Funktionen mit nicht allzu vielen Parametern verwendet werden, ist auch die Verkettungs-Syntax nützlich (dann muss aber alles, was mit Punkten verkettet ist, auch in einer Zeile stehen; oder man hebt die Zeilenumbrüche mit einem Backslash als allererstes Zeichen in der Zeile auf).

    "AlignedSplice(clip1, clip2)" {oder auch: "clip1 ++ clip2"} ist notwendig, damit der Ton von clip2 synchron zum Video bleibt, und nicht beim Zusammenfügen dort hin rutscht, wo der Ton von clip1 aufhört (dann könnte es ab dem Zusammenfügen asynchron werden, also bitte nicht "UnalignedSplice" oder nur "+" verwenden).

  • Das habe ich jetzt so gemacht wie von dir beschrieben und den Trailer mit dem Film verbunden und es hat super geklappt. Danke :)

    Nur eine Frage zur Reihenfolge der Filter. Habe ich mich vielleicht vertan in der Zeile:

    PHP
    video1 = Mpeg2Source("Film1.d2v").Lanczos4Resize(720, 576).Yadif()

    Habe hier im Forum irgendwo gelesen, daß der Deinterlacer immer am Anfang der Bearbeitungskette stehen sollte, also vor dem Resizer. Sollte ich das besser austauschen, also so:

    PHP
    video1 = Mpeg2Source("Film1.d2v").Yadif().Lanczos4Resize(720, 576)
  • Es geht darum, dass du vor einem Deinterlacing auf keinen Fall die Höhe des Videos ändern solltest, denn ein Deinterlacer braucht die Zeilen des Videos unverfälscht in ihrer Abfolge übereinander.

    Abgesehen davon ist auch sonst eine Änderung auf 720x576 Pixel für mich etwas fragwürdig... denn wenn deine Videoquelle auch MPEG2 ist, dann hat sie vielleicht schon 720x576 Pixel? -- Anders gefragt: Welche Dimensionen hat dein Originalfilm?

  • Mein Originalfilm ist eine digitale TV-Aufnahme von CNBC und die senden in der Auflösung 480*576. Bei der MPEG2-Datei ist es ja kein Problem, da die rechteckigen Pixel vom Decoder automatisch auf die richtige Breite gezogen werden.

    Bei der XviD-Kompression (AVI-Datei) habe ich deshalb den Resizefilter dazugenommen und bin dann gestolpert über die Frage, ob erst der Resizer oder erst der Deinterlacer aktiv werden muß. Habe dich so verstanden, daß ein Deinterlacer nur dann unbedingt vor dem Resizefilter aktiv werden sollte, wenn die "Höhe" des Videos geändert wird (also nicht die "Breite", wie in meinem Fall). Ist das richtig?

    (Nochmals danke für die Hilfe bei der Verbindung von zwei Videos. Das war das, was ich gesucht habe und es ist ein nahtloser Übergang von Film1 zu Film2.)

  • Wenn das Ergebnis ein XviD-AVI werden soll, dann gibt es zwei Möglichkeiten, mit anamorph gestauchtem Quellmaterial umzugehen:

    a) Das Video anamorph lassen und im XviD-Codec eintragen, dass der Film vom Decoder beim Abspielen entzerrt werden soll. Das werden DivX-Player wahrscheinlich nicht verstehen, am PC sollte es aber funktionieren.

    b) Man entzerrt vor der Encodierung. Dann aber nicht auf 720 Pixel Breite. Denn auch das Video auf "4:3"-DVDs wäre gestaucht, 576 Zeilen * 4:3 = 768 Pixel pro Zeile

    Je nach Material befand sich auf einer DVD auch bei "4:3"-Seitenverhältnis leicht gestauchtes Video: Entweder von 768 auf 720 Pixel = "Generic PAR", oder von 768 auf 702 Pixel und seitlich aufgefüllt = "ITU-R BT.601 PAR". Bei 16:9-anamorphem Video erst recht: 576 * 16:9 = 1024 - also 1024 Pixel pro Zeile entweder auf 720 Pixel, oder auf 702 Pixel und aufgefüllt.

    Wenn es vorher 576 Zeilen waren, und hinterher immer noch 576 Zeilen sein sollen, gibt es keine Probleme mit dem Deinterlacer. Nur wenn sich die Zeilenanzahl ändert, sollte man vorher deinterlacen, weil ein Deinterlacer mit "Mittelwerten aus übereinanderliegenden Zeilen", die ein Resize-Filter bei Höhenveränderungen berechnen würde, nicht klarkommt.

  • Es geht darum, dass du vor einem Deinterlacing auf keinen Fall die Höhe des Videos ändern solltest, denn ein Deinterlacer braucht die Zeilen des Videos unverfälscht in ihrer Abfolge übereinander.

    Ich habe eine Verständnisfrage zur Reihenfolge der Filter:
    Mein Video ist MPEG2 in 720*576 im 16:9-Format. Die rechteckigen Pixel werden beim Anschauen vom WM-Player etc. auf die korrekte Breite gezogen. Daraus möchte ich mit XviD eine AVI erzeugen und zwar mit schwarzen Balken oben und unten, damit das Seitenverhältnis weiterhin stimmt.
    Muß in diesem Fall Yadif als Deinterlacer vor oder nach dem Resizen und Add Borders stehen? Die Höhe wird ja nicht verändert, wohl aber die schwarzen Balken kommen dazu ... Ich versteh's nicht so richtig. Ist das Skript so ok?

  • Sicher wird die Höhe verändert - nach der Anwendung von "LanczosResize", und vor der Anwendung von "AddBorders". Also zwar nur zwischenzeitlich, aber überhaupt.

    Es geht darum, ob die Höhe überhaupt so verändert wird, dass vertikal Zwischenwerte berechnet werden müssen. Also ob überhaupt ein Resizer verwendet wird, der bei seinem Aufruf die Höhe ändert. Nicht, ob irgendwann am Ende die Höhe wiederhergestellt wird.

    Allgemeine Grundregel ist: Deinterlacer möglichst gleich nach dem Source-Filter anwenden. Es sei denn, man hätte Filter, die auf Interlaced-Material besser anwendbar wären.

  • Ja, jetzt ist es mir auch klar - zwischen Resizer und AddBorders wird die Höhe verändert, also muß der Deinterlacer ganz davor zur Anwendung kommen.

    Mein Skript kann also so bleiben. DANKE!!! :)

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!