> ## Documentation Index
> Fetch the complete documentation index at: https://docs.youka.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Lyric-Videos automatisieren

> Modelle auswählen, Timings korrigieren und eine gewählte Projektversion exportieren

Verwenden Sie `@youka/sdk` und `@youka/cli` ab Version 0.2.0 für diese Beispiele. Über die API erstellte Projekte bleiben in Ihrer Youka-Bibliothek verfügbar.

## Workflow und Modell auswählen

`kind` wählt den Projekt-Workflow aus. `karaoke` trennt Stems. `lyric-video` verwendet das Originalaudio und berechnet keine Trennung. Wird `kind` weggelassen, bleibt das bestehende Karaoke-Verhalten erhalten. Die Lyrics-Verarbeitung ist eine separate Wahl zwischen Alignment, Transkription oder keiner Verarbeitung.

Ermitteln Sie Modelle und Kontoberechtigung, bevor Sie ein Modell auswählen.

```sh theme={null}
youka capabilities --json
```

```ts theme={null}
const capabilities = await client.capabilities.get();
const eligibleModels = capabilities.models.filter(
  (model) => model.eligible && model.workflows.includes("lyric-video"),
);
```

Die Antwort beschreibt Modell-IDs, Operationen, Audio-Inputs, Semantik für bereitgestellten Text, Workflows, Sprachunterstützung und erforderliche Features. `suppliedTextHandling` unterscheidet Alignment, Provider-Keyterms und Korrektur nach der Transkription. Die Berechtigung spiegelt das authentifizierte Konto wider. Discovery beschreibt konfigurierte Unterstützung, keine Garantie für Provider-Uptime. Request-Validierung und Preisangebote bleiben maßgeblich.

Modelle, die isolierte Vocals erfordern, können kein Lyric-Video ohne Trennung verarbeiten. Verwenden Sie sie in einem Karaoke-Workflow mit einem Trennungsmodell, das Vocals erzeugt. Wav2Vec2 ist ein Alignment-Modell. ElevenLabs Scribe ist ein Transkriptionsmodell. Bereitgestellter Transkriptionstext ist eine Orientierung, keine Garantie für identischen Output-Text.

## Projekte erstellen und quotieren

```ts theme={null}
import { AlignmentModel, YoukaClient } from "@youka/sdk";

const client = new YoukaClient({ apiKey: process.env.YOUKA_API_KEY! });
const operation = await client.projects.create(
  {
    kind: "lyric-video",
    source: { type: "path", path: "./song.wav" },
    title: "Example song",
    lyricsSource: {
      type: "transcribe",
      syncModel: AlignmentModel.ElevenLabsTranscription,
      lyrics: "Optional reference lyrics",
    },
  },
  { idempotencyKey: "example-song-create-v1" },
);
const { project } = await client.projects.wait(operation);
```

Richten Sie bereitgestellte Lyrics mit einem Modell aus, das für Lyric-Videos beworben wird.

```sh theme={null}
youka project create ./song.wav --kind lyric-video --mode align \
  --sync-model audioshake-alignment --lyrics 'Line one
Line two' --json
```

Behalten Sie die Trennung für Karaoke-Projekte bei. Lassen Sie `--kind` weg oder übergeben Sie `--kind karaoke` und wählen Sie `--split-model`. Verwenden Sie `--mode none`, um ohne Lyrics-Verarbeitung zu erstellen. Lyric-video-Requests lehnen Trennungsoptionen ab.

Quotieren Sie dieselbe Quelle, denselben Workflow und dieselben Verarbeitungsoptionen vor der Erstellung.

```sh theme={null}
youka project quote ./song.wav --kind lyric-video --mode transcribe \
  --sync-model elevenlabs-transcription --json
```

Ein Quote prüft dieselbe Modellkompatibilität, Sprachrichtlinie, Kontofeatures, Dauer- und Speicherregeln wie die Erstellung. Seine Credit-Aufschlüsselung hat für Lyric-Videos null Separation-Credits. Ein Quote reserviert weder Kapazität noch Credits; der Kontostatus kann sich vor der Erstellung ändern.

## Timings ohne Verarbeitungsjobs korrigieren

Lesen Sie Alignments über `GET /projects/{projectId}/alignments` und holen Sie dann die gewählte Ressource über `GET /projects/{projectId}/alignments/{alignmentId}`. Die Liste enthält `alignments`, `selectedAlignmentId` und `selectionRevision`. Jede Ressource enthält die Timing-Payload, `revision`, `selected` und `selectionRevision`.

Updates ersetzen das komplette `alignment`-Objekt. Sie führen keine Synchronisierung aus und erstellen keinen Processing-Credit-Hold. Behalten Sie beim Bearbeiten IDs, Text, Zeilen-/Wort-/Subword-Indizes, Sängerinformationen und Übersetzungen bei. Zeiten sind absolute Dezimalsekunden. Wenden Sie eine gewünschte Korrektur einmalig in den übermittelten Werten an. Fügen Sie dieselbe Korrektur nicht noch einmal als Export-Offset hinzu.

```ts theme={null}
const snapshot = await client.projects.alignments.list(project.id);
const current = snapshot.alignments.find(
  (alignment) => alignment.id === snapshot.selectedAlignmentId,
);
if (!current) throw new Error("Project has no alignment to edit");

const corrected = structuredClone(current.alignment);
corrected.items[0]!.start = 0.75;
corrected.items[0]!.end = 1.25;

const saved = await client.projects.alignments.update(project.id, current.id, {
  alignment: corrected,
  expectedRevision: current.revision,
  select: true,
  expectedSelectionRevision: snapshot.selectionRevision,
});
```

Verwenden Sie `select: true`, um atomar zu speichern und auszuwählen. Um bestehende Timings auszuwählen, ohne sie zu ersetzen, rufen Sie `client.projects.alignments.select(projectId, alignmentId, { expectedRevision, expectedSelectionRevision })` auf.

Die Alignment-Revision schützt den Timing-Inhalt. Die Selection-Revision schützt, welches Alignment aktiv ist. Ein veraltetes Token führt zu HTTP 409. Holen Sie die neueste Ressource, vergleichen Sie die Änderungen und senden Sie eine bewusste Ersetzung. Aktualisieren Sie das Token nicht automatisch und überschreiben Sie nicht die Änderungen eines anderen Editors.

Die CLI akzeptiert eine JSON-Datei oder Standard Input. Eine Importdatei enthält `{ "alignment": { "items": [...] }, "expectedRevision": "..." }`. Fügen Sie `select` und `expectedSelectionRevision` hinzu, wenn Sie atomar auswählen. Exportierte Ressourcen enthalten außerdem Response-Metadaten, daher extrahieren Sie die Request-Felder vor dem Import.

```sh theme={null}
youka project timings list proj_example --json
youka project timings get proj_example aln_example --json > timing-resource.json
youka project timings import proj_example aln_example --body corrected-request.json --json
youka project timings select proj_example aln_example \
  --expected-revision "$ALIGNMENT_REVISION" \
  --expected-selection-revision "$SELECTION_REVISION" --json
```

Imports akzeptieren bis zu 100.000 Items. Jede Endzeit muss strikt größer als ihre Startzeit sein. Ungültige Zahlen, negative Zeiten, ungültige Indizes, Bereiche mit Länge null oder umgekehrte Bereiche sowie Timings jenseits einer bekannten Projektdauer werden abgelehnt. Legitimate Überschneidungen und Duett-Timing bleiben unterstützt. Öffnen Sie ein bereits geöffnetes App-Projekt nach einer externen Bearbeitung erneut oder aktualisieren Sie es.

## Eine gewählte Version exportieren

```sh theme={null}
youka project versions proj_example --json
youka export create proj_example --version-id ver_example --local \
  --transparent --mute-all --fps 30 --output ./overlay.mov --json
```

`versionId` ist in Export-Requests und Settings-Updates sowie in der Settings-GET-Query optional. Wird sie weggelassen, bleibt das Primary-Version-Verhalten erhalten. Das ausgewählte Alignment gehört zum Projekt, während Styling und Settings zur gewählten Version gehören.

```ts theme={null}
const versions = await client.projects.versions.list(project.id);
const versionId = versions[0]!.id;
const stemVolumes = Object.fromEntries(
  project.stems.map((stem) => [stem.id, 0]),
);
const payload = await client.exports.prepareLocal(project.id, {
  versionId,
  transparent: true,
  stemVolumes,
  fps: 30,
});
console.log(payload.versionId, payload.alignmentId, payload.alignmentRevision);

await client.exports.create(project.id, {
  target: "local",
  versionId,
  transparent: true,
  stemVolumes,
  fps: 30,
  outputPath: "./overlay.mov",
});
```

Cloud-Export-Operation-Handles und lokale Payloads enthalten `versionId`, `alignmentId` und `alignmentRevision`. Diese Felder identifizieren den Timing-Snapshot, der für diesen Export oder die vorbereitete Payload verwendet wurde. Jede Vorbereitung liest den aktuellen Zustand, daher kann ein späterer separater Export neuere Änderungen sehen. Speichern Sie die zurückgegebene Payload, wenn ein externer Renderer exakt diesen vorbereiteten Snapshot rendern muss, und aktualisieren Sie sie, wenn signierte Media-URLs ablaufen.

Transparente lokale Ausgabe verwendet ProRes 4444 in einem MOV-Container. `--mute-all` setzt alle Projekt-Stems auf null Lautstärke. Stille und ein fehlender Audiostream sind unterschiedliche Output-Eigenschaften; prüfen Sie die gerenderte Datei, falls ein Downstream-Tool eine der beiden Varianten erfordert. Lokales Rendering verbraucht keine Cloud-Export-Credits und unterliegt weiterhin der bestehenden Feature-Berechtigung.

Wort-Timing, globale Audio-Offsets und Lyric-Anticipation sind separate Settings. Bestehende Layouts steuern die Sichtbarkeit von Zeilen. Dieses Release verspricht kein festes Reveal-Intervall für jede Zeile und fügt keine separate Backing-Track-Attachment-API hinzu.

## Einen Katalog sicher betreiben

Führen Sie ein Manifest mit stabiler Item-ID, Source-Fingerprint, Operation-Settings, Idempotency-Key, Projekt-/Task-IDs und dem letzten terminalen Ergebnis. Verwenden Sie einen Key nur für Retries derselben Request erneut. Persistieren Sie Erstellungsergebnisse, bevor Sie auf Completion warten, damit ein Neustart das Polling fortsetzen kann. Uploads und lokale Dateivorbereitung haben ihren eigenen Lifecycle; ein Create-Idempotency-Key dedupliziert nicht jeden Upload.

Das ausführbare [catalogue example](/examples/catalogue.js) akzeptiert vorab hochgeladene Input-File-IDs und persistiert einen Checkpoint pro Item. Ein Manifest sieht so aus.

```json theme={null}
[
  {
    "id": "song-001",
    "request": {
      "kind": "lyric-video",
      "inputFileId": "owned-upload-id",
      "title": "Example song",
      "lyricsSource": {
        "type": "transcribe",
        "syncModel": "elevenlabs-transcription"
      }
    }
  }
]
```

Laden Sie das Beispiel als `catalogue.ts` herunter. Installieren Sie seine Dependencies und setzen Sie `YOUKA_API_KEY`. Verwenden Sie ein Node.js-Projekt mit `"type": "module"` in seiner `package.json`.

```sh theme={null}
npm install @youka/sdk@^0.2.0 tsx
npx tsx ./catalogue.ts ./manifest.json ./catalogue-state 1
```

Führen Sie es mit demselben Manifest und State-Verzeichnis erneut aus, um das Polling akzeptierter Jobs fortzusetzen oder eine unsichere Submission mit ihrem ursprünglichen Key erneut zu versuchen. Abgeschlossene und fehlgeschlagene Jobs werden aufgezeichnet und übersprungen. Geänderte Requests erfordern neue Item-IDs. Der Directory-Lock verhindert, dass zwei Prozesse dasselbe Manifest gleichzeitig submitten. Nach einem harten Crash entfernen Sie eine veraltete `.lock` erst, nachdem Sie bestätigt haben, dass die darin gespeicherte PID nicht mehr läuft.

Starten Sie mit einem Item in-flight. Erhöhen Sie eine begrenzte Worker-Anzahl erst, nachdem Sie Processing-Latenz und Rate-Limit-Responses für Ihr Konto gemessen haben. Wiederholen Sie Transportfehler und Rate-Limits mit Backoff und beachten Sie `Retry-After`. Wiederholen Sie nicht blind Validierungsfehler, Timing-Konflikte oder terminale Processing-Fehler. Authentifizierungsfehler erfordern gültige Credentials; sie bedeuten nicht, dass ein Processing-Job fehlgeschlagen ist.

Behalten Sie bestehendes Cloud-Task-Polling und Failure-Credit-Handling bei. Es werden hier weder ein Batch-Endpoint, ein Webhook-Versprechen, eine Preisänderung, eine Lizenzänderung noch eine Retention-Policy eingeführt.
