Wie "Trimmen" mit Zeitangabe

  • Hoffe ich bin hier mit meiner Frage im richtigen Unterforum.
    Ich habe einen VDR (ein auf Linux basierender Pc speziell für TV) mit dem ich auf meine Aufnahmen tätige. Der Vorteil ist, dass das noad Plugin automatisch Schnittmarken setzt, wo Werbung beginnt bzw. endet und so automatishc überspringt, wenn ich die am vdr betrachte. Nun wenn ich die Daten jedoch für weitere Bearbeitung kopiere würde ich gerne gleich diese Schnittmarken in avisynth integrieren. Gibt es da eine möglichekit?
    Die marks.vdr, die die MArken enthält ist so aufgebaut:

    Code
    0:06:38.11 Logo start
    0:21:35.14 Logo lost
    0:31:35.07 Logo start
    0:50:26.04 Logo lost
    0:57:44.22 Logo start
    1:45:01.05 Logo lost


    Momentan löse ich dass so, dass ich in VirtualDub zu dem Zeitcode springe, mir den Frame notiere und diesen dann in avisynth verarbeite. ISt aber nicht so optimal. Gibt es da bessere/einfachere möglchkeiten?

  • Hallo und :welcome:!

    Wenn man nicht genau weiß, wo das hin soll, gibt es bspw. die Newbiesektion, mit fortgeschrittenem Avisynthskripting hat es auf jeden Fall nichts zu tun => verschoben.

    Einfachere Möglichkeiten gibt es sicher: einen Framerechner, also Taschenrechner der mit Frames arbeiten kann. Aber wer hat schon sowas?
    Programme, die Dir zumindest Minuten und Sekunden in Frames umrechnen => bspw. FitCD.
    Bestimmt gibt es auch welche, in denen man Frames auch noch angeben kann, mir fällt nur spontan nichts ein.
    Dritte Möglichkeit: Taschenrechner. Zeiten ins dezimale System bringen und dann mit 1500 (nur Minuten) bzw. 90000 (in Stunden) multiplizieren plus die Frames die Dir nach dem '.' angegeben werden.

    Eleganter wäre es natürlich, wenn man ein kleines Programm schreiben würde, dass einem die Arbeit für die komplette Liste abnimmt, sollte ja nicht so schwierig sein:
    1. Stelle x 90000 + 2. Stelle x 1500 + 3. Stelle x 25 + 4. Stelle = Frames

    Ich gehe jetzt davon aus, dass die 4. Stelle direkt in Frames angegeben ist und nicht dezimal.

    Cu Rippraff

    Blumige Grüße, Rippraff

  • Ich fürchte auch, dass mir da kein Programm bekannt ist, das Schnittmarken im Format HH:MM:SS.FF direkt in Framenummern für Trim-Befehle wandelt.

    Höchstens ChapterXtractor käme dem halbwegs nahe, insofern dass man damit vielleicht Timecode-Listen konvertieren kann. Aber zwei Framenummern zu einem Trim-Befehl zusammenfassen, das kann er wohl nicht, glaube ich.

    Aber ich stelle es frei, damit vielleicht auch mal in der "Softwareentwicklung" anzuklopfen. Vielleicht hat ja jemand Zeit dafür.

  • Ausserdem ... ich weiss zwar nichts weiter über dieses noad plugin, aber ich trotzdem bezweifle ich stark, dass diese automatisierte Werbungs-Erkennung immer wie gewünscht arbeitet. Offensichtlich orientiert es sich an dem Vorhandensein eines Senderlogos. Das ist nicht zuverlässig. Stichworte:

    - Verzögertes Einblenden / verfrühtes Ausblenden des Senderlogos
    - Nach der Werbung wird die letzte Szene vor der Werbung wiederholt (zur Streckung der Sendezeit -> mehr Werbung)
    - Logo verschwindet während der Sendung (z.B. um Sendehinweise einzublenden, manchmal auch ganz einfach technischer Fehler des Senders)

    In vielen Fällen mag sowas einigermaßen brauchbar arbeiten, aber man wird definitiv immer wieder mal bösen Schiffbruch erleiden.

    Und wenn man dazu übergeht, alle gefundenen Werbeunterbrechungen manuell auf Korrektheit zu überprüfen, dann führt sich die ganze Automaten-Geschichte irgendwie selber ad absurdum. :)

  • Hmm... hab' mal versucht, das Problem zu lösen, aber die AVISynth-Syntax krieg' ich trotz Wiki-Lesen nicht auf die Reihe...

    Code
    video = AviSource("video.avi") cutpoints = "0:06:38.11 Logo start0:21:35.14 Logo lost0:31:35.07 Logo start0:50:26.04 Logo lost0:57:44.22 Logo start1:45:01.05 Logo lost" cutAtVDRCutPoints(video, cutpoints) resultvideo = BlankClip() function cutAtVDRCutPoints(video, cutpoints){  StrLen(cutpoints) == 0 ? {  return resultvideo } : {  tempstr = LeftStr(cutpoints, 42)  cutpoints = MidStr(cutpoints, 43, 0)   stundenIn = Int(MidStr(tempstr, 1, 1))  minutenIn = Int(MidStr(tempstr, 3, 4))  sekundenIn = Int(MidStr(tempstr, 6, 7))  framesIn = Int(MidStr(tempstr, 9, 10))   cutpointIn = stundenIn*90000 + minutenIn*60 + sekundenIn*25 + framesIn   stundenOut = Int(MidStr(tempstr, 23, 23))  minutenOut = Int(MidStr(tempstr, 25, 26))  sekundenOut = Int(MidStr(tempstr, 28, 29))  framesOut = Int(MidStr(tempstr, 31, 32))   cutpointOut = stundenOut*90000 + minutenOut*60 + sekundenOut*25 + framesOut    resultvideo = resultvideo + video.trim(cutpointIn, cutpointOut)   cutAtVDRCutPoints(video, cutpoints)  }  }



    Mal ganz abgesehen davon, dass ich nicht weiß, ob das überhaupt so funktioniert (insbesondere die Rekursion, aber auch die generelle Logik) scheint er sich hier an der Syntax des Ternär-Operators zu stören...

    Code
    Script error: syntax error
    Line 18, column 2



    Das wäre die Zeile mit der geschweiften Klammer auf nach StrLen(cutpoints) == 0 ? Ich hab' auch schon versucht, alles in eine Zeile hintereinander zu packen, das hilft auch nicht.

    Laut AviSynth-Wiki sollte zumindest die if-Abfrage so mit Blöcken funktionieren...

    P.S.: for- und while-Schleifen gibt's auch nicht, oder ? Iterativ geht meistens nicht so schief wie rekursiv :D

    Gruß, Christian

  • Danke für eure Hinweise. Ich werde wohl mal versuchen, mir so einen kleinen Framerechner zu basteln.
    Wegen der ungenauigkeit von noad. Wenn ich den Film umcodiere etc., dann such ich mir die Werbestellen genau raus (auch um z.B. Wiederholung wegzubekommen), aber zum normalen anschauen von Serien oder mal nen Film reicht das aus. Außerdem untersucht noad meines Wissens auch noch auf andere merkmale (4/3 16/9 umschaltung, AC3 Ton etc.). Natürlich läufts nicht immer perfekt, aber im wesentlichen doch sehr gut. Und ich glaube, die oben genante wiederholung bei manchen Werbeblocks, hat er auch übersprungen. Bei irgendeinen Film.

  • Soweit ich mich erinnere, wird da der "ternäre" = dreistellige Operator verwendet:

    Variable = Bedingung ? Positivergebnis : Negativergebnis

    Oder ausführlicher:

    Ergebnis = (Stimmt diese Annahme?) ? (ja, weise dieses Ergebnis zu) : (nein, weise jenes Ergebnis zu)

    Achtung: Hier werden immer alle drei Teile benötigt. Das Negativergebnis darf nicht weggelassen werden, unter Umständen ist dann ganz speziell ein "leerer Wert" anzugeben, oder der bisherige Inhalt zu wiederholen.

    Beispiel:

    absolutbetrag = (wert < 0) ? -wert : wert

  • a) nimm mal normale Klammer statt der geschweiften. Die geschweiften sind ausschließlich für Funktions-Deklarationen.

    b) man kann nicht "vielleicht aus der Funktion 'rausspringen". Sowas wie

    x == 0 ? return(ergebnis) : ergebnis=ergebnis+1
    return(ergebnis)

    funktioniert nicht. Da muss man sich anders durchhangeln, z.B. mit "last" oder "NOP" :

    x == 0 ? NOP : ergebnis=ergebnis+1
    return(ergebnis)

  • In den jeweiligen "Hälften" des Entscheidungsoperators darf in den meisten Programmiersprachen im Grunde nur ein Ausdruck stehen (den man der linken Seite vom Gleichheitszeichen zuweisen kann), keine komplette Anweisung (die für sich selber etwas zuweist).

    Auch die Idee von Didée ist nicht ganz "lehrbuchmäßig" korrekt:

    a) kurz:

    return (x == 0) ? ergebnis : ergebnis+1

    Gib, wenn x gleich 0 ist, den Wert "ergebnis" zurück, ansonsten den Wert "ergebnis+1".

    b) ausführlicher:

    ergebnis = (x == 0) : ergebnis : ergebnis+1
    return ergebnis

    "ergebnis" erhält, wenn x gleich 0 ist, den Wert "ergebnis", ansonsten den Wert "ergebnis+1"; dann gib den Inhalt von "ergebnis" zurück.

    ...


    Wenn man jetzt haarspalterisch an die Sache herangeht, haben im Grunde auch Zuweisungen noch ein Ergebnis, das man als "Ausdruck" verwerten kann (dadurch sind Zuweisungsketten der Form "a = b = c = 0" möglich, der Wert 0 wird darin von rechts nach links weitergereicht).

    Und auch ohne linke Seite kann man u.U. eine "Nicht-Zuweisung" durchführen, bei der die "rechte Seite" vom nicht angegebenen Zuweisungs-Gleichheitszeichen an keine Variable zugewiesen wird; bei AviSynth ist das dann die implizite Variable "last". Dadurch funktioniert Didée's Vorschlag dann "trotzdem".

    Eine einzelne Zuweisung ist somit eventuell gerade noch möglich. Ein kompletter Anweisungsblock (zwischen geschweiften Klammern) jedoch nicht: Dann müsste man schon eine Funktion deklarieren, die dann im Entscheidungspoerator ausgeführt wird.

    return (x == 0) ? ErgebnisClip0() : ErgebnisClipSonst()

  • Zitat

    Auch die Idee von Didée ist nicht ganz "lehrbuchmäßig" korrekt:


    Besser gesagt: ich hab' da oben syntaktischen BLÖDSINN gepostet. :wall:

    "x == 0 ? NOP : ergebnis=ergebnis+1" ist natürlich nicht zulässig. Man kann doch nicht mitten in einer solchen Entscheidungsoperation auf einmal mit einer Zuweisung anfangen.
    (Selbst wenn ich bewusstlos wäre, müssten meine Finger sich eigentlich weigern, so nen Quatsch zu schreiben...)

    So. Nachdem nun klar ist, dass es so nicht geht, hier noch ein kleiner Zusatz:

    Es geht doch. Es gehen sogar die "kompletten Anweisungsblöcke", deren Möglichkeit LigH bezweifelt hat. :)

    So geht das.

  • Eigentlich ist das wohl eher "Hacking" als "Lehrbuchmäßig", stimmt schon. Allerdings reden wir ja auch nicht über eine Programmier-Sprache, sondern über eine Script-Sprache. Kleiner (aber feiner) Unterschied. ;)

    Und überhaupt hab' ich mir das nicht ausgedacht - das waren die, die Avisynth's Parser so ausgelegt haben wie er ausgelegt ist.

    Ein Unterschied ist z.B. der, dass man mit dieser Methode beliebig viele Objekte der aktuellen Ebene manipulieren kann (im Script oben: es werden a und b und c und d manipuliert).
    Eine "echte" Funktion hingegen liefert ja nur ein einziges Objekt zurück. Um den gleichen Effekt zu erzielen, müsste man also entweder mehrere Funktionen verwenden, oder umständlich mit "global" Variablen hantieren.

    Außerdem: diese "unschöne" Methode ermöglicht u.U. Operationen, die man mit brav vordeklarierten Funktionen gar nicht machen könnte: eine Funktion ist eine starre Implementierung. Strings können aber während der Laufzeit manipuliert werden; d.h. mit der eval(string)-Methode kann man eine solche "simulierte Funktion" während der Laufzeit variabel gestalten.

    Passendes Beispiel fällt mir jetzt spontan auch keines ein - aber es finden sich bestimmt irgendwelche abstrusen Aufgabenstellungen, wo man so etwas gebrauchen kann.

  • OK danke, ich dachte, man könne hier evtl. den Ternäroperator wie eine Standard if-Anweisung benutzen.

    Das läuft jetzt soweit, dafür hagelts nur so andere Skriptfehler :) Naja, momentan hab' ich keine Zeit, aber ich werd' mich in nächster Zeit nochmal etwas intensiver mit der AVISynth-Syntax auseinandersetzen.

    Gruß, Christian

Jetzt mitmachen!

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