AVISynth und programmierung

  • Mammamia, da wollte ich mich mal etwas intensiver mit AVISynth befassen und auch ein wenig Programmierung lernen, aber ich scheitere bereits an simplen Schleifen. Spinn' ich, oder sind Schleifen wirklich nur durch Rekursion möglich?

    Die Aufgabe, die ich mir selber stellte war, einen schwarzen Clip mit immer heller werdenden Streifen zu verbreitern - es sollte ja einfach bleiben ... ha! ;) . Dazu sollte ein Counter pro Durchlauf um 16 erhöht werden, solange er kleiner als 236 ist. Bei jedem Durchlauf sollte außerdem ein schwarzer Clip um den Wert vom Counter mit Tweak aufgehellt und mit StackHorizontal an den bisherigen Clip angehängt werden. Aber alles was ich hinbekommen habe, waren üble Abstürze und Syntax-Fehler.
    Kann mir mal jemand da ein wenig auf die Sprünge helfen?

  • @katja
    Das bringt eigentlich nicht viel, weil hier der Weg das Ziel war.
    Aus 16 Balken von je 44 Pixel Breite sollte ein Bild zusammengesetzt werden, das von links nach rechts aufsteigend in 16ner-Schritten die Luma-Werte von 16-236 enhalten sollte.

    In C etwa so:

    clip1=BlankClip(length=300, width=44, height=256, fps=25, pixel_type="yuy2", color=$000000);
    clip2=clip1;
    counter=16;

    if (counter<=236) {
    StackHorizontal(clip1,Tweak(clip2,bright=counter));
    counter+=16;
    }
    Return(clip1)

  • aber es geht nicht so, weil der Film ja immer größer wird.Oder wie oder was?

    Male das mittle und das Final Bild Trotzdem.
    ich kann mir das sonst nicht vorstellen.

    hab schon ne Idee mit ScriptClip oder Animate.

    EDIT1:
    erstmal Stufenlos ohne *16

    Code
    clip1=BlankClip(length=300,width=44,height=256,fps=25,pixel_type="yuy2",color=$000000)Clip2=Animate(clip1,0,236,"Tweak",0,0,16,0,0,236)StackHorizontal(clip1,clip2)


    EDIT2:
    jetzt mit 16

    Code
    clip1=BlankClip(length=300,width=44,height=256,fps=25,pixel_type="yuy2",color=$000000)
    Clip2=Animate(clip1,0,236,"Tweak",0,0,16,0,0,236).SelectEvery(16,0)
    StackHorizontal(clip1,clip2)


    Und Du willst jetzt

    Balken1 = Tweak0
    Balken2 = Tweak16
    Balken3 = Tweak32
    usw?

    ui Robby Zeit........

  • @katja

    Zitat


    Und Du willst jetzt
    Balken1 = Tweak0
    Balken2 = Tweak16
    Balken3 = Tweak32
    usw?



    Genau das war das Ziel, ja. Wobei als Endergebnis ein Bild von 704x288 mit exakt 16 Balken entstehen sollte.
    Dabei stand aber mehr das Erlernen der Syntax an sich im Vordergrund, weniger das Ergebnis (das aber trotzdem richtig sein sollte ;) ).
    Ich habe vor vieeeelen Jahren mal in reinem C und Z80- sowie 86K-Assembler programmieren gelernt. Aber OOP und AVISynth allgemein stellen mich vor Rätsel - viele Rätsel.
    Ich krieg' echt die Kriese, wenn ich sehe, wie Leute wie Didée oder scharfi auch komplexe Scripts anscheinend einfach so aus dem Ärmel schütteln - das will ich auch können *grummel* ;)
    Aber bevor ich mich an komplexe Problemstellungen heranwage, möchte ich erstmal AVISynth verstehen lernen - und das wehrt sich! *unerhört!* ;)

  • Hm, mal davon abgesehen, dass das Sript bei mir nicht funktioniert, sehe ich da nichts, was sich als echte Schleife bezeichnen ließe.
    WAS ich sehe, sind jede MEnge syntaktischer Feinheiten, die mich in den Wahnsinn treiben. Irgendwie kann ich mich mit der Fallentscheidung ? 1 : 2 nicht so recht anfreunden... *seufz* Mir stecken wohl die "alten" Programmiermethoden zu sehr in den Knochen. "Wenn das da wahr ist, dann mach das da, basta" ist eher die Art, wie ich früher mal programmieren konnte.

  • Zitat von Kika

    Aber bevor ich mich an komplexe Problemstellungen heranwage, möchte ich erstmal AVISynth verstehen lernen - und das wehrt sich! *unerhört!* ;)
    /----/
    Irgendwie kann ich mich mit der Fallentscheidung ? 1 : 2 nicht so recht anfreunden...


    Sieh's doch mal als "Übersetzung":

    IF condition THEN do_this ELSE do_that

    Streiche "IF", ersetze "THEN" --> "?", und "ELSE" --> ":"

    condition ? do_this : do_that


    Ebenfalls als Programmierer alter Schule (seit ca. 13 Jahren keinen Compiler mehr angefasst) sag ich mal: AviSynth Scripting ist einfach, wirklich einfach. Alles nur eine Sache der Semantik - man muss sich halt daran gewöhnen.

  • Zitat

    man muss sich halt daran gewöhnen.



    Tja, an die einfachen Dinge habe ich mich inzwischen auch gewöhnt, komplexere Strukturen bereiten mir aber nach wie vor Schwierigkeiten. Und ich bin so an das Programmieren mit Schleifen - welcher Art auch immer - gewöhnt, dass ich ohne fast "nackt" dastehe.

    Ich hatte versucht, das Balken-Problem mit einer Funktion zu lösen, die sich selbst aufruft, das hat aber jedesmal geknallt. Sowas zum Beispiel:



    Sowas wie das hier funktioniert allerdings:



    Da ist mir allerdings die Syntx nach wie vor ein Rätsel

  • Vielleicht solltest du dir auch nochmal folgendes verinnerlichen:
    über das skript wird eine Schnittliste erstellt, das skript wird also "von hinten" in eine Art Zugriffsbaumstruktur zerlegt und NICHT wie ein normales C/Basic-Programm "durchlaufen".
    Die obigen Versuche sind eigentlich ziemliche Grenzfälle der skript-Sprache.
    Da es sicher noch einige Lücken in der Fehlerbehandlung gibt, kann man grade bei rekursiven skripts schon mal einen crash erreichen.

    Im obigen Beispiel fällt mir da folgendes auf.
    (1) Die Zeile
    StackHorizontal(clip1,Tweak(clip2,bright=counter))
    heisst ja
    last = StackHorizontal(clip1,Tweak(clip2,bright=counter))
    Das wolltest du sicher nicht.

    (2) eine Funktion, die in der Schnittliste nicht gebraucht wird, wird auch nicht aufgerufen. Da "last" nie zurückgegeben wird, kommen deine Funktionen auch nicht zum Tragen.

    (3) Ich glaube, jede user-Funktion muss einen Rückgabewert haben

  • Zitat

    heisst ja
    last = StackHorizontal(clip1,Tweak(clip2,bright=counter))



    Hm, so aufgelöst aber ich das noch gar nicht betrachtet.
    Aber wieso funktioniert dann das zweite Script? Das ist ja auch eine Rekursion, wenn auch anders aufgebaut.

    Ich denke, ich werde die Sache nochmal neu beginnen. Die Ähnlichkeit der AVISynth-Syntax zu C scheint mich da in eine Sackgasse geführt zu haben.
    Leider sind alle AVISynth-Anleitungen gerade auf diesem Gebiet nicht gerade sehr ergiebig.

    Das Problem, was ich mit AVISynth generell noch habe ist, dass ich mich viel stärker auf AVISynth selbst konzentrieren muss als auf das eigentliche Problem.
    Wie auch immer, ich habe ScriptClip und ConditionalReader "überlebt", dann schaffe ich das hier auch noch... irgendwann. ;)

  • das zweite script funktioniert, weil direkt im "return" bei jeder Bedingung ein clip zurückgegeben wird (durch das return wird das "last" sozusagen unterdrückt).
    Ich glaube auch (da muss ich mal forschen)
    - dass eine user-funktion einen Wert zurückgeben MUSS
    - an eine Funktion wird alles (auch globale Variablen) nur byvalue (also als Kopie) übergegen. Man kanns daher in der Funktion nicht ändern.

  • Haaalt, langsam ...

    >> Ich glaube
    >> - dass eine user-funktion einen Wert zurückgeben MUSS

    Jup. Und wenn man nichts explizit zurückgibt, dann wird halt 'last' zurückgegeben:

    function ABC(clip c) { c.filter() }

    gibt auch ohne return() als Ergebnis c.filter() zurück.


    >> - an eine Funktion wird alles (auch globale Variablen) nur byvalue (also als
    >> Kopie) übergegen. Man kanns daher in der Funktion nicht ändern.

    Globale Variablen kann man sehr wohl ändern, sie müssen/brauchen/dürfen zu diesem Zweck auch gar nicht "übergeben" zu werden: sie sind ja global, also "immer present". z.B. in Restore24 gibt's reihenweise

    global var=0
    ...
    function juhuu( ) { global var = tralala }

    So richtig Sinn macht das aber nur bei Funktionen innerhalb der cond.environment, oder bei rekursiven Funktionen.
    ... oder Bei Spezialfällen wie z.B. den MVTools, die intern mit globalen Variablen arbeiten (wenn man eine Funktion hat, die Bewegungsvektoren sucht, sollte man per globalem Counter bei jedem Funktionsaufruf die idx-Variable um +1 erhöhen) :seher:

  • Zitat

    So richtig Sinn macht das aber nur ..... bei rekursiven Funktionen.



    Genau deshalb habe ich's ja auch ohne Parameter, sondern mit globalen Variablen versucht. Und Rekursionen ohne globale Variablen... die kann ich mir nun wirklich nicht vorstellen. ;)

  • Wieso nicht? die folgende Rekursion läuft 10x durch, ganz ohne globale Variablen. (Macht zwar nichts wirklich sinnvolles, aber man kann ja andere Berechnungen dazwischenhängen) :

    last.reccount(10)

    function reccount(clip c, int counter) {
    counter==0 ? c.subtitle(string(counter)) : c.reccount(counter-1) }

  • Aha, wieder was gelernt. :)

    Aber dann mal gleich die dumme Frage hinterher: Wie ist die Syntax, wenn ich z.B. bei count!=0 zwei Befehale abarbeiten lassen will, bei count==0 aber nur einen? Damit hatte ich nämlich auch so meine Probleme.
    Ebenfalls (noch) unverständlich ist mit dieser clip c. Mit c und counter sind's ja zwei Variablen... verwirrend

  • Zitat

    Ebenfalls (noch) unverständlich ist mit dieser clip c. Mit c und counter sind's ja zwei Variablen... verwirrend


    Clip c war hier nur deswegen drin, um überhaupt irgendwas sinnvolles zurückzugeben.
    Hmmh ... anderes Beispiel: eine Zahl soll n-mal quadriert werden:

    Code
    Startwert = 3wieoft_quadrieren = 5gesuchter_wert = quadriere_n_mal(Startwert, wieoft_quadrieren)function quadriere_n_mal(float base, int times) {base = base^2times == 1 ? base : quadriere_n_mal(base, times-1) }


    Zitat

    Wie ist die Syntax, wenn ich z.B. bei count!=0 zwei Befehale abarbeiten lassen will, bei count==0 aber nur einen?


    Heheh, gut Frage. Je nach genauem Fall kann man's einfach hinschreiben, oder muss (wegen Avisynth's Grammatik) einen Trick bemühen:

    a) Sub-Funktionen erstellen
    b) stickboy's Evaluate(String) - Trick

    edit: im String-Beispiel war etwas vertauscht ... jetzt stimmt's (hoffentlich).


    Naja, ob's damit jetzt wirklich verständlicher geworden ist ... ? :hm:

    Und dann ist da ja noch die Geschichte mit linksoffenen, rechtsoffenen, oder mittig geöffneten Rekursionen ...
    /*graue-Haare-krieg'*/ :)

  • Zitat

    Clip c war hier nur deswegen drin, um überhaupt irgendwas sinnvolles zurückzugeben.



    Also gewissermaßen ein Dummy.

    Zitat


    anderes Beispiel: eine Zahl soll n-mal quadriert werden:



    DAS hab' ich jetzt sogar verstanden. ;)

    Zitat


    a) Sub-Funktionen erstellen



    OK, auf die Idee war ich bereits gekommen.

    Zitat


    b) stickboy's Evaluate(String) - Trick



    Autsch! :D

    Zitat


    Naja, ob's damit jetzt wirklich verständlicher geworden ist ... ?



    Einiges ja, natürlich bleibt dann noch genügend offen, was ich einfach testen muss, aber das hier ist schon mal eine Grundlage, auf der ich aufbauen kann, danke. :)

    Zitat


    Und dann ist da ja noch die Geschichte mit linksoffenen, rechtsoffenen, oder mittig geöffneten Rekursionen ...



    ARGH! *totumfall*

  • Um das Prinzip der Rekursion zu verstehen, muß man zunächst einmal das Prinzip der Rekursion verstanden haben.

    *SCNR* :D

    Ich habe mir schon ab und zu den Komfort einer richtigen Programmiersprache in AviSynth gewünscht. Gerade wenn man den Film nur als Ganzes bearbeitet (Filter) bzw. schneidet (trim), fallen die Unterschiede nicht so auf. Dann wundert man sich, daß manche Sachen einfach nicht gehen.

    Zap

    "Wer grundlegende Freiheiten aufgibt, um vorübergehend ein wenig Sicherheit zu gewinnen, verdient weder Freiheit noch Sicherheit."
    Benjamin Franklin

    mein Rechenknecht

Jetzt mitmachen!

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