Recast
Faça o recast de um vídeo analisado com seu elenco via REST: cote e compre a execução, responda a pontos de decisão, remixe o áudio ou importe um roteiro.
Disponível em Nodaro Cloud
A API do Recast regenera um vídeo analisado com o seu próprio elenco. Você faz a cotação da execução, compra o plano dela, renderiza cena por cena e, em uma execução interativa, escolhe o elenco, as imagens fixas das cenas e a música ao longo do caminho. Você também pode escrever um filme como um roteiro em JSON e importá-lo, e assim um recast não precisa de nenhum vídeo de origem. É o mecanismo por trás do recast.nodaro.ai.
O Recast só roda no Nodaro Cloud; em instalações self-hosted, as rotas retornam 404. Em uma instalação self-hosted, decomponha um vídeo com o nó Análise de vídeo (Video Analysis) e regenere as cenas dele com o Gerar vídeo (Generate Video) em um workflow. As rotas recebem um bearer token. Veja Autenticação.
Endpoints
| Método | Caminho | O que faz | Custo |
|---|---|---|---|
POST | /v1/recast/estimate | Faz a cotação de uma execução. | Grátis |
POST | /v1/recast | Cria uma execução. Isso compra o plano. | O plano cotado |
GET | /v1/recast/:id | Consulta periodicamente uma execução e lê o ponto de decisão pendente. | Grátis |
POST | /v1/recast/:id/start | Começa a renderizar uma execução planned. | Coberto pelo plano |
POST | /v1/recast/:id/select | Responde a um ponto de decisão pendente. | Grátis |
POST | /v1/recast/:id/estimate-rescore | Faz a cotação de uma nova trilha sonora ou de uma nova mixagem. | Grátis |
POST | /v1/recast/:id/rescore | Aplica a mudança de áudio cotada. | O preço cotado |
GET | /v1/video-analysis/authoring-skill | Retorna o guia para escrever um roteiro. | Grátis |
POST | /v1/video-analysis/import/validate | Valida um roteiro. | Grátis |
POST | /v1/video-analysis/import | Importa um roteiro como uma análise concluída. | Grátis |
Cotar e criar uma execução
Uma execução parte de um job de análise: um vídeo analisado pelo nó Análise de vídeo ou um roteiro importado. Primeiro, faça a cotação. POST /v1/recast/estimate recebe as configurações com que você vai criar a execução e retorna { totalCredits, breakdown }.
Depois, POST /v1/recast cria a execução e compra o plano dela. A rota retorna { recastId }. O corpo precisa de workflowId, o ID de um workflow seu ao qual a execução fica vinculada. Sem ele, a rota retorna 400 workflow_id_required; com um ID desconhecido ou de outra pessoa, 404 workflow_not_found.
curl -X POST https://app.nodaro.ai/v1/recast/estimate \
-H "Authorization: Bearer $NODARO_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "analysisJobId": "6c1e8a3f-9b2d-4f5a-8e7c-3d1b9a5f2e6c", "resolution": "720p", "interactive": true }'
curl -X POST https://app.nodaro.ai/v1/recast \
-H "Authorization: Bearer $NODARO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"workflowId": "8d3f5b7a-1c9e-4a2d-b6f8-4e2a7c9d1b3f",
"analysisJobId": "6c1e8a3f-9b2d-4f5a-8e7c-3d1b9a5f2e6c",
"resolution": "720p",
"interactive": true,
"clientCapabilities": ["sheet-gate"]
}'import { createClient, StaticTokenAuth } from '@nodaro/sdk'
const client = createClient({
baseUrl: 'https://app.nodaro.ai',
auth: new StaticTokenAuth(process.env.NODARO_API_KEY!),
})
const quote = await client.recast.estimate({ analysisJobId, resolution: '720p', interactive: true })
console.log(quote.totalCredits, quote.breakdown)
const { recastId } = await client.recast.create({
workflowId,
analysisJobId,
resolution: '720p',
interactive: true,
clientCapabilities: ['sheet-gate'],
})nodaro recast estimate --analysis-job <jobId> --resolution 720p --json
nodaro recast create --workflow <workflowId> --analysis-job <jobId> --resolution 720p --jsonProp
Type
Para reutilizar um conjunto de configurações de renderização, salve-o como uma predefinição recast-render. Veja Predefinições.
Acompanhar uma execução
GET /v1/recast/:id retorna { status, interactive?, capabilities?, audio? }. O status passa por planning, planned, generating e depois completed ou failed. Uma execução planned espera POST /v1/recast/:id/start, que começa a renderização e retorna { gvpJobId? }. A rota de início é idempotente e não custa nada a mais, porque a cotação do plano já cobriu a renderização.
curl https://app.nodaro.ai/v1/recast/2e9b4d6f-8a1c-4e3b-9f5d-7c2a4e6b8d1f \
-H "Authorization: Bearer $NODARO_API_KEY"
curl -X POST https://app.nodaro.ai/v1/recast/2e9b4d6f-8a1c-4e3b-9f5d-7c2a4e6b8d1f/start \
-H "Authorization: Bearer $NODARO_API_KEY"const run = await client.recast.get(recastId)
if (run.status === 'planned') await client.recast.start(recastId)nodaro recast status <recastId> --json
nodaro recast start <recastId>Responder aos pontos de decisão interativos
Uma execução interativa é conduzida pelo servidor: o Nodaro avança cada passo que não exige escolha, e você só consulta o status periodicamente e responde aos pontos de decisão. Quando um ponto de decisão está aguardando, interactive.next no status indica qual é. Os pontos de decisão abrem nesta ordem:
gate | O que você escolhe |
|---|---|
cast | Um retrato para cada integrante do elenco. |
sheet | Só para uma pessoa, quando a execução oferece: uma de 3 fichas de identidade que compartilham o rosto escolhido, para que você escolha o corpo e o figurino. |
anchors | As imagens fixas de um segmento de cena. |
music | A música de uma seção do filme. |
Um ponto de decisão só abre para os tipos que a sua criação declarou em clientCapabilities, por exemplo sheet-gate. Qualquer outro ponto de decisão é decidido automaticamente, então um cliente nunca vê uma pergunta que não consegue responder.
Responda com POST /v1/recast/:id/select. A escolha é gratuita.
| Campo | O que faz |
|---|---|
gate | cast, sheet, anchors ou music. |
picks | Para cast e sheet: as suas escolhas, no formato que o ponto de decisão pendente mostra. |
segment, anchorPicks | Para anchors: o segmento e { start?, end? }, as imagens fixas escolhidas. |
section, musicPick | Para music: a seção e a faixa escolhida. |
finishAuto | true entrega este ponto de decisão e todos os restantes ao revisor automático. |
await client.recast.resolveGate(recastId, { gate: 'cast', picks })
await client.recast.resolveGate(recastId, { gate: 'music', section: 0, musicPick: 1, finishAuto: true })Uma execução interativa abandonada não causa problema: ela espera e depois se resolve sozinha quando o prazo dela passa.
Mudar a trilha sonora ou a mixagem
Depois que um take termina, você pode substituir a música dele ou reequilibrar a mixagem sem renderizar o vídeo de novo. Isso só funciona quando o status traz capabilities.audioLayers: 1 e o take tem um manifesto audio:
interface RecastAudioManifestV1 {
version: 1
revision: string
mode: 'bed' | 'replace'
present: { music?: true; video?: true }
layers: { music?: { url: string }; video?: { url: string } }
bakedEffectiveGain: { music?: number; video?: number }
pendingRescore?: {
jobId: string
requestId: string
state: 'pending' | 'running'
expectedAudioRevision: string
requestedEffectiveGain: { music?: number; video?: number }
}
}presentlista as camadas de áudio que o take tem:musice, no modobed,video, o som original.layerslista só as camadas que têm um arquivo de prévia que o seu navegador consegue tocar. Uma camada ausente delayersainda pode estar no download.bakedEffectiveGainé o nível de cada camada no arquivo atual, em porcentagem.resultUrl, no status, é a única URL de vídeo que você recebe.
Cotar e depois aplicar
A cotação e a aplicação recebem a mesma operação. Envie no máximo uma substituição de música, audioUrl ou uma ou mais sections com um brief, mais a mix completa que você quer. Uma mixagem sozinha também é válida.
{
"expectedAudioRevision": "server-revision",
"sections": [{ "index": 0, "brief": "Sparse analogue pulse" }],
"mix": {
"music": { "gain": 60, "muted": false },
"video": { "gain": 85, "muted": false }
}
}- Cotar.
POST /v1/recast/:id/estimate-rescoreé gratuito e retorna{ credits, audioRevision, noOp }. Ele retorna o preço mesmo quando o seu saldo é insuficiente. - Aplicar.
POST /v1/recast/:id/rescorerecebe o mesmo corpo mais umrequestId(um UUID) e o mesmoexpectedAudioRevision. Ele retorna{ recastId, jobId }, ou{ recastId, noOp: true, audioRevision }quando nada muda. Uma operação sem efeito não reserva créditos e não cria job. - Acompanhar. Consulte o status periodicamente.
audio.pendingRescoremostra a operação, continua lá depois de recarregar a página e desaparece quando a nova revisão é publicada ou a operação falha. Leia o status de novo antes da próxima operação.
Os ganhos são porcentagens de 0 a 200; uma camada silenciada conta como 0. Indique só as camadas de present ou a música que esta requisição adiciona. Um take no modo replace não tem a camada video, e o resultado não pode deixar todas as camadas em silêncio. Reutilize um requestId só para repetir exatamente a mesma requisição.
Envie a mix completa junto com uma substituição de música. Omiti-la só funciona quando o resultado corresponde aos níveis padrão fixos: música 35 e vídeo 100 no modo bed, ou música 100 no modo replace. Qualquer outro nível atual retorna 409 legacy_mix_mismatch.
curl -X POST https://app.nodaro.ai/v1/recast/2e9b4d6f-8a1c-4e3b-9f5d-7c2a4e6b8d1f/rescore \
-H "Authorization: Bearer $NODARO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"requestId": "4f6a8c1e-3b5d-4e7f-9a2c-6d8b1f3e5a7c",
"expectedAudioRevision": "server-revision",
"mix": { "music": { "gain": 60, "muted": false }, "video": { "gain": 85, "muted": false } }
}'const status = await client.recast.get(recastId)
const revision = status.audio?.revision
if (status.capabilities?.audioLayers === 1 && revision) {
const operation = {
expectedAudioRevision: revision,
mix: { music: { gain: 60, muted: false }, video: { gain: 85, muted: false } },
}
const quote = await client.recast.estimateRescore(recastId, operation)
if (!quote.noOp) {
await client.recast.rescore(recastId, { ...operation, requestId: crypto.randomUUID() })
}
}Importar um roteiro como filme
Você pode escrever um filme como um documento JSON, muitas vezes com a ajuda de um modelo de linguagem, e fazer o recast dele sem vídeo de origem. As três rotas são gratuitas.
Ler o guia de criação
GET /v1/video-analysis/authoring-skill retorna o guia em Markdown: os campos do documento, os valores permitidos, os limites, as regras de áudio e um exemplo validado. Entregue o guia ao modelo que escreve o seu roteiro.
Validar até o roteiro ficar válido
POST /v1/video-analysis/import/validate com { "script": { … } } retorna { valid, errors, warnings }. Cada erro tem um path, uma message e, geralmente, uma hint escrita para um ciclo de correção. Corrija cada caminho e valide de novo até valid ser true.
Importar o roteiro
POST /v1/video-analysis/import com { "script": { … }, "rightsAttested": true } guarda o roteiro como uma análise concluída e retorna { jobId, created, warnings, json }. json é o seu documento com os campos que o servidor deriva; guarde-o como a versão oficial do documento. Importar o mesmo roteiro de novo retorna o mesmo jobId com created: false.
Fazer o recast
Crie uma execução com esse jobId como analysisJobId, fidelity: "faithful" e rightsAttested: true.
rightsAttested: true é obrigatório: um recast de roteiro próprio é renderizado exatamente como foi escrito, inclusive com nomes de marcas, então o campo confirma que o roteiro é obra sua. Sem ele, a importação retorna 403 rights_attestation_required.
O documento tem estas partes:
| Parte | O que guarda |
|---|---|
meta | durationSec, width, height, aspectRatio (16:9 ou 9:16, de acordo com a largura e a altura) e um title obrigatório, que dá nome ao projeto. |
look | Opcional. O visual geral do filme. |
slots | O elenco e os cenários, cada um com um role: person, object ou background. |
scenes | As cenas, numeradas a partir de 0, sem lacunas, cada uma com 8 segundos ou menos. O total vai de 4 segundos até o limite de execução da plataforma. |
Um documento acima do limite de execução é recusado, nunca encurtado. Não escreva sceneNumber, slotRefs nem visualResolved: o servidor deriva esses campos e ignora os seus valores. É também por isso que uma análise que você copiou do editor com Copiar JSON é importada como está.
curl https://app.nodaro.ai/v1/video-analysis/authoring-skill \
-H "Authorization: Bearer $NODARO_API_KEY" > recast-authoring.md
curl -X POST https://app.nodaro.ai/v1/video-analysis/import \
-H "Authorization: Bearer $NODARO_API_KEY" \
-H "Content-Type: application/json" \
-d "{ \"script\": $(cat script.json), \"rightsAttested\": true }"const guide = await client.recast.authoringSkill()
const check = await client.recast.validateScript(script)
if (check.valid) {
const { jobId } = await client.recast.importScript(script, { rightsAttested: true })
}nodaro recast skill > recast-authoring.md
nodaro recast validate --file script.json
nodaro recast import --file script.json --rights-attested --jsonUsar pelo MCP
Os assistentes de IA fazem o mesmo ciclo com get_recast_authoring_skill, validate_recast_script, import_recast_script, start_recast, get_recast_status e resolve_recast_gate. start_recast mostra o preço primeiro e só gasta quando é chamada de novo para confirmar. Veja Recast pelo MCP.
Erros
| Status | Código | Significado |
|---|---|---|
400 | workflow_id_required | POST /v1/recast foi enviado sem workflowId. |
400 | validation_error, duplicate_section, unknown_section, all_audio_silent | A requisição ou a operação de áudio é inválida. |
402 | insufficient_credits | A conta não tem créditos para cobrir o plano ou a mudança de áudio. |
403 | rights_attestation_required | Uma importação de roteiro chegou sem rightsAttested: true. |
404 | workflow_not_found | O workflow não existe ou não é seu. |
404 | not_found | A execução não existe, ou a instância é self-hosted. |
409 | audio_layers_unavailable, audio_layer_unavailable, audio_preview_unavailable | O take não tem áudio com revisões, ou a camada que você indicou está ausente ou não tem uma prévia utilizável. |
409 | rescore_sections_unavailable, legacy_mix_mismatch | Não é possível substituir seções de música neste take, ou uma substituição sem mix não corresponde aos níveis atuais. |
409 | stale_audio_revision, rescore_in_progress, idempotency_conflict | O áudio mudou, outra mudança está em andamento ou um requestId foi reutilizado para uma requisição diferente. Leia o status e tente de novo. |
Perguntas frequentes
Páginas relacionadas
Recast
Análise de vídeo
Predefinições
Voz e mídia
Jobs
Última atualização
Assistente de prompt
Transforme uma ideia bruta em um prompt otimizado via REST: peça perguntas guiadas, monte um prompt com as respostas ou melhore um prompt em uma chamada.
Produções do Studio
Leia e edite produções do Studio via REST com operações atômicas, gere imagens fixas e clipes, incorpore jobs, planeje a exportação, compartilhe e copie.