Tutorial für die Videobearbeitung mit AVISynth LPer Spezifisch

Ich brauche deine Hilfe, um den Fortbestand des LetsPlayForums zu sichern: Mehr Informationen findest du hier!
  • Stand: 24. August 2013 (Noch im Aufbau) | Die einzelnen Videos zu den entsprechenden Abschnitten kommen im September definitiv jetzt und werden euch Visuel durch das Tutorial führen. Damit ist es euch überlassen, ob ihr euch das anlesen tut hier oder euch das anschauen wollt. ;D


    Index


    Einleitung
    So, ein herzliches Willkommen schon mal hier, für das Tutorial zur Videobearbeitung mit AVISynth.


    AVISynth wird euch hier im Forum ständig gegen den Kopf geworfen in Zusammenhang mit [lexicon]MeGUI[/lexicon]. Doch was ist dieses AVISynth eigentlich erst mal?


    AVISynth ist in erster Linie ein [lexicon]Frameserver[/lexicon] der per Script gesteuert wird. Sogenannte AVS Skripte. Bedeutet das AVISynth keine Grafische Benutzeroberfläche benötigt um eine Videobearbeitung zu realisieren. Zudem ist AVISynth vollkommen kostenlos und kann wie auch schon oft erwähnt im Forum, Sachen machen wo andere kostenpflichtige Programme scheitern.


    Warum eigentlich Frameserver? Weil AVISynth mittels der AVS Skripte alle Frames die entweder geladen wurden oder erzeugt wurden von A nach B liefert, damit andere Programme die mit AVISynth zusammenarbeiten diese auch verarbeiten können.


    Ich werde euch in diesem Tutorial nicht nur per Video Beispiele und Tricks zeigen, sondern euch auch Skripte hier direkt erklären.


    Das wird so in etwa die Tiefe haben für euch, das es für LPer 100% ausreichen wird.

    ^^


    Für das editieren des Scriptes kann jeder Texteditor genommen werden. Ich empfehle euch aber den kostenlosen AvsP Editor mit dem ihr auch gleich eine Vorschau habt und zusätzliche Infos in der Unteren Leiste.


    Downloaden könnt ihr den AvsP Editor auf der Hauptseite von AVISynth
    Oder den AvsPmod von der Doom9 Seite - Sogar um einiges besser ;D


    Grundlegende Sachen die man Wissen muss (Mathematik bleibt nicht aus)
    Wer mit AVISynth arbeiten will hat keine Zeitangaben, da das Skript mit Frames arbeitet. Um sich aber nich zu verrennen mit Frames bedient man sich folgender Rechnungen:


    Frames / FPS = Time(sek)


    Time(sek) * FPS = Frames


    Frames / Time(sek) = FPS


    Das sollte den Leuten in Elektrotechnik bekannt vorkommen mit Wiederstand, Spannung und Stromstärke. Man könnte es hier genauso machen und es in ein Dreieck stecken

    ^^



    Dann gibt es noch Rechnungen bezüglich der Positionen. Wir haben ein Bild mit x und y Koordinaten. Diese werden in Pixelpositionen angegeben. (Abkürzung px). Dabei ist die Position 0,0 in der oberen linken Ecke und die max x und max y Position an der unteren rechten Ecke.


    Bei Zentrierungen für Bild in Bild, Thumbnails, Schriftzeichen etc. muss oft mit dem Mittelwert gerechnet werden. Als Beispiele werde ich das immer an einem 1080p Videos machen. Natürlich sind die Rechnungen alle identisch zu jeder anderen [lexicon]Auflösung[/lexicon].


    Um eine Aufnahme so Seitenverhältnismäßig genau zu skalieren bedient man sich wieder einer Rechnung die wie folgt aussieht:


    Unser [lexicon]Quellvideo[/lexicon] hat jetzt mal ganz dämliche Werte von 224x400 und wir wollen das auf 1080p hochskalieren.
    Also rechnen wir:


    (224 * 1080) / 400 = 604,8


    Also beträgt die exakte neue [lexicon]Auflösung[/lexicon] 604,8 x 1080 . Da Kommastellen aber unschön sind und meist zu Fehlern führen rundet man am besten auf die nächst gerade Zahl. Hier währe es also 604 x 1080. Ich hab bewusst 604 genommen, da 605 ungerade ist und bei vielen Programmen wie [lexicon]MKV[/lexicon] Merge zu abstürzen führen kann.


    Die Rechnung sollte aus der Mathematik bekannt sein indem man den Fehlenden Wert durch ein Kreuzverfahren ermittelt.
    224/400 = x/1080 in diesem Fall. Hier wird einfach nach x aufgelöst. ;D



    Farbangaben werden Hexadezimal angegeben. Das klingt jetzt komplizierter als es ist. Ihr habt einen bestimmten Farbraum zur Verfügung der durch R G und B bestimmt wird. Diese Werte können für R, G oder auch für B von 0 - 255 gehen.


    Um aber Speicher zu sparen haben sich Programmierer damals gedanken gemacht und bedienen sich Hexadezimalzahlen mit der Baisis 16. Um nicht weiter ins Detail zu gehen um euch zu langweilen warum und wieso das so gemacht wird (Weil kann man auf Wikipedia nachlesen wunderschön), hier mal ein Beispiel wie so eine Umrechnung aussieht:


    255 / 16 = 15 Rest 15
    15 / 16 = 0 Rest15
    15 = F
    Also FF


    235 / 16 = 14 Rest 11
    14 / 16 = 0 Rest 14
    11 = B
    14 = E
    Also EB


    Immer den Restbetrag von hinten nach vorne lesen um den Wert zu erhalten. Die Farbangabe wird dann durch ein $ Zeichen gekennzeichnet und sieht im Script dann so aus z.B.: $FF0EEB . Also R 255, G 14, B 235


    Das wars erst mal zur Grundrechnung die man benötigt in AVISynth. Taschenrechner von Vorteil ;D



    Das erste Skript soll ein Intro sein ohne etwas zu laden.


    (Video erscheint hier)


    Es geht weiter. Und ich werde euch hier selbstverständlich auch noch ein Video dazu machen. ;D


    Wir sitzen also vor unserem leeren AVS Script und wollen uns ein Intro erstellen wo ganz simple nur ein Schriftzug eingeblendet und ausgeblendet werden soll. Aber es soll nix geladen werden, sondern einfach komplett neu im Script entstehen.


    Dafür brauchen wir erst einmal ein Bild auf das wir arbeiten können. Sozusagen unsere Spielwiese ;D


    Hier müssen wir wissen wie groß der Clip werden soll und wievel FPS das ganze haben soll und wie lang der Clip gehen soll. Ich werde das mit 30 Sekunden machen mit 30FPS bei einer [lexicon]Auflösung[/lexicon] von 1920x1080.
    Also rechnen wir mit 30 * 30 = 900
    Also wird das Video 900 Frames betragen. Das Bild erzeugen wir mit Blankclip wie folgt:


    BlankClip(length=900, width=1920, height=1080, fps=30)


    Jetzt haben wir schon mal ein leeren schwarzen Clip von 30 Sekunden und 900 Frames.
    Die Hintergrundfarbe kann man natürlich ändern, indem man den Befehl mit color erweitert.


    BlankClip(length=900, width=1920, height=1080, fps=30, color=$0000FF)


    Jetzt haben wir anstatt einer schwarzen Fläche, eine blaue. Die Farbe könnt ihr natürlich bestimmen wie ihr wollt.
    Um Fehler zu entgehen durch spätere Video und Sound zusammknüpfungen, legen wir uns hier eine leere Audiospur an für diesen Clip.
    Dafür ergänzen wir einfach den Befehl mit Audio_rate


    BlankClip(length=900, width=1920, height=1080, fps=30, color=$0000FF, audio_rate=44100)


    Jetzt haben wir schon einen Clip mit 900 Frames, eine [lexicon]Auflösung[/lexicon] von 1920x1080, 30 FPS, einer blauen Videofläche wo noch nix drauf ist und eine leere Audiospur erzeugt. Zudem beträgt das Video haargenau unsere 30 Sekunden. Audioinfo ist momentan 44.1Khz Mono mit 8bit.


    Jetzt kommt die Schrift hinzu die wir zentriert auf die Fläche haben wollen. Also eröffnen wir eine nächste Zeile mit Subtitle.


    Subtitle("Mein erstes AVISynth Video")


    Damit wird ein gelber Sub oben in die linke Ecke auf Position 0, 0 geschrieben. Um Untertitel zu positionieren gibt es 9 unterschiedliche Ausrichtungen. Einmal 1 = unten/links, 2 = unten/mitte, 3 = unten/rechts, 4 = mitte/links, 5 = mitte/mitte, 6 = mitte/rechts, 7 = oben/links, 8 = oben/mitte und 9 = oben/rechts
    Diese Werte werden in der Funktion align eingetragen, den wir jetzt mal hinzufügen werden:


    Subtitle("Mein erstes AVISynth Video", align=5)


    Ihr könnt die Position aus selbst bestimmen mit x und y Werten. Wenn ihr das machen solltet, ist eine Ausrichtung mit align total überflüssig. Um das mit x und y Werten an eine bestimmte Position zu setzen macht man folgendes:


    Subtitle("Mein erstes AVISynth Video", x= 367, y=654)


    So könnt ihr das manuell da hinsetzen wo ihr den Text haben wollt.
    Als nächstes kommt das hinzufügen von Farbe, Schriftgröße und Schriftzeichen(Font). Dafür ändern wir wieder unseren Subtitle Befehl wie folgt:


    Subtitle("Mein erstes AVISynth Video", font="Comic Sans MS", size=60, text_color=$FFFFFF, align=5)


    Hinzugekommen sind die Parameter font, size und text_color
    Damit ist unser Schriftzug erst mal fertig soweit.


    Der letzte Schritt betrifft das einblenden und ausblenden. Mit einem zweiten Clip hätte man auch ganz einfach eine Überblendung machen können mit dem Befehl Dissolve. Den werd ich im späteren Tutorialverlauf noch verwenden. Hier reichen uns für den Anfang Fadein und Fadeout. Bei der internen Fadein und Fadeoutfunktion wird eine Bildblende gemacht. Bedeutet: Nicht die Subs werden angesprochen bei diesem Befehl, sondern das entsprechende aktuelle Overlay in dem das ganze passiert. (Zu Overlay werd ich auch später noch kommen)


    Wir haben unser Hintergrundvideo blau gemacht. Demnach sollten wir, wenn wir nur den Text Effektmäßig ansprechen wollen auch in Blau blenden.
    Dazu machen wir eine neue Zeile mit Fadein und Fadeout


    Fadein(100, color=$0000FF).Fadeout(100,color=$0000FF)


    Damit wird der Text für 100 Frames ein und Ausgeblendet. Also insgesamt 200 Frames. Das passiert am Anfang und am Ende des Gesamt Overlay Clips.


    Damit ist das Intro fertig und euer erstes selbst erstelltes Video mit AVISynth. Eine Farbconvertierung seitens [lexicon]MeGUI[/lexicon] sollte automatisch geschehen. Ansonsten setzt man den Befehl ConvertToYV12() noch an letzter Stelle.


    Hier noch mal alles im Überblick:

    Code
    BlankClip(length=900, width=1920, height=1080, fps=30, color=$0000FF, audio_rate=44100)
    Subtitle("Mein erstes AVISynth Video", font="Comic Sans MS", size=60, text_color=$FFFFFF, align=5)
    Fadein(100, color=$0000FF).Fadeout(100,color=$0000FF)
    ConvertToYV12()


    Damit beende ich erst mal das Anfangstutorial und werde die nächsten Tage bestimmt das nächste starten und euch weiter in die Materie einführen ;D


    Bis dahin... viel Spaß mit AVISynth

    ^^
  • Super Tutorial für Leute die wissen wollen was eigentlich dahinter steckt ohne von einer Welle an Informationen komplett erschlagen zu werden. Kudos an dich dass du dir die Mühe gemacht hast.
    Einen Punkt habe ich aber doch zu bemängeln. So richtig LPer Spezifisch ist das mMn nämlich nicht. Welcher LPer braucht denn schon "BlankClip"?
    Trotzdem alles recht anschaulich erklärt, für einige hier sicher sehr interessant.


  • Das mit dem Blankclip erkläre ich nicht ohne Grund und wird im späteren Tutorialverlauf noch mal für etwas anderes aufgegriffen ;D


    Alles Klar, dann warte ich mal gespannt ab.



    Weil man z.b. ein Intro oder Outro machen möchte wo Text drauf erscheint, oder bilder zu sehen sein sollen oder oder oder. Gibt massig Varianten wofür man das nutzen könnte


    Mir ist sehr wohl bewusst wofür man das benutzen kann/könnte, trotzdem stellt sich mir die Frage welcher LPer ernsthaftes Interesse daran hat sein Intro/Outro auf diese Art und Weise zu gestalten. Aber es scheint ja bald noch darauf eingegangen zu werden.

  • Mir ist sehr wohl bewusst wofür man das benutzen kann/könnte, trotzdem stellt sich mir die Frage welcher LPer ernsthaftes Interesse daran hat sein Intro/Outro auf diese Art und Weise zu gestalten. Aber es scheint ja bald noch darauf eingegangen zu werden.


    Ich vor wenigen stunden.


    Wollte es gestern schon nutzen, aber die Audiosettings waren nich exakt gleich. Um irgendwelche Nachrichten rüberzubringen oder Credits etc. ist das schon ganz nützlich.

  • Videos laden, anpassen und ein Bild im Bild erzeugen mit Hilfe von Overlay (Erklärung von Variablen)


    (Video erscheint hier)


    Heute zeig ich euch wie ihr Videos ladet, sie anpasst und wie man eine Bild in Bild Darstellung zaubert. (Wird oftmals für Outros verwendet zur Darstellung zu anderen Videos oder für eine Webcam)


    Bevor wir loslegen sollten die vorliegenden Videos für diesen Teil des Tutorials die gleiche Länge haben in etwa. Weil zum Thema schneiden und croppen werde ich noch im nächsten Thema bezug nehmen, da sowas ja halt extrem wichtig ist. Hier will ich euch aber vorbereiten mit Variablen umzugehen und wie diese sich untereinander unterscheiden.


    Diesmal benötigen wir kein Blankclip, sondern laden unser Video mit AVISource (Ganz wichtig: Die Quellvideos müssen ein encodiertes Material haben das passt. [lexicon]Lagarith[/lexicon], [lexicon]FRAPS[/lexicon], DXTory) Für korrekte Einstellungen der Aufnahmen, bitte das entsprechende Tutorial lesen dazu. Für Aufnahmen wie dem [lexicon]KGV1[/lexicon] [lexicon]Codec[/lexicon] (Sega Emulator Fusion) oder dem TSCC / TSC2 [lexicon]Codec[/lexicon] (Camtasia 7 / 8 ) wird das Laden mit DirectShowSource bewerkstelligt.


    Ich werde euch beide etwas nährbringen, damit ihr nicht ewig rätseln müsst, warum das Video nicht richtig geladen wird.


    Fangen wir also damit an das Video 1 mit AVISource geladen wird und Video 2 mit DirectShowSource. (Zwei Fliegen mit einer Klappe ;D)


    Code
    AVISource("D:\test\screen.avi")
    DirectShowSource("D:\test\screen2.avi")


    Was wir jetzt feststellen, ist das DirectShowSource einen Fehler ausgibt. Das liegt daran das dieser Befehl ein Plugin ist, den wir erst laden müssen und noch vor der eigentlichen Ladesequenz steht. Also fügen wir hinzu:


    Code
    #Plugin und Importsektion
    LoadPlugin("{Pfad}\MeGUI\tools\avs\directshowsource.dll")
    #Quellen Ladesektion
    AVISource("D:\test\screen.avi")
    DirectShowSource("D:\test\screen2.avi")


    Damit sollte die AVS geladen werden können, aber wir stellen fest das hier etwas total schief gelaufen ist. Denn nur das letzte Video was wir mit DirectShowSource geladen haben wurde geladen. Also brauchen wir Variablen und realisieren so unsere Spuren/Tracks. Die Variablen sollten mit einen Buchstaben beginnen und keine Sonderzeichen enthalten. Für Videospuren empfehle ich als Kürzel "v" + Nummer. Für Bilder "p" + Nummer. P für Picture halt. Bei zusätzlichen änderungen wie Masken etc. werde ich entsprechend die Variable auch so nennen wie "p1mask" . Damit ich nicht durcheinander komme. Die Bezeichnungen wie er die Variablen nennt, ist jedem selbst überlassen. ;D


    Code
    #Plugin und Importsektion
    LoadPlugin("{Pfad}\MeGUI\tools\avs\directshowsource.dll")
    #Quellen Ladesektion
    v1 = AVISource("D:\test\screen.avi")
    v2 = DirectShowSource("D:\test\screen2.avi")


    Die Fehlermeldung "Not a clip" müsste erscheinen, da wir unsere Videos noch keinen Ausgang/Output haben. Da wir ein Bild in Bild haben wollen kommt nun der Befehl Overlay ins Spiel. Overlay dient wie der Name schon sagt, zur Überlagerung. Genau das wollen wir ja erreichen. Also ergänzen wir wieder:



    Wir haben hier jetzt v2 auf v1 geladen und v2 sollte jetzt vor v1 zu sehen sein. Bedenkt aber das die FPS genommen werden auf den das andere Video gelegt werden. Hier werden z.B. die FPS von v1 genommen. Würde man bei Overlay v1 und v2 tauschen, dann würden die FPS von v2 genommen. Die Ausgabe des Farbkanals ist standartmäßig auf RGB32 gesetzt. Auch wenn in YV12 aufgenommen wurde. Das hatte ich im letzten Tutorialabschnitt schon erklärt das sowas [lexicon]MeGUI[/lexicon] automatisch für euch hinsetzt an letzter Stelle. Ihr könnt aber auch jeden anderen Farbkanal als Ausgang wählen. Für uns reicht aber YV12 dicke aus. Diesmal brauchen wir nicht ConvertToYV12() eingeben, sondern können es im Overlay angeben.



    Das sieht doch schon mal recht schick aus, oder? Natürlich möchte ich aber noch etwas Kontrolle darüber haben was die Quellvideos angeht. Das ein Video 30FPS hat und das zweite 25FPS stört mich und könnte eventuell zu Konflikten kommen. Daher werde ich beide so anpassen, das die Zeitlänge nicht geändert wird, aber die FPS geändert wird. Das kann man mit zwei Mitteln machen. Einmal mit ConvertFPS und einmal mit ChangeFPS. Nehmt am besten wenn es geht nur ChangeFPS. Anstatt die FPS erneut zu konvertieren werden sie mit ChangeFPS nur abgeändert. v2 hat in diesem Tutorial 25FPS und v1 hat 30FPS. Also werde ich nur v2 abändern.



    Ein AssumeFPS benötigt ihr erst, wenn sich ein Video das ihr ladet entweder zu schnell abgespielt wird oder zu langsam. Dazu braucht ihr aber Werte wie Zeitlänge der Audiospur. Das hat was mit Assynchronität zu tun. Die neue FPS bei AssumeFPS ergibt sich aus numerator und denominator.
    Bedeutet numerator / denominator = FPS. Als Beispiel: AssumeFPS(30,1) = hier wird die Framerate auf 30FPS geändert. Das heißt das ein 25FPS Video somit kleiner wird von der Zeitlänge. Assume(2997,100) wären dann logischerweise eine 29.97 FPS Änderung. Sofern ihr aber immer Progressiv aufnehmt ohne Halbbilder, braucht ihr das nicht zu verwenden. Bei AssumeFPS kann auch der Ton ans Video angepasst werden, sollte die Länge des Videos stimmen. Das macht ihr dann mit: AssumeFPS(sync_audio=true) . Bedenkt das eure Quelle dann eine Audiospur geladen haben muss. AssumeFPS wird aus Analysen Gründen des Quellvideos mit angegeben. Daher werde ich das auch mit angeben. (Wie gesagt: Muss nicht, sofern man ordentlich aufgenommen hat wie mit [lexicon]FRAPS[/lexicon] oder [lexicon]Lagarith[/lexicon] z.B.). In Bezug auf sync_audio, worauf ich auch zum nächsten Abschnitt komme, nämlich die Audiospur laden. Das geht wie folgt in der Quellen Ladesektion in den entsprechenden Ladefiltern.



    Dieses audio=true läd nun von der screen.avi intern die Audiospur ein. Ledeglich die erste Spur. Ihr könnt auch in AVISynth eure Audiospuren laden, mixen, anpassen etc. Das ist zum einen viel Arbeit und würde euch nur unnötig belasten. Daher meine Empfehlung für euch, da ihr eh mit [lexicon]MeGUI[/lexicon] arbeitet. Bearbeitet eure Audiospur mit [lexicon]Audacity[/lexicon] und achtet ledeglich nur bei der AVISynth Videobearbeitung drauf das die Länge in Ordnung ist. Sprich: Videobearbeitung komplett mit AVISynth und Audiobearbeitung komplett mit [lexicon]Audacity[/lexicon]. Dann habt ihr nicht so ein Stress hinterher im Skript wegen Ladefehler oder Anpassungsfehler.


    Also schalte ich jetzt die Audiospuren bewusst wieder aus hier, so das keine erst geladen werden und wir mit dem Blanken Video arbeiten nur:



    Jetzt wollen wir aber noch das ganze unseren gewünschten Größen anpassen. Weil v1 beträgt 1280x720 vllt und eure Webcam v2 nur 640x480. Sieht natürlich etwas doof aus wenn das zusammengepappt ist. Hier benötigen wir unsere Resize Filter. Den entsprechenden Resize Filter sollte man jedoch nach eigenem Ermessen wie das Bild gerade aussieht nehmen. Ich werde hier jetzt den Spline64Resize Filter anwenden. Wer genauer wissen will wo die Unterschiede zwischen den einzelnen Resizer Filtern sind, kann sich das auf http://avisynth.org/mediawiki/Resize anlesen.


    Ich werde hier jetzt v1 auf 1920x1080 resizen und v2 etwas kleiner auf 320x240 und ich werde auch v2 an die untere rechte Ecke platzieren mit einen Seitenabstand von 30px.


    Das wir die Position anhand der oberen linken Ecke nur bestimmen können, muss gerechnet werden wieder. Wir haben nach dem Resize ein Bild von 1920x1080 und ein kleines Bild von 320x240. Und der Abstand soll 30px betragen vom Rand.


    1920 - 320 - 30 = 1570
    1080 - 240 - 30 = 810


    Also muss v2 an Position 1570, 810 positioniert werden. Das geschieht im Overlay. Da wo v2 auf v1 gelegt wird. Nur das wir jetzt noch sagen wo genau das passieren soll.



    Das wars erst mal dazu. Variablen zu einzelnen Clips müssen identisch sein, sollten diese miteinander verknüpft werden. Bei Overlay ist das nicht der Fall. Im nächsten Tutorialabschnitt zeig ich euch was ich damit meine, indem wir schneiden und croppen, aber auch mit welchen Tricks man Positionen anspricht innerhalb des AVS Skriptes. Weil bei AVS hatte ich ja schon erwähnt das alles (wenn man sich eine Timeline vorstellt) nach Links angeklatscht wird. Also brauchen wir ja noch die Möglichkeit bestimmte Positionen anzusprechen. Das aber wie gesagt beim nächsten mal.

  • Videos per AVISynth schneiden, croppen und Positionen ansprechen


    (Video erscheint hier)


    Gleich vorweg, bevor wir loslegen mit dem schneiden gebe ich euch für das bessere Verstehen eine Vorgefertigte AVS Test Datei die A) Zum Croppen dienen soll und B) zum schneiden gut geeignet ist. Ihr braucht dafür einfach nur den Code hier kopieren. Der Clip geht ca. 13,5 Sekunden lang und beinhaltet sowohl zentrierte aufeinanderliegende farblich unterschiedliche Clips, als auch eine Frameanzeige die uns den aktuellen [lexicon]Frame[/lexicon] mitteilt.



    Für Übungszwecke sollte das Beispiel ausreichen. Sollte der letzte Videofilter keine Variable besitzen, so ist dieser in der Variable "last" immer gesichert. Wir ergänzen jetzt nur unter ShowFrameNumber die AVS Datei und fangen erst mal mit dem Croppen an. Als Test habe ich die Auflösungen 800x600 (Blau), 640x480 (Grün) und 320x240 (Rot) vorgegeben. Zu sehen im BlankClip Eintrag. Der Befehl zum Croppen ist ganz einfach und erschließt sich aus dem Befehl Crop und den Parametern Links, Oben, Rechts und Unten. Wir Croppen also unser Video mal auf 640x480. In [lexicon]MeGUI[/lexicon] könnt ihr das auch Wunderschön machen mit Vorschaubild.


    Die Frage ist bei AVISynth wieviel muss ich jetzt wegschnibblen an den Seiten. Wieder leichte Mathematik: (800 - 640) / 2 = 80 (für Links und Rechts) und (600 - 480) / 2 = 60 (für Oben und Unten) . Beachtet aber das Links und Oben mit Positiven Werten gefüttert werden muss beim Croppen und Rechts und Unten mit negativen Werten. Bedeutet für Links = 80, Oben = 60, Rechts = -80 und Unten = -60
    Das geben wir auch im Code genauso ein:


    Code
    #... Hier kommt das Videobeispiel hin ...
    Crop(80, 60, -80, -60)


    Damit ist unser aktuelles Bild die Grüne Fläche und beträgt anstatt 800x600, nur noch 640x480. Croppen wird dazu verwendet um bestimmte Sachen wie unschöne Ränder oder Bildvergleiche zu erzeugen. Jetzt croppen wir mal die Rote 320x240 Fläche nur auf die Hälfte. Also 160x240. Die Frage ist jetzt wo wir das machen. Das muss noch vor dem eigentlichen Overlay passieren. Bedeutet, ihr könnt den Clip den ihr ladet sofort croppen indem ihr den Cropbefehl einfach mit einen Punkt dranhängt. Ich Zeig das mal am Gesamten Beispiel wieder:



    Was wir jetzt sehen, ist das der rote Clip geschrumpft und es so aussieht als ob er an beiden Seiten gecroppt wurde. Dem ist aber nicht so, denn es wurde nur die rechte Seite gecroppt auf die Hälfte des eigentlichen Clips. Das es in der Mitte wieder ist, hängt durch den dynamischen Overlay zusamm wo ihr eine Rechnung seht bezüglich x und y Koordinaten. Diese Rechnung bewirkt das die Bilder egal wie groß sie sind immer zentriert im Gesamtbild liegen. Ändert sich also die [lexicon]Auflösung[/lexicon] eines der Clips, wird diese automatisch zentriert im Bild.


    Kommen wir nun zum schneiden. Das Schneiden in AVISynth ist etwas kompliziert für den Anfang und [lexicon]MeGUI[/lexicon] erzeugt bei einem Schnitt sowas hier z.B.:


    Code
    __film = last
    __t0 = __film.trim(41, 89)
    __t1 = __film.trim(132, 191)
    __t2 = __film.trim(218, 258)
    __t0 ++ __t1 ++ __t2


    Was macht dieser verwirrende Abschnitt eigentlich? Hier nun die [lexicon]Auflösung[/lexicon] dazu

    ^^


    Wie etwas weiter oben beschrieben wird in "last" der letzte Videoclip der angezeigt wird gespeichert. Hier wird last in die Variable "__film" gelegt. Im nächsten Schritt geschiet der erste Schnitt mit dem Befehl Trim. Und zwars wird hier nur die Fläche herausgeschnitten die man weiter verwenden möchte. Hier also von [lexicon]Frame[/lexicon] 41 - [lexicon]Frame[/lexicon] 89. Bedenkt dabei das der eigentliche Anfangs [lexicon]Frame[/lexicon] 1 ist und bei AVISynth 0 . Bedeutet dieser erste Schnitt zeigt uns nachher auf der [lexicon]Frame[/lexicon] Anzeige im Video die Werte 42 - 90 für den ersten Schnitt.
    Hier wird nun die Variable "__t0" dazu verwendet den ersten Schnitt zu sichern aus dem Gesamtclip der in last war und nun in __film drin ist. Der Schnitt wird einfach an der Variable angehangen mit einen Punkt (__film.trim(Anfangs [lexicon]Frame[/lexicon], End Frame)). Und das kann man so oft wiederholen bis man alles fertig hat.
    Im letzten Schritt werden alle Schnitte die gemacht wurden in die Globale Variable "last" gespeichert. Diese brauch nicht angegeben werden als Variableziel, sondern es reicht wenn die Variablen oder Filter eine Videoausgabe erzeugen können. Hier haben __t0 bis __t2 Videoinformationen gesichert die auch als Ausgabe dienen können und werden nun mit dem Operator "++" zusammengesetzt zu einem Clip.


    Diese Trimmethode verwendet [lexicon]MeGUI[/lexicon] zum schneiden von Videos. Für manchen jetzt doch etwas mehr verständlich warum man nur einen Schnitt machen sollte damit ;D


    Das Schneiden wird auch als Trick benutzt um Positionen leichter innerhalb eines Videos anzusprechen. Weil was nützt uns ein Fadein oder Fadeout nur am Anfang und am Ende des gesamt Videos?

    ^^


    Der Trick ist eigentlich ganz Simple. Ihr legt euch dafür mehrere AVS Datein an die euer Video laden. Croppt diese zurecht. Und dann kommt der Clou mit dem Schneiden. Da wo Blenden erscheinen sollen, macht ihr schnitte. Oder halt da wo bestimmte Bilder nur angezeigt werden sollen. Bedenkt aber das das gesamte Video wieder auf die gleiche Länge kommen muss. Bedeutet wenn das erste AVS von 0 bis 100 getrimmt wird, muss der nächste Abschnitt logischerweise von 101 weitergehen. Habt ihr alles erledigt kommt ein sogenanntes Makefile. Diese Makefile ist auch eine AVS Datei und ladet nun alle anderen AVS Datein wieder, damit es ein Video wieder ist. Während die einzelnen zerschnittenen AVS Files ganz normal aussehen, sieht das Makefile in der Ladesektion etwas anders aus. Das könnte dann so aussehen:


    Code
    #Plugin und Importsektion
    v1=Import("Abschnitt_1.avs")
    v2=Import("Abschnitt_2.avs")
    v3=Import("Abschnitt_3.avs")
    v4=Import("Abschnitt_4.avs")


    Damit laden wir wie bei der Schnittfunktion auch jeden Abschnitt in eine Variable. Und wie bei der Schnittfunktion mit Trim auch kommt nun der Operator "++" ins Spiel um die einzelnen Szenen wieder zusammenzusetzen.


    Code
    #Plugin und Importsektion
    v1=Import("Abschnitt_1.avs")
    v2=Import("Abschnitt_2.avs")
    v3=Import("Abschnitt_3.avs")
    v4=Import("Abschnitt_4.avs")
    v1++v2++v3++v4


    Damit ist unser Video wieder komplett und eine komplette Bearbeitung des Gesamtvideos kann im Makefile stattfinden. Ihr könnt halt das Video ganz normal weiter verwenden und bearbeiten. Oder ihr wollt nur ein Abschnitt bearbeiten, dann macht man das halt im entsprechenden Abschnitt dazu. Bedenkt aber das alle anderen AVS Datein (Sprich die Abschnitte) keine Farbkonvertierung brauchen. Dies kann man jetzt ganz gepflegt 1 mal machen im Makefile. Ihr könnt das Makefile aber auch wieder mit Trim und Crop weiterverarbeiten. Bedenkt aber das das was schon in den Abschnitt AVS Datein entfernt wurde im Makefile nicht wieder erscheinen kann.


    Mit diesem Trick bedient man sich eine Frameposition ohne viel Tara zu verändern. Ihr könnt auch eine Überblende im Makefile zwischen den einzelnen Abschnitten machen mit Dissolve. Das sieht dann so aus:


    Code
    #Plugin und Importsektion
    v1=Import("Abschnitt_1.avs")
    v2=Import("Abschnitt_2.avs")
    v3=Import("Abschnitt_3.avs")
    v4=Import("Abschnitt_4.avs")
    v1=Dissolve(v1,v2,100)
    v1++v3++v4


    Hier wird zwischen v1 und v2 das Bild zunehmend überlagert bis v2 endgültig zu sehen ist. Das passiert in diesem Code über eine Framedauer von 100 [lexicon]Frame[/lexicon].


    Mit der Importfunktion können auch AVS Datein geladen werden die Funktionen besitzen um diese in der aktuellen AVS auch aufzurufen. Was man dafür nehmen könnte um sich viel Codegeschreibsel zu ersparen ;D


    Wenn dazu noch Fragen sein sollten, könnt ihr diese gerne stellen, falls noch etwas unklar sein sollte.

    ^^
  • Animationen und Alphamasken mittels AVISynth


    (Video erscheint hier)


    Da wir die Grundlagen bereits kennen kommen wir nun zu etwas schwierigerem, nämlich wie wir mit AVISynth Animationen erzeugen können und wie wir Alphamasken ausnutzen können um beispielsweise eine Bildfreistellung zu zaubern damit. Ok, eine Bildfreistellung wäre doch ein bisschen extrem ausgedrückt, wenn man bedenkt das wenn man einen Blauen Vorhang hinter sich hat, es aufnimmt und nur den blauen Hintergrund entfernen möchte. Da gehört schon einiges mehr zu. Was ich hier erkläre beschränkt sich auf ein Farbmuster dann.


    Aber erst mal zu den Animationen. In AVISynth gibt es zwei Filter die es uns erlauben andere Filter zu verwenden. Bedeutet man könnte diesen Filter mehrmals verkapseln. Ich hab mich beim Probieren selbst erst mal damit beschäftigt und hab es auch beim x male nicht geschafft den Filter ApplyRange und Animate zu koppeln. Erst im Gleitzforum konnte mich einer aufklären was das anging. Aber erst mal: Was ist überhaupt dieser Animate und ApplyRange Filter eigentlich? Nun um es kurz zu sagen: Animate gibt einen anderen Filter wieder der sich von [lexicon]Frame[/lexicon] x nach [lexicon]Frame[/lexicon] y ändern kann. Dabei darf aber die Größe des Clips nicht geändert werden. ApplyRange hingegen lässt uns einen anderen Filter von [lexicon]Frame[/lexicon] x bis [lexicon]Frame[/lexicon] y anzeigen. Ist [lexicon]Frame[/lexicon] y abgelaufen, sorgt ApplyRange dafür das dieser nicht mehr angezeigt wird.


    Das ist eigentlich eine schöne Sache, da man eventuell die Webcam während das Video abspielt sich bewegen lassen kann von a nach b. Oder wir erschaffen damit eine Blende wie sie in StarWars zu sehen ist, dank der Alphamasken auf die ich dann noch kommen werde.


    Fangen wir also damit an, das ich euch wieder eine Übungsvorlage gebe mit v1 und v2. Denkt dran das ihr die Blankclips jeder Zeit mit Videos austauschen könnt ;D


    Code
    #Quellen Ladesektion
    v1=BlankClip(length=901, width=800, height=600, fps=30, color=$0000ff).KillAudio()
    v2=BlankClip(length=901, width=160, height=120, fps=30, color=$FFFF00).KillAudio()


    Ich habe hier jetzt einen Befehl hinzugefügt, nämlich KillAudio(). Damit wird erreicht das beim angegebenen Clip die Audiospur entfernt wird. Also ganz Simple.
    v1 ist hier jetzt Blau und v2 ist ein kleines gelbes Kästchen. Für die Webcam z.B. .


    Wir legen also los indem wir unter der Quellen Ladesektion unsere Bearbeitungssektion erzeugen und mit Animate dafür sorgen das v2 von rechts bis nach links wandert ohne v1 zu verlassen. Ich werde hier ein dynamischen Code verwenden um dafür zu sorgen das sich alles nach der [lexicon]Auflösung[/lexicon] und Länge des geladeten Videos anpasst. Damit v2 v1 nicht verlässt rechnet man Zahlenmäßig: Für x = 800 - 160 = 640 und für y = 600 - 120 = 480 . Um es dynamisch zu machen für jede x belibige [lexicon]Auflösung[/lexicon] wird jetzt folgendermaßen gerechnet: x = v1.Width - v2.Width und für y = v1.Height - v2.Height . Die Informationen wie groß der Clip ist holen wir uns also mit den Befehlen Width und Height. Ändert sich also v1 oder v2, ändern sich diese Werte bei der Rechnung, was das ganze halt dynamischer macht. Das dazu. Nun zu Animate. Hier erst mal der Code:


    Code
    #Bearbeitungssektion
    Animate(v1,0,100,"Overlay",v2,0,v1.height-v2.height,v2,v1.width-v2.width,0)


    Hier passiert nun folgendes: Auf v1 wird der Filter Animate angewendet und soll von [lexicon]Frame[/lexicon] 0 bis [lexicon]Frame[/lexicon] 100 den Filter Overlay animieren. Nach dem Overlayeintrag der als Zeichenfolge geschehen muss kommen Optionale Argumente die den angesprochenen Filter betreffen. Hier nun Overlay.


    Overlay haben wir ja schon kennen gelernt und wissen das ein Clip auf ein anderen Clip gesetzt werden kann. Bei Animate wird nun v1 an Overlay übergeben als Clip auf den wir dann v2 setzen und dann die x und y Koordinaten der Startposition angeben. Danach kommt das gleiche Spiel hinterher mit der Angabe des Clips gefolgt von der entsprechenden Endposition.


    Wenn ihr das Video nun abspielt, läuft die gelbe Box von links/unten nach recht/oben von [lexicon]Frame[/lexicon] 0 bis [lexicon]Frame[/lexicon] 100 und verhaart dort bis der gesamte Clip zuende ist.


    Gleiches Spiel mit ApplyRange, nur mit weniger Angaben und den Effekt innerhalb eines bestimmten Framefensters ein Filter wirken zu lassen.


    Code
    #Bearbeitungssektion
    ApplyRange(v1,101,200,"Overlay", v2,v1.width-v2.width,0)


    Hier erreichen wir das von [lexicon]Frame[/lexicon] 101 bis 200 v2 auf einer Position angezeigt wird. Der Befehl ApplyRange ist mit dem Befehl Animate fast identisch, nur das Animate eine Endbedingung haben möchte und ApplyRange die Bedingung innerhalb der Frames nur macht. Animate würde somit den Clip weiter auf der Endposition ablaufen lassen.


    Sofern Fragen dazu noch offen sein sollten, könnt ihr mir diese gerne stellen ;D Weil jetzt wird es Verwirrender, denn ich möchte nun beide Filter auf einmal anwenden. Weil ich möchte das v2 von links nach rechts wandert und dann verschwindet vom Bild. Da wir mit ApplyRange und Animate Filter ansprechen können, kann man diese Filter selbst als Filter aufrufen und somit das ganze Verkapseln.


    Ich zeig euch das mal an einem Beispiel wieder:

    Code
    #Bearbeitungssektion
    ApplyRange(v1, 0, 100, "Animate", 0, 100, "Overlay", v2, 0, 0, v2, v1.width - v2.width, 0)


    Ich hoffe man sieht jetzt was damit gemeint ist. Anstatt Overlay, hätte man wieder Animate nehmen können usw. Was somit endlos weitergeführt werden könnte. Für unsere Zwecke reicht dieses Gebilde vollkommen aus.
    Wie funktioniert nun das ganze? Also (Und das musste mir auch erst jemand aus dem Gleitz Forum erklären ;D) v1 ist unser Hintergrundclip auf dem wir alles projekzieren. Von [lexicon]Frame[/lexicon] 0 bis [lexicon]Frame[/lexicon] 100 soll nun Animate ausgeführt werden und Animate soll ebenfalls auf v1 von [lexicon]Frame[/lexicon] 0 bis [lexicon]Frame[/lexicon] 100 den Overlay Filter dazu bewegen eine Animation auszuführen. Hiermit erreichen wir nun das v2 wärend der Wiedergabe von links nach rechts wandert und dann verschwindet.


    Sieht doch schon mal ganz Praktisch aus. Lassen wir v2 doch einmal um den Bildschirm wandern. Hierzu ist euer eigener Kopf gefragt, damit möchte ich erreichen das ihr mitdenkt und es versteht. Ihr könnt dazu gerne hier ins Tutorial schreiben und euch drüber austauschen ;D Kleiner Tipp von mir: Übergebt ApplyRange an den nächsten Filter, indem ihr es in eine Variable sichert.


    Habt ihr alles fertig sollt ihr das ganze so anpassen, das egal wie lang der Clip ist, diese komplette Animation so lange geht wie der Gesamtclip. Bedeutet: Wenn ich die Länge von Clip v1 und v2 ändere, soll die Komplette Animation auch so lange gehen. Auch hier als Tipp: Die Maximale Frameanzahl könnt ihr durch "FrameCount" ermitteln. Einfach dann an v1 oder v2 anhängen wie so z.B. : v1.FrameCount oder v2.FrameCount , um die maximale Frameanzahl zu ermitteln.


    Baut euch daraus etwas um die Start und EndFrames der Filter Animate und ApplyRange zu ändern ;D



    Jetzt kommen wir zu Alphamasken. Alphamasken sind spezielle Bilder die im [lexicon]Alphakanal[/lexicon] die Transparente Farbe speichern. Das kann jede mögliche Farbe sein. Im Austausch für diese Farbe wird diese mit einem anderen Bild getauscht. Bedeutet: Wir tauschen eine spezifische Farbe mit einem Videoclip aus.


    Ein schönes Beispiel auf Youtube: https://www.youtube.com/watch?v=M9FcjU7dF44


    Und hier kommt auch die Verwendung von Blankclips ins Spiel. Ich möchte nämlich jetzt kein gewöhnliches Bild mit Alphamaske erzeugen, sondern ein Animiertes. Und zwar mächte ich eine StarWars Szenen Blende haben. Also das von Links nach Rechts das Bild durch ein anderes ersetzt wird. Trefflich gewählt also können wir unsere neu erworbene Kenntniss mit Animate anwenden um diesen Effekt zu erziehlen. Also bauen wir uns erst einmal eine Blende Farblich mit Blankclips. Nehmt am besten Farben die im Video nachher nicht zu sehen sind. Sowas wie ein grelles Grün oder ein grelles Pink.


    Das ganze sieht im Endeffekt dann so aus:

    Code
    #Quellen Ladesektion
    v1=BlankClip(length=101, width=800, height=600, fps=30, color=$80FF80).KillAudio()
    v2=BlankClip(length=101, width=800, height=600, fps=30, color=$FF80FF).KillAudio()
    #Bearbeitungssektion
    Animate(v1,0,100,"Overlay",v2,-v2.width,v1.height-v2.height,v2,v1.width-v2.width,0)


    Hiermit erzeugen wir mit BlankClip solch eine simple Blende. v1 und v2 haben nun entsprechende Farben die unwahrscheinlich in einem richtigen Clip Grossflächig zu sehen sind.


    Allerdings müssen wir die Blende vorher encodieren lassen, damit sie für uns brauchbar ist. Das machen wir am besten mit Virtual Dub und dem [lexicon]Lagarith[/lexicon] [lexicon]Codec[/lexicon]. Ladet dazu einfach die AVS Datei rein und lasst diese mit dem [lexicon]Lagarith[/lexicon] encodieren. Das müssen wir leider so machen, da das Video was wir im Code erzeugt haben uns das ganze im Zusammenhang mit unserer Alphamaskte zerstören würde und wir etwas völlig anderes haben dadurch, was nicht gewollt war.


    Übrigens könnt ihr solche Masken überall erstellen. Sogar mit Schrottasia. Beachtet aber dabei das ihr so [lexicon]Lossless[/lexicon] wie Möglich das ganze exportiert. Bei [lexicon]Camtasia[/lexicon] 8 wäre das der TSC2 [lexicon]Codec[/lexicon] und bei allen anderen wenn es geht der [lexicon]Lagarith[/lexicon] [lexicon]Codec[/lexicon]. Halt irgendwas was [lexicon]Lossless[/lexicon] ist ;D Muss ja nur eine Animation sein die aus zwei unterschiedlichen Farben besteht.


    Weiter im Text... wir haben also unsere Blende fertig encodiert und ein Buntes Etwas erzeugt. Auf diese zwei Farben projekzieren wir mit dem nächsten Script unsere Clips. Das sieht dann folgendermaßen aus:


    So, was passiert hier nun? Als erstes laden wir unsere Quellen v1 - v3. v1 unsere Blende und die 2 Aufnahmen die verblendet werden sollen. Das ganze muss im RGB32 Farbraum stattfinden und deshalb werden hier die Aufnahmen in RGB32 umgewandelt. Das müssen wir machen, da wir sonst mit den Maskenfiltern nicht arbeiten können.


    Als erstes wird nun mit ColorKeyMask die Farbe selektiert die wie austauschen möchten auf v1 und setzen gleich den [lexicon]Alphakanal[/lexicon] dafür damit diese Farbe nicht angezeigt wird. Hier nicht vergessen den Pixel_Type auf RGB32 zu setzen, da sonst wieder Fehler auftreten. Diese Maske wird jetzt mit Overlay ersetzt, da die Farbe ja jetzt Transparent ist erscheint das Video durch. Im Overlay geben wir dann unsere Maske m1 an und convertieren das ganze auch da in RGB32. Da ja v2 oben noch nicht convertiert wurde, können wir das hier gleich machen für den nächsten Schritt. Denn dieser Overlay dient jetzt als Blaupause für unsere nächste Farbe. Wir reseten die Maske vom Overlay und wählen eine neue Farbe aus die wir für die Nächste Maske nehmen. Danach brauch nur noch Layer dafür sorgen das auf die letzte Maske unser letztes Video kommt. Und fertig ist der Zauber. Danach wieder alles in YV12 convertieren und [lexicon]MeGUI[/lexicon] kann encodieren.


    Aber Vorsicht: Bei selbsterstelten Blenden oder Dessolve laufen beide Clips in der Blendzeit gleichzeitig ab. Bedeutet das ihr eure Audiospur auch abändern müsst um die entsprechende Zeit.


    So. Das wars erst mal dazu. Alles wichtige ist damit eigentlich gesagt zu AVISynth. Sollte jemanden noch etwas einfallen was er vllt bräuchte oder realisieren möchte damit kann das in diesen Tutorial Thread gerne tun

    ^^

    Ich denke mal da es weitere schlaue Köpfe gibt was AVISynth angeht und ich auch nicht alles wissen kann

    ^^


    Das hier sind nur die Grundlegensten Sachen jetzt die man mit internen Filtern zaubern kann. Sachen wie Restoration von Videos oder Nachbearbeitung etc... sind alles weitere Sachen die man machen kann.


    Gut zu wissen währe noch bestimmt wie man Bilder ladet, oder?

    ^^

    Nun, da ich denke das ihr euch durch das Tutorial gekämpft habt und euch damit schon beschäftigt habt, könnt ihr euch das mit den Bildern anhand meiner Templates anschauen die bei [ Text-Tutorial ] Der große AviSynth-Guide zu finden sind ;D


    Und wie gesagt, bei Fragen oder weiteren Wünschen wie man was machen kann, könnt ihr euch hier drüber die Finger blutig schreiben ;D Die die in AVISynth dann etwas bewandert sind, werden euch dann sicher weiter helfen ;D

  • Vllt solltest du noch einbringen, das Verlustformate nicht mit DirectShow geladen werden sollten, sondern eher mit FFMPEGSource (File index + FFVideoSource)
    Zum einen unterstützt es sehr viel mehr Codecs, zum anderen umgeht man damit systeminstallierte decoder/filter, und es hat frameexaktes seeking, was directshowsource nicht hinkriegt.


    [lexicon]Lossy[/lexicon] Formate also auf jeden Fall immer per FFVideoSource einlesen.


    __


    DirectShowSource sollte eig. von Haus aus existieren. Wundert mich gerad, das du da extra noch die dll laden musst.

  • DirectShowSource sollte eig. von Haus aus existieren. Wundert mich gerad, das du da extra noch die dll laden musst.


    Liegt daran das ich das nicht von Haus aus in der Plugin Liste von AVISynth habe ;D Hatte ich seltsamer weise noch nie.

    ^^


    FFVideoSource ist auch ein Plugin den man erst laden muss/erst mal runterladen muss ;D


    Danach sollte damit genauso wieder verfahren werden wie mit allen anderen Ladefunktionen von Quellmaterialien

    ^^

    Vllt solltest du noch einbringen, das Verlustformate nicht mit DirectShow geladen werden sollten, sondern eher mit FFMPEGSource (File index + FFVideoSource)
    Zum einen unterstützt es sehr viel mehr Codecs, zum anderen umgeht man damit systeminstallierte decoder/filter, und es hat frameexaktes seeking, was directshowsource nicht hinkriegt.


    [lexicon]Lossy[/lexicon] Formate also auf jeden Fall immer per FFVideoSource einlesen.


    Eingebracht ;D
    Wieso noch mal erklären, wenn du das so wunderschön schon machst?

    ^^

    Generell sollte auch erwähnt werden das sowas erst genutzt werden sollte, sollte eine [lexicon]MP4[/lexicon], [lexicon]MKV[/lexicon] oder sowas noch mal reencodiert werden. Wer sowieso [lexicon]Lossless[/lexicon] aufnimmt mit [lexicon]FRAPS[/lexicon] oder [lexicon]Lagarith[/lexicon], wird sowieso AVISource nehmen. Und ganz verquerte Codecs wie [lexicon]KGV1[/lexicon] oder Zib Motion Block Video sind auch immer sehr kurios zu laden

    ^^

    Sollte man auch mit bedenken.

  • Habe jetzt grad schon einmal kurz überfliegend reingeschaut in das Tutorial und habe jetzt schon den Eindruck, dass all die Videospielereien, die ich zukünftig mal machen möchte ich hier mit diesem Tutorial werd erlernen können. Vielen dank jetzt schon einmal für deine Mühe

    :)
  • Funktionen und ihre Nutzung + If Then Else - Abfragen


    Funktionen dienen in AVISynth zur erleichterten Bedienung von gewissen Routinen die aus vielen einzelnen Befehlen bestehen. Mit anderen Worten: Man verkürzt sich so Vorgänge die man immer wieder braucht.


    Großes Problem in AVISynth ist das Ansprechen eines Filters in einem bestimmten Zeitbereich/Framebereich. Was weiß ich, Filter xy soll von [lexicon]Frame[/lexicon] 20 bis [lexicon]Frame[/lexicon] 60 wirken. Aber der eigentliche Filter wirkt nur auf das gesamte Video.


    Um das zu realisieren in AVISynth gibt es ein Weg und der heißt Schneiden.


    Wir haben also unser Video. Ich nenne ihn mal clip0. Die Schnitte erfolgen in 3 Clips. Einen Anfangsclip, ein Bearbeitungsclip und ein Endclip. Daraus ergeben sich 4 Kombinationen:
    1. Nur Bearbeitungsclip
    2. Anfangsclip + Bearbeitungsclip
    3. Bearbeitungsclip + Endclip
    4. Anfangsclip + Bearbeitungsclip + Endclip


    Also 4 Möglichkeiten das Video wieder zusammzufügen. Von den 3 Clips interessiert nur der Bearbeitungsclip dann. Das ist der Bereich wo dann der Filter drauf wirkt.


    Der Anfangsclip ist der, der von [lexicon]Frame[/lexicon] 0 an startet und bis zu dem [lexicon]Frame[/lexicon] Bereich geht wo wir unseren Startframe setzen.
    Der Bearbeitungsclip besteht aus unseren Framestart und Frameend Position.
    Der Endclip besteht aus unseren Frameend Position und der maximalen Cliplänge des Original Videos.


    Wenn Filter xyz von [lexicon]Frame[/lexicon] 30 - 50 wirken soll, dann tritt Möglichkeit 4 in Kraft.
    Wenn Filter xyz von [lexicon]Frame[/lexicon] 0 - 50 wirken soll, dann tritt Möglichkeit 3 in Kraft
    Wenn Filter xyz von [lexicon]Frame[/lexicon] 30 - Video Endframe wirken soll, dann tritt Möglichkeit 2 in Kraft
    Und wenn Filter xyz von [lexicon]Frame[/lexicon] 0 - Video Endframe wirken soll, dann tritt Möglichkeit 1 in Kraft


    Das mal jetzt als Verständnis, damit man eine Vorstellung jetzt ungefähr hat

    ^^


    Als nächstes brauchen wir Abfragen um das ganze zu Realisieren. Dazu können wir uns einer If Then Else (Ist Dann Ansonst) Abfrage bedienen.


    Einfache Logik für Programmierer:
    If x = 3 then y= 2 else y=4


    Auf Deutsch:
    Ist x = 3 dann y = 2 ansonsten y=4


    In AVISynth:
    y = (x=3) ? 2 : 4


    Sollte doch verständlich sein, oder? Wenn Fragen sind, einfach fragen ;D


    Kommen wir nun zur Funktion. Eine Funktion sollte so aufgebaut werden, das sie für viele Sachen mehrmals verwendet werden kann. Sprich sie sollte Dynamisch sein. Zudem sollten die meisten Funktionen in AVISynth einen Wert zurück liefern. das machen wir mit Return. Wir senden also unsere Informationen an eine Funktion, die dann das entsprechende Ergebnis liefert.


    Ich möchte mit euch das bereits genannte Problem + die Lösungsansätze dafür nutzen um mit euch eine Funktion dafür zu entwickeln das Problem mit nur einen einzigen Befehl zu lösen.


    Ich möchte jetzt nämlich einen Filter verwenden den man immer wieder mal braucht. Und zwars Overlay.
    Was brauchen wir also alles für unsere neue Funktion? Overlay braucht 2 Clips, dann brauchen wir natürlich einen Start und einen Endframe und einen Bildbereich von x,y - x2,y2
    Das würde also ein Rechteck bedeuten. Das sind also 8 Werte die wir brauchen.


    Erstellen wir uns also unsere Funktion. Nennen wir sie einfach xyz. Ihr könnt diese Funktion so bezeichnen wie ihr wollt. Ich rate aber davon ab die Funktion so zu benennen wie andere Befehle ;D


    Also fangen wir an mit:

    Code
    Function xyz (clip clipx, clip clip0, int sw, int sh, int ew, int eh, int sframe, int eframe) {
    }


    clipx werde ich als das Video nehmen auf das gezeichnet werden soll, clip0 ist das Video auf das der Filter nachher wirken soll. sw, sh, ew und eh stehen für startwidth, startheight, endwidth und endheight. Quasi unser Bildbereich (x,y) - (x2,y2) . Und sframe und eframe stehen für unseren Framebereich auf das der Filter angewendet wird. Hier als startframe und endframe ;D


    Die Funktion ist noch relativ leer. Aber man kann sie aufrufen mit dem Befehl:
    xyz(last, v1, 0, 0, 320, 240, 0, 1800)


    Als Anschauhung gebe ich wieder ein Beispielskript vor:

    Code
    v1=BlankClip(length=1800, width=640, height=480, fps=25, color=$000000)
    v2=BlankClip(length=1800, width=640, height=480, fps=25, color=$FF0000)
    xyz(v1,v2,100,100,300,300,500,1000)
    xyz(v2,350,200,500,500,500,1000)
    Function xyz (clip clipx, clip clip0, int sw, int sh, int ew, int eh, int sframe, int eframe) {
    }


    Nehmen wir mal an v1 und v2 sind das gleiche Video. Ich hab das jetzt mal so erstellt damit man farblich erkennt was dann passiert nach dem Vorgang.


    Als nächstes geben wir unserer Funktion die einzelnen Schnitte vor für unsere 3 Clips die wir brauchen um unseren Filterbereich zu verwenden.
    Clip1 soll unser Anfangsframe sein. Da AVISynth uns einen Strich durch die Rechnung macht, wenn wir Trimen wollen von [lexicon]Frame[/lexicon] 0 oder [lexicon]Frame[/lexicon] 1 zu [lexicon]Frame[/lexicon] was weiß ich, muss eine Abfrage her.


    Diese lautet um es verständlich zu machen für andere User:

    Code
    If sframe = 1 then
    clip1 = clip0.Trim(0, sframe - 2)
    Else
    clip1 = clip0.Trim(0, sframe - 1)
    End If


    In AVISynth also:

    Code
    clip1 = (sframe == 1) ? clip0.Trim(0, sframe - 2) : clip0.Trim(0, sframe - 1)


    Das entspricht genau das gleiche Muster.


    Clip2 ist unser Bearbeitungsclip. Hier muss mit Crop unser Bereichsfenster gecroppt werden. Da der Cropbefehl auch Negative Zahlen braucht für rechts und unten, müssen wir wieder unsere Mathematik spielen lassen.


    Wie berechnen wir x2 und y2 unseres Rechtecks? Genau. Indem wir uns der Clipbreite und Höhe bedienen.
    Weil Breite - ew und Höhe - eh ergeben unsere x2 und y2 Position. Da es aber negative Zahlen sein müssen bei rechts und unten in Crop formen wir das um in: -Breite + ew und -Höhe + eh.


    Das ganze sieht dann also so aus:

    Code
    clip2 = clip0.Crop(sw, sh, -clip0.width + ew, -clip0.height + eh)


    Nun müssen wir noch dafür sorgen das der neue Clip2 wieder auf die gleiche Größe kommt wie der Ursprungsclip, damit Clip1, 2 und 3 wieder zusammengefügt werden können. Und das gecroppte clip2 soll auch wieder an der gleichen Position erscheinen von da wo wir es herrausgecroppt haben.


    Das machen wir mit Overlay. Gleichzeitig schneiden wir es auf Start und Endframe. Also den Bereich wo das ganze im Gesamtvideo angezeigt werden soll. Das machen wir dann mit dem Trim Befehl wieder.


    Also die nächste Zeile lautet dann:

    Code
    clip2 = Overlay(clipx, clip2, x = sw, y = sh).Trim(sframe, eframe)


    clip2 wird auf Clipx gezeichnet auf Position sw und sh die wie ja schon verwenet haben. Da es die exakten Größen hat weil das Video ja meist identisch ist bei nur einen Video ;D sieht man dann halt keinen Unterschied das da der Bereich neu aufgelegt wurde. Bei der Beispielvorgabe allerdings sieht man es dann durch den Schwarzen und Roten Clip dann um es euch auch mal zu zeigen was da passiert.

    ^^


    Jetzt brauchen wir natürlich noch unseren Clip3. Der muss 1 [lexicon]Frame[/lexicon] später anfangen und bis zum Schluss des Gesamtvideos gehen.
    Das ist jetzt ganz einfach. Das machen wir so:

    Code
    clip3 = clip0.Trim(eframe+1, clip0.framecount-1)


    So. Wenn wir das alles haben fehlt uns nur noch ein Rückgabewert des Videos. Hier kommen unsere 4 Möglichkeiten ins Spiel die wir abfragen müssen.
    Wieder einfache Logik erst mal zum Überblick:


    In AVISynth sieht das dann so aus:

    Code
    return (sframe == 0 && eframe == clip0.framecount - 1) ? clip2 : (sframe == 0) ? clip2++clip3 : (eframe == clip0.framecount - 1) ? clip1++clip2 : clip1++clip2++clip3


    Das wars dann auch schon. Die Funktion sollte damit fertig sein und ihr könnt diese auch mal testen. Das Return gibt wie gesagt die entsprechende Variable zurück. In unserem Fall hier ein Videoclip. Bei dem Return werden die entsprechenden Clips wieder zusammen gefügt. Da unsere Funktion sehr Framegenau ist, kommen keine Frames dazu oder werden weniger.


    Diese Funktion hier Überlagert ein Video auf ein anderes.


    Ihr könnt mit Clip2 nun anstellen was ihr wollt. Benutzt andere Filter oder was weiß ich. Ihr habt auf jedenfall eine Frameangabe von wo der Filter wirken soll. Das ist besser als ApplyRange, da bei dieser Methode mehr Kontrolle ist und man mehrere Filter einbauen kann die auf Clip2 wirken mit nur einem Befehl nachher.


    Hier noch mal das fertige Skript für euch:


    Wie ihr seht, taucht im Framebereich 500 bis 1000 ein Viereck auf und rechts daneben ein schmales Rechteck. Das sind die Bereiche die herausgecoppt wurden. Bei xyz(v2,350,200,500,500,500,1000) fehlt eine Clipangabe. Wie in den Tutorials davor erwähnt muss Last als Variable nicht angegeben werden sofern der erste Eingang des Filters ein Clip ist. Bei diesem eben genannten dick makierten Beispiel steht eigentlich xyz(last, v2,350,200,500,500,500,1000) da. Last ist das Resultat aus dem ersten xyz Aufruf mit xyz(v1,v2,100,100,300,300,500,1000).


    Mit dieser Funktion ist es also Möglich viele Sachen zu machen. Wenn dazu noch Fragen sind, immer stellen. Ich versuche sie dann auch zu beantworten.

    ^^
  • Danke für das Tutorial, mir hat das ganze doch sehr geholfen und ich
    habe die Anfangsscripte auch schon ausgetestet und bin positiv
    überrascht. Die späteren jedoch muss ich mir in Ruhe noch einmal
    anschauen denn die sind doch schon etwas schwerer für mich

    :D

    . Auf jedenfall Klasse das du dir hier die Arbeit machst das ganze zu erklären

    :thumbsup:

    .


    Beim 2. Script hast du soweit ich sehe beim Resizefilter einmal , und einmal x angegeben. Ich habe das jetzt bei meinen Script einfach auch auf , abgeändert (wobei ich auch als 2. ein AviSource genommen hatte). Geht das mit dem x also auch oder muss es , sein (also so wie ich es nun gemacht habe)?

  • kann man eigentlich über avsynth , eine ogg datei mit einer jpg datei verbinden ?
    also zbsp..
    man will einen soundtrack vom spiel machen...was 3 mins geht...und das foto dann 3 mins angezeigt wird...
    wäre sowas möglich ?

  • uff...da blick ich garnicht durch^^ bin da nicht so versiert drin...^^
    hast du zufällig n skript ? was ich an meinen ordnern etc anpassen kann ?
    man muss ja auch die länge angeben oder ? wenn die ogg datei 3 mins geht wie gebe ich das im skript wieder ?

  • Zitat

    # Use a still-frame image with audio:
    audio = DirectShowSource("Gina La Piana - Start Over.flv")
    video = ImageSource("Gina La Piana.jpg", fps=25, start=1, end=ceil(25*AudioLengthF(audio)/AudioRate(audio)))
    return AudioDub(video, audio)


    hab ich gerade gefunden aus einem anderen thread mit dem gleichen thema

    ^^
  • na da wo Gina bla bla ist ist natürlich der pfad was nur logisch ist

    :)


    und hier mal was directshowsource unterstützt an audio
    audio = true (in v2.53): There is audio support in DirectShowSource. DirectShowSource is able to open formats like WAV/DTS/AC3/MP3, provided you can play them in WMP for example (more exact: provided they are rendered correctly in graphedit). The channel ordening is the same as in the wave-format-extensible format, because the input is always decompressed to [lexicon]WAV[/lexicon]. For more information, see also GetChannel. [lexicon]AviSynth[/lexicon] loads 8, 16, 24 and 32 bit int [lexicon]PCM[/lexicon] samples, and float [lexicon]PCM[/lexicon] format, and any number of channels.



    ansonsten einfach das bild mit der Länge vom audio erstellen und wie demon schon sagte später [lexicon]muxen[/lexicon].
    wäre in etwa

    Zitat

    Image = ImageSource("Pfad", 0, 0, 30, false).Loop(Dauer des Videos * 30)
    return Image

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!