דילוג לתוכן
תיעוד Nodaro
תיעודמדריך הרכיביםמודליםתבניותסוכני AI (MCP)מפתחיםאירוח עצמימחקרהשוואות
SDK ל-TypeScript

Recast ב-SDK

אומדן מחיר, קנייה ובדיקת הסטטוס של הרצות Recast מ-TypeScript, מענה לנקודות הבחירה, ייבוא תסריט כתוב ושינוי מיקס המוזיקה בהרצה שהסתיימה.

זמין ב-Nodaro Cloud

client.recast מריץ Recast: הוא יוצר מחדש סרטון מקור שנותח, עם הליהוק שלכם, והוא יכול גם לרנדר תסריט שכתבתם, ״סרט כ-JSON״. מקבלים אומדן מחיר להרצה, קונים אותה, בודקים את ההתקדמות שלה ועונים על נקודות הבחירה שלה: הליהוק, גיליונות הזהות, תמונות הסטילס של הסצנות והמוזיקה. המתודות קוראות לנקודות הקצה שבדף ה-API של Recast. המדריך לכתיבת תסריטים נמצא בדף Recast דרך MCP.

Recast רץ ב-Nodaro Cloud. בהתקנה באירוח עצמי, המתודות האלה זורקות NotFoundError.

מתודות

מתודהמה היא עושה
authoringSkill()קריאת המדריך לכתיבת תסריט
validateScript(script)בדיקת תסריט כתוב
importScript(script, opts)שמירת תסריט כתוב כניתוח
estimate(input)אומדן מחיר להרצה, בחינם
create(input)קניית התוכנית ויצירת ההרצה
get(recastId)קריאת הסטטוס של ההרצה ושל נקודת הבחירה שממתינה
start(recastId, opts?)התחלת הרינדור של הרצה מתוכננת
resolveGate(recastId, input)מענה לנקודת בחירה שממתינה
estimateRescore(recastId, input)אומדן מחיר למיקס חדש או לרצועת מוזיקה חדשה
rescore(recastId, input)החלת שינוי האודיו שקיבלתם עליו אומדן מחיר

תסריטים כתובים

authoringSkill()‎

מחזירה את המדריך לכתיבה, כ-Markdown (GET /v1/video-analysis/authoring-skill). המדריך מכסה את מסמך התסריט, את הערכים המותרים ואת המגבלות שלו, את כללי האודיו ודוגמה שנבדקה. המתודה חינמית.

authoringSkill(): Promise<string>
const guide = await client.recast.authoringSkill()

תנו את המדריך למודל השפה שכותב את התסריט שלכם.

validateScript(script)‎

בודקת תסריט כתוב ומחזירה { valid, errors, warnings } (POST /v1/video-analysis/import/validate). המתודה חינמית ולא שומרת כלום.

validateScript(script: Record<string, unknown>): Promise<{
  valid: boolean
  errors: Array<{ path: string; message: string; hint?: string }>
  warnings: string[]
}>

מאפיין

סוג

let check = await client.recast.validateScript(script)
while (!check.valid) {
  script = await fixWithModel(script, check.errors) // each error has a path, a message and usually a hint
  check = await client.recast.validateScript(script)
}

כל שגיאה מציינת ב-path את המקום השגוי, ובדרך כלל כוללת גם hint שנכתב בשביל מודל שפה. תקנו ובדקו שוב, עד שהשדה valid הוא true.

importScript(script, opts)‎

שומרת תסריט תקין כמשימת ניתוח שהושלמה (POST /v1/video-analysis/import). העבירו את ה-jobId שהמתודה מחזירה בתור ה-analysisJobId של הרצת Recast. המתודה חינמית.

importScript(script: Record<string, unknown>, opts: { rightsAttested: true }): Promise<{
  jobId: string
  created: boolean
  warnings: string[]
  json: Record<string, unknown>
}>

מאפיין

סוג

const { jobId: analysisJobId, json } = await client.recast.importScript(script, { rightsAttested: true })

סרט Recast מתסריט כתוב מרונדר בדיוק כפי שנכתב, ולכן ייבאו רק יצירות שבבעלותכם. השדה json הוא המסמך שלכם, עם השדות שהשרת מוסיף; העדיפו אותו על פני הקלט שלכם. ייבוא חוזר של אותו תסריט מחזיר created: false.

ההרצה

estimate(input)‎

נותנת אומדן מחיר להרצה, בקרדיטים (POST /v1/recast/estimate). המתודה חינמית. גוף הבקשה זהה לזה של create(), בלי workflowId, rightsAttested ו-clientCapabilities.

estimate(input: EstimateRecastInput): Promise<{ totalCredits?: number; breakdown?: Record<string, number> }>

מאפיין

סוג

const quote = await client.recast.estimate({ analysisJobId, fidelity: "faithful" })
console.log(quote.totalCredits, quote.breakdown)

segmentSec ב-SDK 2.17.0. נתיבי Recast מקבלים ב-segmentSec שם של שיטת קיבוץ: "scenes-max", "scenes" או "max". ב-SDK 2.17.0 השדה מוגדר בטיפוסים כמספר, ולכן העבירו את השם עם המרת טיפוס, למשל segmentSec: "scenes" as unknown as number, או השמיטו את השדה כדי להשתמש בברירת המחדל של השרת. מספר כמו 10 נדחה עם 400. אותו דבר חל על create() ועל start().

create(input)‎

יוצרת את ההרצה וקונה את התוכנית (POST /v1/recast). קבלו קודם אומדן מחיר עם estimate().

create(input: CreateRecastInput): Promise<{ recastId: string }>

מאפיין

סוג

const { recastId } = await client.recast.create({
  workflowId,
  analysisJobId,
  fidelity: "faithful",
  rightsAttested: true,
  interactive: true,
  clientCapabilities: ["sheet-gate"],
})

בלי workflowId, הקריאה נכשלת עם 400 workflow_id_required; עם תהליך לא מוכר או של מישהו אחר, היא נכשלת עם 404.

get(recastId)‎

מחזירה את ההרצה (GET /v1/recast/:id). קראו למתודה הזו מדי כמה שניות כדי לבדוק את ההתקדמות. בהרצה אינטראקטיבית, השדה interactive.next מציין את השלב או את נקודת הבחירה שממתינים.

get(recastId: string): Promise<RecastRunSnapshot>

מאפיין

סוג

const run = await client.recast.get(recastId)
console.log(run.status, run.interactive)

בתמונת המצב יש status, interactive, capabilities, ובהרצה שהסתיימה עם שכבות אודיו נפרדות, גם audio. ראו את הסעיף שינוי מיקס המוזיקה.

start(recastId, opts?)‎

מתחילה את הרינדור של הרצה במצב planned (POST /v1/recast/:id/start). המחיר של הרינדור כבר נכלל באומדן של התוכנית, וקריאה חוזרת לא משנה כלום.

start(recastId: string, opts?: { segmentSec?: number; provider?: string }): Promise<{ gvpJobId?: string }>

מאפיין

סוג

const { gvpJobId } = await client.recast.start(recastId)

resolveGate(recastId, input)‎

עונה על נקודת בחירה שממתינה בהרצה אינטראקטיבית (POST /v1/recast/:id/select). הפלטפורמה מקדמת בעצמה כל שלב אחר, כך שלקוח רק קורא ל-get() מדי כמה שניות ועונה על נקודות בחירה. הבחירה עצמה חינמית.

resolveGate(recastId: string, input: ResolveRecastGateInput): Promise<Record<string, unknown>>

מאפיין

סוג

await client.recast.resolveGate(recastId, { gate: "music", musicPick: 1 })
await client.recast.resolveGate(recastId, { finishAuto: true })

נקודת בחירה נפתחת רק בסוגים שהקריאה שלכם ל-create() הצהירה עליהם ב-clientCapabilities. בכל השאר, הפלטפורמה מכריעה אוטומטית.

שינוי מיקס המוזיקה

בהרצת Recast שהסתיימה, המוזיקה והאודיו של הסרטון עצמו יכולים להישמר כשכבות נפרדות. כשהמתודה get() מחזירה capabilities.audioLayers עם הערך 1, המניפסט audio מתאר אותן:

  • revision מזהה את האודיו הנוכחי. כל שינוי דורש אותו.
  • present מפרט את השכבות שיש בהרצה, music ו-video.
  • layers כולל קובצי תצוגה מקדימה של השכבות הקיימות.
  • bakedEffectiveGain מתאר את רמות העוצמה בקובץ הנוכחי להורדה.
  • pendingRescore מתאר שינוי שעדיין מתבצע. הוא נשאר גם אחרי טעינה מחדש של הדף.

לעולם אל תמציאו גרסת אודיו, ולעולם אל תנחשו את המיקס לפי תצוגה מקדימה שחסרה.

estimateRescore(recastId, input)‎

נותנת אומדן מחיר לשינוי אודיו: מיקס חדש, רצועת מוזיקה חדשה או שניהם (POST /v1/recast/:id/estimate-rescore). המתודה חינמית ומחזירה { credits, audioRevision, noOp }.

estimateRescore(recastId: string, input: EstimateRecastRescoreInput): Promise<{ credits: number; audioRevision: string; noOp: boolean }>

מאפיין

סוג

rescore(recastId, input)‎

מחילה את שינוי האודיו (POST /v1/recast/:id/rescore). שלחו את אותה פעולה שקיבלתם עליה אומדן מחיר, ועוד requestId חדש, מסוג UUID. השתמשו שוב באותו requestId רק כדי לנסות שוב את אותה בקשה אחרי כשל ברשת.

rescore(recastId: string, input: EstimateRecastRescoreInput & { requestId: string }): Promise<
  | { recastId: string; jobId: string }
  | { recastId: string; noOp: true; audioRevision: string }
>

מאפיין

סוג

const { total: available } = await client.credits.balance()
const run = await client.recast.get(recastId)

if (run.capabilities?.audioLayers === 1 && run.audio) {
  const operation = {
    expectedAudioRevision: run.audio.revision,
    mix: {
      music: { gain: 55, muted: false },
      video: { gain: 100, muted: false },
    },
  }
  const quote = await client.recast.estimateRescore(recastId, operation)
  if (!quote.noOp && available >= quote.credits) {
    await client.recast.rescore(recastId, { ...operation, requestId: crypto.randomUUID() })
  }
}

השינוי רץ כמשימה. קראו ל-get(recastId) מדי כמה שניות, עד שהשדה audio.pendingRescore נעלם והשדה audio.revision משתנה. שינוי שלא היה משנה כלום מחזיר noOp: true, בלי משימה.

  • פעולה כוללת מיקס, החלפת מוזיקה אחת (audioUrl או sections) או החלפה יחד עם המיקס שלה.
  • עם החלפה, שלחו את המיקס המלא שאתם רוצים. השמטה שלו עובדת רק כשהרמות הן בדיוק רמות ברירת המחדל הישנות, ובכל מקרה אחר הבקשה נכשלת עם 409 legacy_mix_mismatch.
  • בקשה עם expectedAudioRevision לא עדכני נכשלת עם 409 stale_audio_revision, ושינוי שני בזמן ששינוי אחר רץ נכשל עם 409 rescore_in_progress. טענו שוב את ההרצה, ואז קבלו אומדן מחיר חדש.
  • פעולה לא תקינה נכשלת עם 400, למשל validation_error, unknown_section, duplicate_section או all_audio_silent.
  • באומדן מחיר אף פעם לא משוריינים קרדיטים, והוא מחזיר את המחיר גם כשהיתרה שלכם נמוכה מדי.

שאלות נפוצות

מה עושה Recast?

Recast יוצר מחדש סרטון מקור שנותח, עם הליהוק שלכם. Nodaro מתכנן את ההרצה לפי הניתוח, מרנדר אותה חלק אחר חלק, ומאפשר לכם לבחור בדרך את הליהוק, את גיליונות הזהות, את תמונות הסטילס של הסצנות ואת המוזיקה.

האם יצירה של הרצת Recast עולה קרדיטים?

כן. המתודה create קונה את התוכנית, ולכן קבלו קודם אומדן מחיר עם המתודה client.recast.estimate, שלא עולה כלום. גם מענה לנקודת בחירה עם המתודה resolveGate לא עולה כלום.

האם אפשר להריץ Recast על תסריט משלכם, במקום על סרטון אמיתי?

כן. בדקו את התסריט עם המתודה validateScript עד שהוא תקין, ואז ייבאו אותו עם המתודה importScript, כשהערך של rightsAttested הוא true. הייבוא מחזיר jobId, ואותו מעבירים בתור analysisJobId של הרצת Recast חדשה.

איך משנים את עוצמת המוזיקה בהרצת Recast שהסתיימה?

טענו את הרצת ה-Recast עם המתודה get, קבלו אומדן מחיר למיקס החדש עם estimateRescore, ואז שלחו את אותה פעולה ל-rescore עם requestId חדש. קראו ל-get מדי כמה שניות, עד שגרסת האודיו משתנה.

עודכן לאחרונה

בדף הזה