> ## 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.

# أتمتة فيديوهات الكلمات

> اختر النماذج، صحّح التوقيتات، وصدّر إصدار المشروع الذي تختاره

استخدم `@youka/sdk` و`@youka/cli` بالإصدار 0.2.0 أو أحدث لهذه الأمثلة. تظل المشاريع التي يتم إنشاؤها عبر واجهة API متاحة في مكتبة Youka لديك.

## اختيار سير عمل ونموذج

تحدد `kind` سير عمل المشروع. يقوم `karaoke` بفصل المسارات (stems). يستخدم `lyric-video` الصوت الأصلي ولا يفرض رسومًا على الفصل. إن لم تُحدَّد `kind` فسيتم الإبقاء على سلوك karaoke الحالي. معالجة الكلمات هي خيار منفصل: محاذاة (alignment) أو تفريغ (transcription) أو بدون معالجة.

اكتشف النماذج وأهلية الحساب قبل اختيار نموذج.

```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"),
);
```

يصف الرد معرّفات النماذج، العمليات، مداخل الصوت، دلالات النص المزوّد، سير العمل، دعم اللغات، والميزات المطلوبة. يميّز `suppliedTextHandling` بين المحاذاة، والكلمات المفتاحية لدى المزوّد، والتصحيح بعد التفريغ. تعكس الأهلية الحساب المُصادَق عليه. يصف الاكتشاف الدعم المُهيّأ، وليس ضمانًا لتوفّر المزوّد. تظل صلاحية التحقق من الطلب وتسعيرات الأسعار (price quotes) هي المرجع النهائي.

النماذج التي تتطلب عزلاً لصوت الغناء لا يمكنها معالجة فيديو كلمات بدون فصل. استخدمها ضمن سير عمل karaoke مع نموذج فصل يُنتج مسار vocals. Wav2Vec2 هو نموذج محاذاة. ElevenLabs Scribe هو نموذج تفريغ. النص المُزوَّد للتفريغ هو إرشاد، وليس ضمانًا لتطابق النص الناتج حرفيًا.

## إنشاء المشاريع والحصول على تسعير

```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);
```

قم بمحاذاة الكلمات المزوّدة باستخدام نموذج مُعلن لفيديوهات الكلمات.

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

احتفِظ بالفصل لمشاريع karaoke. احذف `--kind` أو مرّر `--kind karaoke` واختر `--split-model`. استخدم `--mode none` للإنشاء بدون معالجة الكلمات. طلبات lyric-video ترفض خيارات الفصل.

اطلب تسعير المصدر نفسه وسير العمل وخيارات المعالجة قبل الإنشاء.

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

يتحقق التسعير من توافق النموذج، وسياسة اللغة، وميزات الحساب، والمدة، وقواعد التخزين نفسها كما في الإنشاء. يحتوي تفصيل الأرصدة فيه على صفر من أرصدة الفصل لفيديوهات الكلمات. لا يحجز التسعير سعة أو أرصدة؛ قد تتغير حالة الحساب قبل الإنشاء.

## تصحيح التوقيتات دون تشغيل وظائف معالجة

اقرأ المحاذاة عبر `GET /projects/{projectId}/alignments`، ثم احصل على المورد المختار عبر `GET /projects/{projectId}/alignments/{alignmentId}`. تحتوي القائمة على `alignments` و`selectedAlignmentId` و`selectionRevision`. يتضمن كل مورد حمولة التوقيت و`revision` و`selected` و`selectionRevision`.

تستبدل التحديثات كائن `alignment` كاملًا. وهي لا تُجري مزامنة ولا تُنشئ حجزًا لأرصدة المعالجة. احتفِظ بالمعرّفات والنص وفهارس السطر/الكلمة/تحت-الكلمة (subword) ومعلومات المغني والترجمات عند التحرير. الأوقات هي ثوانٍ عشرية مطلقة. طبّق أي تصحيح مطلوب مرة واحدة ضمن القيم المُرسلة. لا تُضِف التصحيح نفسه مرة أخرى كإزاحة تصدير.

```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,
});
```

استخدم `select: true` للحفظ والاختيار بشكل ذري (atomically). لاختيار توقيتات موجودة دون استبدالها، استدعِ `client.projects.alignments.select(projectId, alignmentId, { expectedRevision, expectedSelectionRevision })`.

تحمي مراجعة المحاذاة (alignment revision) محتويات التوقيت. وتحمي مراجعة الاختيار (selection revision) أي محاذاة هي النشطة. ينتج عن رمز قديم HTTP 409. اجلب أحدث مورد، وقارن التعديلات، وقدّم استبدالًا مقصودًا. لا تُحدِّث الرمز تلقائيًا وتكتب فوق تغييرات محرر آخر.

تقبل CLI ملف JSON أو الإدخال القياسي. يحتوي ملف الاستيراد على `{ "alignment": { "items": [...] }, "expectedRevision": "..." }`. ضمّن `select` و`expectedSelectionRevision` عند الاختيار بشكل ذري. تحتوي الموارد المُصدَّرة أيضًا على بيانات وصفية للاستجابة، لذا استخرج حقول الطلب قبل الاستيراد.

```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
```

تقبل عمليات الاستيراد حتى 100,000 عنصر. يجب أن يكون كل وقت نهاية أكبر بشكل صارم من وقت بدايته. تُرفض الأرقام غير الصالحة، والأوقات السلبية، والفهارس غير الصالحة، والنطاقات ذات الطول الصفري أو المعكوسة، والتوقيتات التي تتجاوز مدة مشروع معروفة. ما تزال التداخلات المشروعة وتوقيتات الدويتو (duet) مدعومة. أعد فتح أو حدّث مشروع تطبيق مفتوح مسبقًا بعد تعديل خارجي.

## تصدير إصدار مُختار

```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` اختياريًا في طلبات التصدير وتحديثات الإعدادات، وكذلك في استعلام GET للإعدادات. يؤدي حذفه إلى الإبقاء على سلوك الإصدار الأساسي. تنتمي المحاذاة المحددة إلى المشروع، بينما ينتمي التنسيق والإعدادات إلى الإصدار المختار.

```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",
});
```

تتضمن مقابض عمليات التصدير السحابي وحمولات التصدير المحلي `versionId` و`alignmentId` و`alignmentRevision`. تحدد هذه الحقول لقطة التوقيت المستخدمة لذلك التصدير أو الحمولة المُحضّرة. كل عملية تحضير تقرأ الحالة الحالية، لذا قد يلاحظ تصدير منفصل لاحق تعديلات أحدث. احفظ الحمولة المُعادة عندما يجب على مُصيّر خارجي أن يُصيّر بالضبط تلك اللقطة المُحضّرة، وقم بتحديثها عند انتهاء صلاحية عناوين URL الموقّعة للوسائط.

يستخدم الإخراج المحلي الشفاف ProRes 4444 ضمن حاوية MOV. يقوم `--mute-all` بتعيين جميع stems الخاصة بالمشروع إلى مستوى صوت صفر. الصمت وغياب مسار الصوت خاصيتان مختلفتان في الإخراج؛ افحص الملف المُصيّر إذا كانت أداة لاحقة تتطلب إحداهما. لا يستهلك التصيير المحلي أرصدة تصدير سحابية ويظل خاضعًا لأهلية الميزات الحالية.

توقيت الكلمات، وإزاحات الصوت العامة، واستباق الكلمات (lyric anticipation) هي إعدادات منفصلة. تتحكم التخطيطات الحالية في ظهور الأسطر. لا يعد هذا الإصدار بفاصل كشف ثابت لكل سطر ولا يضيف واجهة API منفصلة لإرفاق مسار backing-track.

## تشغيل كتالوج بأمان

احتفِظ ببيان (manifest) يتضمن معرّف عنصر ثابت، وبصمة المصدر، وإعدادات العملية، ومفتاح idempotency، ومعرّفات المشروع/المهمة، وآخر نتيجة نهائية. أعد استخدام المفتاح فقط لإعادات محاولة الطلب نفسه. خزّن نتائج الإنشاء قبل انتظار الاكتمال حتى يتمكن أي إعادة تشغيل من استئناف الاستطلاع. الرفع وتحضير الملفات محليًا لهما دورة حياة خاصة بهما؛ مفتاح idempotency للإنشاء لا يزيل تكرار كل عملية رفع.

يقبل المثال التنفيذي [catalogue example](/examples/catalogue.js) معرّفات ملفات إدخال مرفوعة مسبقًا ويخزّن نقطة تحقق واحدة لكل عنصر. يبدو البيان كالتالي.

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

نزّل المثال باسم `catalogue.ts`. ثبّت تبعياته واضبط `YOUKA_API_KEY`. استخدم مشروع Node.js مع `"type": "module"` في `package.json` الخاص به.

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

أعد التشغيل باستخدام البيان نفسه ودليل الحالة نفسه لاستئناف الاستطلاع للوظائف المقبولة أو لإعادة محاولة إرسال غير مؤكد باستخدام مفتاحه الأصلي. تُسجّل الوظائف المكتملة والفاشلة وتُتخطّى. تتطلب الطلبات المتغيرة معرّفات عناصر جديدة. يمنع قفل الدليل عمليتين من إرسال البيان نفسه بالتزامن. بعد تعطل قاسٍ، احذف `.lock` القديم فقط بعد التأكد من أن PID المخزن فيه لم يعد قيد التشغيل.

ابدأ بعنصر واحد قيد التنفيذ. زد عدد العمال ضمن حدّ (bounded) فقط بعد قياس زمن معالجة الاستجابة واستجابات حدود المعدل (rate-limit) لحسابك. أعد محاولة أخطاء النقل وحدود المعدل مع تراجع (backoff)، مع احترام `Retry-After`. لا تُعِد المحاولة بشكل أعمى لأخطاء التحقق، أو تعارضات التوقيت، أو إخفاقات المعالجة النهائية. تتطلب أخطاء المصادقة بيانات اعتماد صالحة؛ ولا تعني أن وظيفة المعالجة فشلت.

احتفِظ باستطلاع مهام السحابة الحالي ومعالجة أرصدة الفشل. لا يتم تقديم نقطة نهاية دفعية (batch endpoint)، ولا وعد webhook، ولا تغيير في التسعير، ولا تغيير في الترخيص، ولا سياسة احتفاظ جديدة هنا.
