Interaktiver Kurs

Deine Video-Fabrik erklärt

Jede Nacht baut ein Computerprogramm ein fertiges YouTube-Video — Idee, Bilder, Stimme, Musik, Upload. Hier erfährst du, wie das Ding wirklich funktioniert.

7 Module ~35 Minuten Echter Code aus deinem Projekt Keine Vorkenntnisse nötig

Scrollen zum Start

01

Die Nachtschicht

Um 6 Uhr morgens beginnt jemand zu arbeiten. Dieser Jemand ist kein Mensch.

Was hier eigentlich läuft

Zeitsplitter ist ein YouTube-Kanal mit kurzen Geschichtsvideos — „1588: Der Sturm, der Spanien stoppte“, „Wien 1683“, „Nancy 1477“. Jedes ist etwa 60 Sekunden lang, hochkant, mit Bildern, Erzählstimme und Musik.

Das Besondere: Niemand schneidet diese Videos. Kein Mensch sucht Bilder aus, spricht den Text ein oder lädt etwas hoch. Das erledigt eine Kette von Programmen — vollautomatisch, jede Nacht.

~60sLänge pro Video
7Szenen im Schnitt
0Menschen im Prozess
24/7läuft der Server

Stell dir eine Zeitungsredaktion vor

Nachts, wenn alle schlafen, arbeitet eine kleine Crew: Die Redakteurin sucht ein Thema. Der Autor schreibt den Text. Die Bildredaktion besorgt Fotos. Die Druckerei setzt alles zusammen. Am Morgen liegt die Zeitung am Kiosk.

Genau so ist dein System gebaut — nur dass jede dieser Rollen ein Stück Software ist.

💡
Der wichtigste Gedanke des ganzen Kurses

Software wird fast nie als ein großer Block gebaut, sondern als viele kleine Spezialisten, die sich Aufgaben zuwerfen. Fachleute nennen das Separation of Concerns — Trennung der Zuständigkeiten.

Der Moment, in dem alles beginnt

Um 6:00 Uhr UTC passiert etwas sehr Unspektakuläres: Eine Uhr schlägt. Genauer gesagt: ein Cron-Job feuert und startet ein Programm namens Orchestrator.

0 6 * * *Täglich um 6:00 — der Orchestrator erfindet eine neue Videoidee
10 */6 * * *Alle 6 Stunden — der Monitor schaut nach, was weitergehen muss
0 7 * * *Täglich um 7:00 — der Planer vergibt Veröffentlichungstermine
35 * * * *Jede Stunde — der Cockpit-Sync aktualisiert deine Übersicht

Diese fünf Zeichen sind eine Zeitangabe: Minute, Stunde, Tag, Monat, Wochentag. Ein Stern heißt „jeder“. 0 6 * * * heißt also: Minute 0, Stunde 6, an jedem Tag.

Die Reise eines Videos

Klick dich einmal durch. Das ist der komplette Weg von „es gibt noch nichts“ bis „das Video steht auf YouTube“.

💡
Idee
📝
Drehbuch
🎨
Bilder
🎙️
Stimme
🎬
Schnitt
📺
YouTube
Bereit.
Klick auf „Nächster Schritt“.
Schritt 0 / 6
🧭
Merk dir diese Kette

Idee → Drehbuch → Bilder → Stimme → Schnitt → Upload. Der ganze Rest des Kurses hängt an dieser Reihenfolge. Wenn später etwas kaputt ist, fragst du zuerst: An welcher Station?

Wie ein Video „weiß“, wo es gerade steht

Jedes Video ist eine Zeile in einer Tabelle. Und diese Zeile hat ein Feld, das alles steuert: production_status.

1

plan
Idee da, Drehbuch fehlt

2

planned
Drehbuch fertig

3

rendering
Video wird gebaut

4

publish yt
bereit zum Upload

5

done
online

Der Monitor liest alle 6 Stunden diese Zeilen und fragt bei jeder: Muss ich hier etwas anstoßen? So sieht das im echten Code aus:

Code
const { id, production_status, idea } = prod;
const status = (production_status || '').toLowerCase().trim();
Auf Deutsch

Hol dir aus der Videozeile drei Dinge heraus: die Nummer, den Status und die Idee.

Mach den Status kleingeschrieben und schneide Leerzeichen ab — damit „Planned “ und „planned“ als dasselbe gelten. Ohne diese Zeile würde ein versehentliches Leerzeichen die ganze Automatik anhalten.

vps/scripts/progress-monitor.vps.js, Zeile 204

Kurz nachgedacht

Zwei Situationen aus dem echten Betrieb

Keine Punkte, keine Wertung — nur zum Mitdenken.

Szenario

Du schaust morgens in die Übersicht. Ein Video steht seit drei Tagen auf planned. Alle anderen sind längst online.

Wo würdest du zuerst nachsehen?

Szenario

Du willst ein altes Testvideo aus dem System nehmen, ohne es zu löschen. Es soll einfach nicht mehr angefasst werden.

Was ist der sicherste Weg?

02

Die Besetzung

Sechs Spezialisten. Keiner kann alles, jeder kann eine Sache richtig gut.

Ein Filmteam, das nie schläft

Bei einem Filmdreh macht niemand alles gleichzeitig. Es gibt eine Regie, eine Kamera, einen Schnitt, einen Verleih. Jeder beherrscht sein Handwerk — und keiner mischt sich in die anderen ein.

Dein System ist genau so besetzt. Lern die sechs kennen, dann verstehst du jede Fehlermeldung schneller.

🎬
LARZ — die Regie

Ein KI-Agent, der auf deinem Server wohnt. Er entscheidet, wann was passiert, und startet die anderen. Er schreibt aber selbst kein Video.

🔀
n8n — der Aufnahmeleiter

Ein Programm, in dem Abläufe als Flussdiagramme gebaut werden: „mach erst dies, dann jenes“. Man klickt sie zusammen, statt sie zu programmieren. Hier laufen die eigentlichen Produktionsschritte.

🗄️
Data Tables — das Klemmbrett

Eine Datenbank mit einer Zeile pro Video. Wer wissen will, wie weit ein Video ist, schaut hier nach. Sie ist die einzige Wahrheit im System.

⚙️
ffwd2api — der Cutter

Dein selbst gebauter Video-Server. Er legt Bilder, Stimme, Untertitel und Musik übereinander und rendert daraus eine Datei. Das ist der einzige Teil, den du selbst programmiert hast.

🤖
kie.ai & ElevenLabs — die Zulieferer

Fremde Dienste im Internet. Der eine malt Bilder, der andere spricht Texte. Sie gehören dir nicht, kosten Geld pro Nutzung — und können ausfallen.

📺
yutu — der Verleih

Ein kleines Kommandozeilen-Werkzeug, das mit YouTube spricht: hochladen, Aufrufzahlen holen, Kommentare lesen.

Wo wohnt wer?

Alle sechs laufen auf einem einzigen Server, den du gemietet hast. Manche in eigenen abgeschotteten Bereichen, sogenannten Containern.

Dein VPSein gemieteter Computer, der nie ausgeht
openclaw-larzContainer: hier lebt der Agent samt seiner Skripte
n8nContainer: die Workflows + die Datenbank
ffwd2apiläuft direkt auf dem Server, weil er viel Rechenleistung braucht
🏠
Warum das wichtig ist

Weil Container voneinander getrennt sind, können sie nicht einfach so miteinander reden — sie brauchen eine Adresse. Genau daran ist in diesem Projekt schon mehrfach etwas gescheitert. Mehr dazu in Modul 6.

Hör den dreien beim Arbeiten zu

So klingt es, wenn LARZ prüfen will, ob ein Video fertig ist. Klick dich durch das Gespräch.

Gruppenchat · Produktion
0 / 7
💡
Fällt dir was auf?

Niemand merkt sich etwas im Kopf. Jeder Zwischenstand wird sofort in die Tabelle geschrieben. Das ist Absicht: Wenn der Server mitten in der Nacht neu startet, weiß danach trotzdem jeder, wo er war. Fachleute nennen das Zustand auslagern.

Wie LARZ die Tabelle fragt

Drei kurze Befehle — mehr braucht es nicht, um mit der Datenbank zu reden.

Code
async function readAll(tab) {
  return asArray(await gateway({ op: 'getAll', tab }));
}

async function readRow(tab, matchField, matchValue) {
  const rows = asArray(await gateway({ op: 'getRow', tab, matchField, matchValue }));
  return rows[0];
}
Auf Deutsch

readAll heißt „lies alles“. Es bekommt den Namen einer Tabelle.

Es fragt die Datenbank nach allen Zeilen und gibt sie als Liste zurück. Das await bedeutet: warte, bis die Antwort da ist.

readRow heißt „lies eine Zeile“ — und zwar die, bei der ein bestimmtes Feld einen bestimmten Wert hat.

Es fragt gezielt nach und nimmt den ersten Treffer.

Gibt genau diese eine Zeile zurück. Zum Beispiel: „gib mir das Video mit der Nummer 25“.

vps/scripts/data-client.js, Zeile 74–81

Kurz nachgedacht

Zwei Entscheidungen, die im Alltag vorkommen

Szenario

Du willst, dass in jedem Video am Ende ein Logo eingeblendet wird — bei allen, ab sofort.

Welchem der sechs würdest du das auftragen?

Szenario

Der Bilddienst kie.ai hat eine Störung und antwortet stundenlang nicht.

Was kannst du in dieser Zeit trotzdem noch tun?

03

Die Rohrpost

Sechs Programme, die sich nicht sehen können — und trotzdem zusammenarbeiten.

Ein Problem, das du nicht siehst

In alten Bürohäusern gab es Rohrpost: Man steckte einen Zettel in eine Kapsel, warf sie in ein Rohr, und Druckluft schoss sie in die richtige Abteilung. Der Absender sah den Empfänger nie.

Genau dieses Problem haben deine Programme. Sie laufen in getrennten Containern und können sich nicht direkt „anfassen“. Sie brauchen Rohre.

📮

Webhook

Eine Web-Adresse, die auf Zuruf ein Programm startet. Wie ein Briefkasten, bei dem jemand sofort aufsteht, wenn du etwas einwirfst.

🏷️

Die Adresse

n8n:5678 — links der Name des Containers, rechts die Tür-Nummer. Beides muss stimmen, sonst kommt nichts an.

📦

Die Nutzlast

Der Inhalt der Kapsel. Meist winzig — oft nur {"id": 25}. Mehr braucht der Empfänger nicht, den Rest holt er sich aus der Datenbank.

Die fünf Rohre deines Systems

Jede Produktionsstufe hat ihre eigene Adresse. Diese Liste ist im Alltag Gold wert.

/webhook/5d7b39f3…Idee erfinden
/webhook/d71094f9…Drehbuch schreiben — erwartet {id}
/webhook/4e1887e1…Video bauen — erwartet {id} · kostet Geld
/webhook/LARZPublishVPS01/…Auf YouTube hochladen — erwartet {id, PublishTime}
/webhook/LARZDataGateway01/…Die Datenbank lesen und beschreiben
⚠️
Eine Falle, die im echten Betrieb zugeschnappt ist

Diese kryptischen Zeichenfolgen sind Adressen — und sie sind auf dem Server andere als früher in der Cloud. Wer die alte Adresse benutzt, ruft ins Leere und bekommt keinen Fehler, sondern einfach: nichts. Genau das ist passiert.

Ein Auftrag auf seinem Weg

Verfolge, was passiert, wenn LARZ ein Video rendern lassen will. Fünf Stationen, ein winziges Datenpaket.

🎬
LARZ
🚪
Gateway
🗄️
Data Table
🔀
n8n
⚙️
ffwd2api
Bereit.
Klick auf „Nächster Schritt“.
Schritt 0 / 6

Der Trick mit dem Zwischenstecker

Früher lagen alle Daten in einer Google-Tabelle. Heute in einer Datenbank auf deinem Server. Das ist ein kompletter Umbau — trotzdem musste kaum ein Skript umgeschrieben werden.

Der Grund: ein Adapter, der sich nach außen genau so verhält wie die alte Tabelle.

Ohne Adapter

  • Jedes der ~30 Skripte einzeln umschreiben
  • Überall neue Fehlerquellen
  • Wochenlange Umstellung
  • Kein Weg zurück

Mit Adapter

  • Eine einzige Zeile pro Skript austauschen
  • Alle Befehle heißen weiter gleich
  • An einem Tag umgestellt
  • Rückweg bleibt offen
Code
const GW_HOST = process.env.N8N_DATA_HOST || 'n8n';
const GW_PORT = parseInt(process.env.N8N_DATA_PORT || '5678', 10);
const GW_PATH = process.env.N8N_DATA_PATH ||
  '/webhook/LARZDataGateway01/webhook/data-gateway';
Auf Deutsch

Merke dir, wo die Datenbank wohnt: standardmäßig im Container namens n8n.

Und an welcher Tür sie klopft: Nummer 5678.

Und welchen Briefkasten sie benutzt.

Das || heißt „oder ersatzweise“: Steht eine Adresse in den Einstellungen, nimm die. Sonst nimm diese hier. So kann man die Adresse ändern, ohne den Code anzufassen — praktisch, wenn dasselbe Programm mal woanders laufen soll.

vps/scripts/data-client.js, Zeile 19–22

Kurz nachgedacht

Zwei Situationen, in denen Nachrichten verloren gehen

Szenario

Du baust ein neues Feature. Die KI schlägt vor, in einem Skript die Videodatenbank direkt aufzumachen und darin zu lesen — statt den Adapter zu benutzen.

Wie reagierst du?

Szenario

Ein Skript meldet: ECONNREFUSED 172.25.0.20:80. Übersetzt: „Ich habe an Tür 80 geklopft, niemand da.“

Was ist die wahrscheinlichste Ursache?

04

Der Taxameter

Vier fremde Dienste arbeiten für dich. Drei davon zählen mit.

Wenn du einsteigst, läuft die Uhr

In einem Taxi zahlst du nicht für das Auto, sondern für die gefahrenen Kilometer. Steht es, kostet es fast nichts. Fährt es, tickt der Zähler.

Genau so funktionieren die Dienste, die dein System benutzt. Und der teuerste Zähler läuft beim Bildermalen.

🎨
kie.ai — malt die Bilder

Pro Video etwa 7 Bilder. Der mit Abstand größte Kostenblock. Jeder versehentlich ausgelöste Rendervorgang kostet echtes Geld.

🎙️
ElevenLabs — spricht den Text

Wandelt Erzähltext in eine Stimme. Abgerechnet pro Zeichen. Moderate Kosten.

🧠
OpenAI — denkt sich Ideen und Texte aus

Erfindet Themen, schreibt Drehbücher, formuliert Titel und Beschreibungen. Günstig, aber nicht umsonst.

📺
YouTube — nimmt das Video entgegen

Kostet nichts, hat aber Tageslimits. Und einmal hochgeladen ist hochgeladen.

Welcher Status welche Rechnung auslöst

Das ist die praktisch wichtigste Tabelle des ganzen Kurses. Ein Status ist kein Etikett — er ist ein Auslöser.

plan→ startet das Drehbuch. Textkosten, gering.
plannedstartet den Bau des Videos. Bilder werden gekauft.
publish ytlädt öffentlich zu YouTube hoch. Nicht rückholbar.
hold→ löst gar nichts aus. Der sichere Parkplatz.
💸
Warum das im Alltag zählt

Wenn du eine alte Testzeile auf planned stehen lässt und der Monitor läuft, kauft er dafür Bilder — für ein Video, das niemand haben will. Deshalb gilt: Alles, was unklar ist, kommt auf hold.

Was ein Schlüssel ist — und warum er wehtut

Damit kie.ai weiß, wem es die Rechnung schickt, schickt dein System bei jeder Anfrage einen API-Schlüssel mit. Ein langes Passwort für Maschinen.

❌ Schlüssel im Code

  • Landet in der Versionsgeschichte
  • Ist für alle sichtbar, die das Projekt sehen
  • Lässt sich nicht mehr „zurücknehmen“
  • Muss ersetzt werden, um wertlos zu werden

✅ Schlüssel in separater Datei

  • Bleibt außerhalb des Projekts
  • Wird nie mitveröffentlicht
  • Lässt sich austauschen, ohne Code zu ändern
  • Pro Umgebung ein anderer möglich
🔑
Aus dem echten Projekt

In diesem Repository lag genau so ein Schlüssel jahrelang im Klartext im Code — ein Zugang zu allen Tabellen. Er wurde entfernt, aber: Einmal veröffentlicht bleibt ein Schlüssel in der Versionsgeschichte. Nur ein Austausch beim Anbieter macht ihn wirklich wertlos. Merk dir den Satz für jedes künftige Projekt.

So sieht ein sauberer Zugriff aus

Code
// Credentials kommen aus credentials.yaml (ausserhalb des Repos).
const creds = yaml.parse(fs.readFileSync('…/credentials.yaml', 'utf8'));

const auth = new google.auth.JWT(
  creds.google.client_email, null,
  creds.google.private_key.replace(/\\n/g, '\n'),
  ['https://www.googleapis.com/auth/spreadsheets.readonly']
);
Auf Deutsch

Ein Kommentar für den nächsten Menschen: Die Zugangsdaten stehen bewusst woanders.

Lies die Zugangsdatei von der Festplatte — sie liegt außerhalb des Projekts und wird nie mitveröffentlicht.

Baue daraus einen Ausweis für Google.

Nimm daraus die Kennung des Zugangs …

… und den geheimen Schlüssel. (Das replace repariert nur Zeilenumbrüche, die beim Speichern verunstaltet wurden.)

Und sag klar, was du darfst: nur lesen. Selbst wenn dieser Zugang gestohlen wird, kann damit niemand etwas verändern. Fachleute nennen das „so wenig Rechte wie möglich“.

scripts/get_bups.js, Zeile 1–12 — die Fassung nach der Bereinigung

Kurz nachgedacht

Zwei Fragen zu Geld und Zugängen

Szenario

Du willst testen, ob dein neues Drehbuch-Format funktioniert. Du brauchst dafür kein fertiges Video — nur den Text.

Wie testest du möglichst günstig?

Szenario

Dir fällt auf, dass ein Zugangsschlüssel versehentlich im Code gelandet und veröffentlicht worden ist. Du entfernst ihn sofort aus der Datei.

Reicht das?

05

Der Türsteher

Wie 15 Videos zweimal veröffentlicht wurden — und was daraus gelernt wurde.

Der Tag, an dem es peinlich wurde

Im Juli tauchten auf dem Kanal plötzlich Videos doppelt auf. Dieselbe Geschichte, zweimal hochgeladen — nur mit unterschiedlichen Titeln, weil die KI jedes Mal einen neuen erfand.

15Doppel-Uploads
10×Auslöser in 7 Minuten
0Fehlermeldungen

Das Tückische: Es war kein Absturz. Jeder einzelne Upload war technisch erfolgreich. Das System tat exakt, was man ihm gesagt hatte — nur eben mehrfach.

💡
Die gefährlichste Sorte Fehler

Nicht der, bei dem etwas rot blinkt. Sondern der, bei dem alles grün ist und trotzdem das Falsche passiert. Solche Fehler findet man nur, wenn man das Ergebnis prüft — nicht die Fehlermeldungen.

Ein Türsteher mit Gästeliste

Vor einem gut geführten Club steht jemand mit einer Liste. Wer schon drin ist, kommt nicht nochmal rein — egal wie oft er sich anstellt. Der Türsteher fragt nicht, warum jemand nochmal will. Er schaut auf die Liste und sagt Nein.

Genau das fehlte deinem Upload-Ablauf. Es gab keine Liste. Jeder, der klopfte, kam rein.

1

Auftrag kommt an

2

Türsteher prüft die Liste

3

Schon drin? → BLOCKED

4

Noch nicht? → Upload

Die Liste des Türstehers

Er prüft zwei Dinge. Wenn eines davon zutrifft, ist Schluss.

Code
String($json.publishing_status || "").toLowerCase().includes("uploaded")
|| String($json.youtube_video_id || "").trim() !== ""
Auf Deutsch

Erste Prüfung: Steht im Statusfeld irgendwo das Wort „uploaded“? Das || "" fängt den Fall ab, dass das Feld leer ist — sonst würde das Programm hier abstürzen.

Zweite Prüfung: Oder hat das Video bereits eine YouTube-Nummer? Wenn ja, existiert es dort schon.

Das || heißt „oder“. Eine zutreffende Prüfung genügt zum Blockieren. Zwei unabhängige Belege statt einem — falls einer mal nicht gesetzt wurde.

vps/workflows/03_LARZ_Publish_VPS — Node „Guard: Already published?“
🛡️
Das Fachwort dafür

Ein Ablauf, den man gefahrlos mehrfach auslösen kann, heißt idempotent. Das ist eines der wertvollsten Wörter, die du aus diesem Kurs mitnimmst — es beschreibt in einem Begriff, was hier 15 Doppel-Uploads verhindert hätte.

Finde den Fehler

Hier ist eine erfundene Version des Türstehers — mit einem Denkfehler. Klick auf die Zeile, die das Problem verursacht.

Was „BLOCKED“ bedeutet

Seit dem Umbau antwortet der Ablauf in so einem Fall mit einem klaren Satz statt mit einem Upload:

🚫

BLOCKED: Produktion 25 ist bereits veroeffentlicht (youtube_video_id: 905QBp3aMfs). Kein erneuter Upload.

Das ist keine Fehlermeldung. Das ist der Türsteher, der seinen Job macht. Wer das für einen Fehler hält und „repariert“, indem er die Felder leert, baut den ursprünglichen Bug eigenhändig wieder ein.

🧠
Genau hier scheitern KI-Assistenten gern

Zeigst du einer KI die Meldung „BLOCKED“ und bittest um eine Lösung, schlägt sie oft vor, die Sperre zu umgehen. Sie sieht ein Hindernis, nicht den Schutz. Du musst wissen, dass das Hindernis Absicht ist — genau dafür ist dieses Wissen da.

Kurz nachgedacht

Drei Situationen rund um den Türsteher

Szenario

Ein Video wurde versehentlich hochgeladen. Du löschst es auf YouTube und willst es später neu, besser hochladen.

Was passiert, wenn du den Upload einfach nochmal auslöst?

Szenario

Du beschreibst einer KI ein neues Feature: „Kunden sollen per Klick eine Rechnung per Mail bekommen.“

Welchen Satz solltest du unbedingt dazusagen?

Szenario

Der Türsteher prüft zwei Dinge: das Statusfeld und die YouTube-Nummer. Eine KI schlägt vor, das zu vereinfachen — eine Prüfung reiche doch.

Was entgegnest du?

06

Die blockierte Kreuzung

Vier echte Fehler aus diesem Projekt — und wie man sie findet.

Wenn niemand mehr fährt

Stell dir eine Kreuzung ohne Ampel vor. Vier Autos kommen gleichzeitig an, jedes will links abbiegen, jedes wartet auf das andere. Niemand hat einen Unfall. Niemand macht etwas falsch. Trotzdem bewegt sich nichts — für immer.

Das ist ein Deadlock — und genau der hat deine Videoproduktion tagelang lahmgelegt.

🧊
Das Symptom

Beim Zusammenmischen von Musik und Ton blieb das Programm hängen. Kein Absturz, keine Fehlermeldung, 0 % Prozessorlast — es tat einfach nichts mehr. Ein normales „langsam“ sieht anders aus: Da ist der Prozessor beschäftigt.

Die Wächter-Uhr, die nie klingelte

Für solche Fälle gab es bereits einen Wachhund: Passiert fünf Minuten lang nichts, brich ab und versuch es neu.

Er löste nie aus. Und der Grund dafür ist die eigentliche Lehre dieses Moduls.

1
Das blockierte Programm meldete weiter Fortschritt

Es schickte brav Statusmeldungen — allerdings immer dieselbe: time=00:00:00.

2
Der Wachhund zählte das als Lebenszeichen

Er prüfte nur: Kommt eine Meldung? Ja. Also stellte er seine Uhr zurück.

3
Ergebnis: ewiges Warten

Ein Wächter, der jede Bewegung als Fortschritt zählt, bewacht nichts. Er beruhigt nur.

💡
Die übertragbare Lehre

Miss nie „passiert etwas?“, sondern immer „kommt es voran?“. Das gilt für Ladebalken, Warteschlangen, Wiederholversuche — überall. Ein Zähler, der stehen bleibt, ist ein Stillstand, auch wenn es geschäftig aussieht.

Die Reparatur

Zwei Änderungen. Die erste beseitigt die Blockade, die zweite macht den Wachhund ehrlich.

Code · Fix 1
command = command.outputOptions(["-filter_complex_threads", "1", "-threads", "1"]);
Auf Deutsch

Sag dem Video-Werkzeug: Arbeite diesen Schritt mit genau einem Arbeiter ab, nicht mit vielen parallel.

Ein einzelner Arbeiter kann sich nicht selbst blockieren. Es wird minimal langsamer — aber es funktioniert. Der Mix, der vorher endlos hing, dauert jetzt 27 Sekunden.

ffwd2api · server/video-processor.ts, Zeile 2242
Code · Fix 2
// Only treat as activity if the encode position actually advanced.
if (progress && progress.timemark) {
  const tp = String(progress.timemark).split(":");
  const secs = (parseInt(tp[0])||0)*3600 + (parseInt(tp[1])||0)*60 + (parseFloat(tp[2])||0);
  if (secs > (lastProgressSec || 0)) { lastProgressSec = secs; lastActivity = Date.now(); }
}
Auf Deutsch

Der Kommentar sagt es direkt: Nur als Aktivität werten, wenn die Position wirklich vorangekommen ist.

Wenn eine Statusmeldung mit Zeitangabe kommt …

… zerlege die Angabe „00:01:23“ in ihre drei Teile.

Rechne alles in Sekunden um: Stunden mal 3600, Minuten mal 60, plus Sekunden.

Der entscheidende Vergleich: Nur wenn diese Zahl größer ist als beim letzten Mal, stell die Uhr zurück. Bleibt sie stehen, läuft die Uhr weiter — und der Wachhund schlägt an.

ffwd2api · server/video-processor.ts, Zeile 1144–1149

Vier Fehler, vier Fragen

Alle vier sind in diesem Projekt wirklich passiert. Präg dir die Fragen ein — sie sparen dir Stunden.

🧊

Hängt fest, 0 % Last

Frage: Warten hier zwei aufeinander?
Beschäftigt = langsam. Untätig = blockiert.

🚪

Verbindung verweigert

Frage: Stimmen Adresse und Tür-Nummer?
Eine 80 in der Meldung heißt: Tür vergessen.

🔌

Läuft, aber niemand erreicht es

Frage: Hört es nur auf sich selbst?
Der Video-Server war zweimal auf 127.0.0.1 eingestellt — das heißt „nur ich selbst“.

🔑

Gestern ging's noch

Frage: Ist ein Zugang abgelaufen?
Schlüssel verfallen lautlos. Der Code ist unschuldig.

🔍
Die Reihenfolge, die fast immer funktioniert

1. Wo steht es? (Status prüfen) → 2. Was sagt das Protokoll? → 3. Wann ging es zuletzt? → 4. Was hat sich seitdem geändert? Erst danach lohnt es sich, Code zu lesen.

Kurz nachgedacht

Drei Störungen — wo suchst du?

Szenario

Ein Rendervorgang läuft seit vier Stunden. Der Prozessor des Servers langweilt sich bei 2 %.

Was schließt du daraus?

Szenario

Nach einem Neustart des Servers schlagen alle YouTube-Uploads fehl. Am Code wurde nichts geändert.

Wonach schaust du zuerst?

Szenario

Deine KI dreht sich im Kreis: Sie schlägt seit vier Versuchen leichte Varianten desselben Fixes vor, nichts wirkt.

Wie brichst du aus der Schleife aus?

07

Der Umzug

Warum das ganze System von fremden Servern auf deinen gezogen ist.

Von der Mietwohnung ins eigene Haus

In einer Mietwohnung ist vieles bequem: Der Hausmeister kümmert sich, du zahlst monatlich, kein Aufwand. Aber du darfst keine Wände versetzen, die Miete steigt, und wenn der Vermieter kündigt, musst du raus.

Genau so verhält sich die Cloud zu einem eigenen VPS. Ein eigenes Haus ist mehr Arbeit — aber alles darin gehört dir.

🏢 Vorher: gemietet

  • Workflows liefen bei einem Anbieter
  • Daten in einer Google-Tabelle
  • Videobearbeitung über fremde Dienste
  • Monatliche Gebühren, feste Grenzen
  • Bei Störungen: warten

🏠 Jetzt: eigener Server

  • Workflows laufen auf deinem VPS
  • Eigene Datenbank auf derselben Maschine
  • Selbst gebauter Video-Server
  • Ein Fixpreis, keine Stückkosten
  • Bei Störungen: selbst nachsehen können
⚖️
Ehrlich bleiben: Es gibt einen Preis

Der eigene Server bedeutet auch: Wenn er ausfällt, gibt es keinen Hausmeister. Updates, Sicherheit, Backups liegen bei dir. Diese Abwägung — Bequemlichkeit gegen Kontrolle — begegnet dir bei fast jeder Technikentscheidung.

Was beim Umzug nicht weggeworfen wurde

Die alte Wohnung steht noch — leer, aber möbliert. Alle alten Abläufe sind abgeschaltet, aber nicht gelöscht.

1
Abschalten statt löschen

Neun alte Abläufe stehen auf „inaktiv“. Ein einziger Befehl macht sie wieder scharf.

2
Die Tabelle blieb als Schaufenster

Deine Google-Tabelle zeigt weiter alles an — aber sie steuert nichts mehr. Ein Programm spiegelt stündlich den echten Stand hinein.

3
Nur eine Wahrheit

Entscheidend ist: Es gibt genau eine Stelle, die zählt. Die Anzeige darf hübsch sein — bestimmen tut sie nichts.

Code
await sheets.spreadsheets.values.clear({ spreadsheetId: SHEET_ID, range: `${tab}!A:Z` });
await sheets.spreadsheets.values.update({
  spreadsheetId: SHEET_ID,
  range: `${tab}!A1`,
  valueInputOption: 'RAW',
  requestBody: { values: data }
});
Auf Deutsch

Lösche zuerst das ganze Anzeige-Blatt leer.

Und schreib danach den aktuellen Stand komplett neu hinein.

Ab der ersten Zelle links oben.

Text bleibt Text — die Tabelle soll nichts eigenmächtig umrechnen.

Hier kommen die frischen Daten aus der echten Datenbank.

Warum löschen statt aktualisieren? Weil so unmöglich alte Zeilen stehen bleiben können. Leeren und neu schreiben ist umständlicher, aber es kann nicht schiefgehen.

vps/scripts/cockpit-sync.js, Zeile 108–114

Das ganze Bild

Alles, was du in sechs Modulen kennengelernt hast, auf einen Blick.

Dein VPSein Computer, der nie ausgeht
LARZentscheidet, wann was passiert — 15 Zeitpläne
n8n24 Abläufe: Idee, Drehbuch, Bau, Upload
Data Tablesdie einzige Wahrheit: eine Zeile pro Video
Guardder Türsteher gegen Doppel-Uploads
ffwd2apisetzt Bild, Ton und Musik zusammen
yutuspricht mit YouTube
Draußen im Internetgehört dir nicht, kostet Geld
kie.aimalt die Bilder — größter Kostenblock
ElevenLabsspricht den Text
OpenAIerfindet Ideen und Drehbücher
Google Sheetnur noch Schaufenster, steuert nichts

Kurz nachgedacht

Zwei Entscheidungen, wie sie dir wieder begegnen werden

Szenario

Du baust ein neues Projekt. Eine Kollegin schlägt vor, die Daten „erstmal in einer Google-Tabelle“ zu halten — das sei schnell eingerichtet und jeder könne reinschauen.

Was ist die durchdachte Antwort?

Szenario

Der Umzug ist fertig, das neue System läuft. Die alten Abläufe beim Cloud-Anbieter liegen noch da.

Was tust du mit ihnen?

Das war's.

Du weißt jetzt, was jede Nacht auf deinem Server passiert — und kannst mitreden, wenn es klemmt.

idempotentZweimal auslösen darf nur einmal wirken
DeadlockAlle warten aufeinander, keiner kommt voran
AdapterZwischenstück, das den Unterbau austauschbar macht
Separation of ConcernsJeder Teil macht genau eine Sache
Zustand auslagernFortschritt speichern, damit Neustarts nichts kosten
Rollback-PfadDen Rückweg offenhalten, bevor du umschaltest

Diese sechs Begriffe sind dein Werkzeug beim Steuern von KI-Assistenten.
Wer sie präzise benutzt, bekommt präzisere Ergebnisse.

← Zurück zum Projekt auf FFWD Labs

Die Videos aus dieser Pipeline entstehen KI-gestützt und werden vor der Veröffentlichung von einem Menschen freigegeben. Wie wir das kennzeichnen, steht auf der KI-Transparenzseite.

Impressum · Datenschutz · KI-Transparenz