Voz e mídia
Vozes, troca de voz de um ou vários falantes, dublagem, importação de vídeo, legendas, cortes, ferramentas de áudio e publicação social via REST no Nodaro.
Os endpoints de voz e mídia expõem as ferramentas de voz e de mídia do Nodaro como REST simples. Eles cobrem catálogo de vozes, modificação de voz e troca de voz de vários falantes, dublagem, design de voz, importação de vídeo, legendas, cortes, ferramentas de áudio, transcrição e publicação em redes sociais. A maioria funciona como job: o POST retorna { jobId } na hora, você consulta periodicamente GET /v1/jobs/:id/status até o status ser completed e lê o resultado em output_data.
As rotas funcionam em todas as edições, com as exceções indicadas abaixo, e recebem um bearer token. Veja Autenticação e, para consultar periodicamente vários jobs de uma vez, Jobs. Para enviar arquivos locais, faça o upload deles primeiro; veja Envio de arquivos.
Vozes
| Método | Caminho | O que faz |
|---|---|---|
GET | /v1/voices | O catálogo de vozes prontas: nome, voice_id, gênero, sotaque e idade. |
GET | /v1/voices/library | Busca na Biblioteca de vozes compartilhada, com search, gender, language, page, page_size e mais. |
GET | /v1/voice-clones | Os clones de voz que você fez antes de a clonagem ser descontinuada. |
PATCH | /v1/voice-clones/:id | Renomeia ou edita um desses clones. |
DELETE | /v1/voice-clones/:id | Exclui um desses clones. |
POST | /v1/voice-clones, /v1/voice-clones/from-url | Descontinuadas. As duas retornam 410 voice_cloning_retired. |
Sempre que uma rota aceita uma voz, passe o voice_id de uma voz do catálogo, o nome de uma voz pronta, como Rachel, ou o elevenlabsVoiceId de um clone. Os clones feitos antes da descontinuação continuam funcionando em todo lugar.
Um resultado da Biblioteca de vozes pode trazer recommendedProvider: o modelo de texto para fala em que a voz foi verificada. Quando o seu app não tem um seletor de modelo, envie esse valor como provider no Texto para fala (Text to Speech), para que a voz soe como na prévia. verifiedProviders lista todos os modelos em que a voz foi verificada; quando o seu app tem um seletor, substitua a escolha do usuário só quando ela não estiver nessa lista. hasMore, na resposta, controla o “carregar mais”.
import { createClient, StaticTokenAuth } from '@nodaro/sdk'
const client = createClient({
baseUrl: 'https://app.nodaro.ai',
auth: new StaticTokenAuth(process.env.NODARO_API_KEY!),
})
const { voices, hasMore } = await client.voices.searchLibrary({ search: 'deep', language: 'en' })
const voice = voices[0]
await client.nodes.run('text-to-speech', {
text: 'Hello!',
voice: voice.voice_id,
voiceType: 'library',
...(voice.recommendedProvider ? { provider: voice.recommendedProvider } : {}),
})Criar uma voz ou falar com uma voz descrita
| Método | Caminho | Corpo | Resultado |
|---|---|---|---|
POST | /v1/voice-design | { text, voiceDescription, model?, loudness?, guidanceScale?, seed?, quality?, shouldEnhance? } | Uma prévia e um ID de voz reutilizável. |
POST | /v1/voice-remix | { text, voiceDescription } | Fala na voz descrita, sem clonagem. |
No Design de voz (Voice Design), text é uma frase de prévia de 100 a 1.000 caracteres, loudness vai de -1 a 1 e guidanceScale, de 0 a 100. No Remix de voz (Voice Remix), text tem de 1 a 5.000 caracteres. Os dois retornam um job.
Mudar a voz de uma gravação
POST /v1/voice-changer substitui a voz de uma faixa de áudio, ou de um vídeo inteiro com fala, por uma voz de destino. Envie exatamente um entre audioUrl e videoUrl; quando você envia os dois, o vídeo prevalece. Em um vídeo, o Nodaro extrai o áudio, muda a voz e coloca o áudio de volta na imagem original, e o output_data do job traz videoUrl e audioUrl.
curl -X POST https://app.nodaro.ai/v1/voice-changer \
-H "Authorization: Bearer $NODARO_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "videoUrl": "https://cdn.nodaro.ai/uploads/talking.mp4", "voiceId": "Aria", "removeBackgroundNoise": false }'const { jobId } = await client.voices.change({
videoUrl: 'https://cdn.nodaro.ai/uploads/talking.mp4',
voiceId: 'Aria',
})nodaro voice changer --voice Aria --video https://cdn.nodaro.ai/uploads/talking.mp4 --watch| Campo | O que faz |
|---|---|
voiceId | Obrigatório. A voz de destino. |
audioUrl ou videoUrl | Obrigatório, um dos dois. A gravação a modificar. |
model | O modelo de fala para fala. |
stability, similarityBoost | De 0 a 1. O quanto a interpretação é estável e o quanto a voz se aproxima da voz de destino. |
style | De 0 a 1, padrão 0. Exagera a interpretação, com algum custo em velocidade e estabilidade. |
useSpeakerBoost | Aumenta a semelhança com a voz de destino, um pouco mais devagar. |
seed | Um inteiro que torna a saída repetível. |
removeBackgroundNoise | true retorna só a voz limpa; false mantém a música e os efeitos sob a nova voz. |
Veja Modificador de voz (Voice Changer) para preços e dicas.
Trocar a voz de vários falantes
O Modificador de voz Pro (Voice Changer Pro) detecta cada falante de uma gravação e dá a cada um uma voz diferente, mantendo as palavras e o timing. Ele roda no Nodaro Cloud. Uma instalação self-hosted conectada ao Nodaro Cloud pode fazer a troca de voz em uma única chamada por meio dessa conexão; as etapas analyze e export exigem o próprio Nodaro Cloud. Veja Conectar ao Nodaro Cloud.
| Método | Caminho | O que faz |
|---|---|---|
POST | /v1/voice-changer-pro | Troca a voz de cada falante mapeado, como um vídeo pronto ou como stems separados. |
POST | /v1/voice-changer-pro/analyze | Detecta os falantes sem trocar as vozes. Só no Nodaro Cloud. |
POST | /v1/voice-changer-pro/export | Renderiza um vídeo pronto a partir da sua própria mixagem dos stems. Só no Nodaro Cloud. |
Mapear vozes para os falantes
orderedVoices mapeia os falantes pela ordem de detecção: o falante 0 recebe a entrada 0, o falante 1 recebe a entrada 1, e assim por diante, com 1 a 8 entradas. Os falantes que passam do fim da lista mantêm a própria voz. Cada entrada é uma destas:
- Um ID de voz, como
"Rachel". null, uma posição que mantém a voz original: esse falante mantém a própria voz, e os falantes seguintes ainda têm a voz trocada. Essas posições não custam nada, mas pelo menos uma entrada precisa ser uma voz.- Um objeto com configurações por falante:
{ voiceId, engine?, stability?, similarityBoost?, style?, useSpeakerBoost?, seed?, volumeMode?, volume? }.engineésts(o padrão, fala para fala) ouv3, que interpreta a fala de novo a partir da transcrição com o ElevenLabs v3 e só aceita os valores 0; 0,5 e 1 emstability.volumeModeématch(o padrão),normalizeoumanual, comvolumede 0 a 200 por cento.
Antes de trocar as vozes, o Nodaro sempre separa as vozes da música e dos efeitos. O resto do corpo controla o resultado:
| Campo | O que faz |
|---|---|
audioUrl ou videoUrl | Obrigatório, um dos dois. Em um vídeo, o áudio com as vozes trocadas volta para a imagem original. |
preserveBackground | Mistura a música e os efeitos de volta sob as novas vozes. Padrão true. |
separationQuality | fast (o padrão, preserva mais da voz) ou best (uma separação mais fina). |
removeBackgroundNoise | Também remove o ruído do resultado. |
musicVolumeMode, musicVolume | O nível do fundo mantido: match (o padrão), normalize ou manual, com 0 a 200 por cento. |
voiceFx | Uma reverberação ou um eco só nas vozes: { preset, wetDryMix?, delayMs?, decay? }. As predefinições de reverberação, como room, hall ou church, usam wetDryMix; echo e custom usam delayMs e decay. |
output | video (o padrão, o resultado pronto) ou stems (faixas secas, sem nivelamento, para a sua própria mixagem). |
analysis | O output_data de um job analyze anterior. A troca de voz reutiliza os falantes e os stems dessa análise, em vez de detectá-los de novo. |
A troca de voz é cobrada por falante mapeado; analyze e export têm preços fixos. Veja os preços em Modificador de voz Pro.
O fluxo interativo: analyze, troca de voz em stems, export
A troca de voz em uma única chamada renderiza um vídeo pronto de uma vez. O fluxo interativo permite verificar os falantes antes de pagar pela troca de voz e mixar o resultado antes de renderizá-lo.
Detectar os falantes
POST /v1/voice-changer-pro/analyze com audioUrl ou videoUrl e, opcionalmente, separationQuality e suggestTitle. O output_data do job concluído traz vocalsUrl e backgroundUrl, já separados, e languageCode e languageProbability, detectados. A lista speakers dá, para cada falante, id, segments, firstStartSec, wordCount e um snippet. Ele também traz um suggestedTitle quando você pede um. Procure “falantes” que não são pessoas, como aplausos.
Trocar as vozes em stems
POST /v1/voice-changer-pro com output: "stems" e todo o output_data da análise como analysis. A troca de voz pula a detecção, então você pode trocar as vozes de novo, com outras vozes, sem pagar pela detecção outra vez.
Mixar e exportar
Defina o nível de cada stem na sua própria interface; isso não custa nada. Depois, envie POST /v1/voice-changer-pro/export com o videoUrl de origem e até 16 tracks, cada uma { url, gain, muted, kind? }. gain vai de 0 a 200, kind é voice ou background, e pelo menos uma faixa precisa estar com som. Um voiceFx opcional se aplica só às faixas de voz. O fluxo de vídeo é copiado, nunca codificado de novo, então a exportação corresponde à sua prévia. O output_data.videoUrl do job concluído é o resultado.
AUTH="Authorization: Bearer $NODARO_API_KEY"
VIDEO="https://cdn.nodaro.ai/uploads/panel.mp4"
# 1. Detect the speakers
JOB=$(curl -s -X POST https://app.nodaro.ai/v1/voice-changer-pro/analyze -H "$AUTH" \
-H 'Content-Type: application/json' -d "{\"videoUrl\":\"$VIDEO\",\"suggestTitle\":true}" | jq -r .jobId)
# ...poll until completed, then keep the analysis
ANALYSIS=$(curl -s "https://app.nodaro.ai/v1/jobs/$JOB/status" -H "$AUTH" | jq .data.output_data)
# 2. Recast to stems: speaker 2 keeps their own voice
JOB=$(curl -s -X POST https://app.nodaro.ai/v1/voice-changer-pro -H "$AUTH" -H 'Content-Type: application/json' \
-d "{\"videoUrl\":\"$VIDEO\",\"orderedVoices\":[\"Rachel\",null,\"Aria\"],\"output\":\"stems\",\"analysis\":$ANALYSIS}" | jq -r .jobId)
# 3. Export your mix
curl -s -X POST https://app.nodaro.ai/v1/voice-changer-pro/export -H "$AUTH" -H 'Content-Type: application/json' -d "{
\"videoUrl\": \"$VIDEO\",
\"tracks\": [
{ \"url\": \"<voice stem 0>\", \"gain\": 100, \"muted\": false },
{ \"url\": \"<voice stem 1>\", \"gain\": 90, \"muted\": false },
{ \"url\": \"<background stem>\", \"gain\": 70, \"muted\": false, \"kind\": \"background\" }
],
\"voiceFx\": { \"preset\": \"hall\", \"wetDryMix\": 25 }
}"const { jobId: analyzeJob } = await client.voices.analyze({ videoUrl, suggestTitle: true })
const analysis = (await client.jobs.get(analyzeJob)).output_data // once completed
const { jobId: recastJob } = await client.voices.recast({
videoUrl,
orderedVoices: ['Rachel', null, 'Aria'],
output: 'stems',
analysis,
})
const stems = (await client.jobs.get(recastJob)).output_data // once completed
await client.voices.exportMix({
videoUrl,
tracks: [
{ url: stems.tracks[0].url, gain: 100, muted: false },
{ url: stems.tracks[1].url, gain: 90, muted: false },
{ url: stems.backgroundUrl, gain: 70, muted: false, kind: 'background' },
],
voiceFx: { preset: 'hall', wetDryMix: 25 },
})nodaro voice analyze --video https://cdn.nodaro.ai/uploads/panel.mp4 --watch --json > analyze.json
jq .output_data analyze.json > analysis.json
nodaro voice recast --video https://cdn.nodaro.ai/uploads/panel.mp4 --voices Rachel,keep,Aria \
--analysis-file analysis.json --output stems --watch
nodaro voice export --source https://cdn.nodaro.ai/uploads/panel.mp4 --tracks-file mix.json \
--voice-fx hall --voice-fx-mix 25 --watchNa CLI, a palavra keep em --voices cria uma posição que mantém a voz original.
Dublar para outro idioma
POST /v1/dubbing traduz e dubla uma faixa de áudio ou um vídeo inteiro, mantendo a voz de cada falante. Envie exatamente uma origem: audioUrl, videoUrl ou sourceUrl (um link público, como uma página do YouTube ou do TikTok, que o próprio modelo de dublagem busca). Um vídeo volta como vídeo dublado: output_data.videoUrl, mais a faixa dublada sozinha em output_data.audioUrl.
| Campo | O que faz |
|---|---|
targetLanguage | Obrigatório. Um código ISO, por exemplo es ou pt-BR. |
sourceLanguage | O idioma falado. É detectado quando você o omite. |
numSpeakers | 0 (o padrão) detecta os falantes; de 1 a 20 melhora a separação quando você sabe o número. |
startTime, endTime | Dubla só essa janela da origem, em segundos. |
disableVoiceCloning, dropBackgroundAudio | Não reproduz a voz própria de cada falante, ou descarta a música e os efeitos. |
highestResolution | Mantém a resolução de origem em um vídeo. |
useProfanityFilter, targetAccent, watermark | Um filtro de palavrões, um sotaque para o idioma de destino e a marca-d’água do modelo de dublagem em um vídeo. |
Uma dublagem é cobrada por minuto do trecho dublado, com mínimo de 1 minuto. O trecho pode ter até 30 minutos; um trecho mais longo retorna 413, então duble uma janela com startTime e endTime. Veja Dublagem (Dubbing).
Importar um vídeo de um link
POST /v1/download-video importa para o seu armazenamento um vídeo de rede social (YouTube, TikTok, Instagram, X ou Facebook) ou um link direto para um arquivo de vídeo. A rota retorna { downloadId }, não um ID de job. O arquivo pronto vai para a sua biblioteca.
| Campo | O que faz |
|---|---|
url | Obrigatório. A página ou o arquivo a importar. |
maxHeight | Limita a resolução, por exemplo 720. Omita para obter a melhor disponível. |
sectionStartSec, sectionEndSec | Importa só esse intervalo, em segundos, com cerca de 3 segundos a mais em cada ponta, porque o corte cai nos quadros-chave. Envie os dois ou nenhum, e corte o resultado para ter um corte exato. |
requireAudio | Por padrão, um resultado sem som falha, porque isso geralmente indica uma origem degradada. Envie false para aceitar um clipe sem som. |
Acompanhe o download com GET /v1/download-video/progress/:downloadId, um fluxo de server-sent events. Mais ou menos a cada 500 ms, ele envia { phase, percent, videoUrl?, thumbnailUrl?, error? }, e termina em completed, com o videoUrl armazenado, ou em failed, com o error. Comece a ouvir assim que a importação começar, porque o progresso só fica guardado por pouco tempo depois que o download termina. No máximo 4 downloads ficam em andamento ao mesmo tempo por conta; um quinto retorna 429 too_many_downloads.
DL=$(curl -s -X POST https://app.nodaro.ai/v1/download-video \
-H "Authorization: Bearer $NODARO_API_KEY" -H 'Content-Type: application/json' \
-d '{ "url": "https://www.youtube.com/watch?v=VIDEO_ID", "maxHeight": 720 }' | jq -r .downloadId)
curl -sN https://app.nodaro.ai/v1/download-video/progress/$DL \
-H "Authorization: Bearer $NODARO_API_KEY"const { downloadId } = await client.media.downloadVideo({
url: 'https://www.youtube.com/watch?v=VIDEO_ID',
maxHeight: 720,
})
for await (const event of client.media.downloadVideoProgress(downloadId)) {
console.log(`${event.phase} ${event.percent}%`)
if (event.phase === 'completed') console.log('stored at', event.videoUrl)
}nodaro media download "https://www.youtube.com/watch?v=VIDEO_ID" --max-height 720 --watch
nodaro media metadata "https://www.youtube.com/watch?v=VIDEO_ID"Duas rotas relacionadas respondem na hora:
POST /v1/video-metadatacom{ url }lê a duração, o tamanho, o título e o status de transmissão ao vivo de um vídeo sem baixá-lo. Use essa rota para decidir se vale importar só um trecho.POST /v1/save-to-storagecom{ mediaUrl, filename?, mediaType? }copia qualquer URL de mídia externa para o seu armazenamento, no servidor. A rota retorna um job.
Editar vídeo
| Método | Caminho | O que faz | Preço |
|---|---|---|---|
POST | /v1/trim-video | Corta um vídeo em um intervalo. | Cortar vídeo (Trim Video) |
POST | /v1/add-captions | Embute legendas em um vídeo. | Adicionar legendas (Add Captions) |
POST | /v1/still-to-video | Uma imagem e uma faixa de áudio viram um MP4. | 0 créditos |
POST | /v1/slideshow | De 2 a 100 imagens e uma faixa de áudio opcional viram um MP4. | 0 créditos |
POST | /v1/video-overlay | Coloca de 1 a 20 camadas de imagem com tempo definido sobre um vídeo. | 22 créditos |
POST | /v1/media/process | Corta ou recorta um arquivo armazenado e responde na hora. | Grátis |
Cortar um vídeo
POST /v1/trim-video recebe videoUrl e o intervalo na unidade que você preferir: startTime e endTime em segundos, trimStartFrames e trimEndFrames, trimStartSeconds e trimEndSeconds, ou keepFirstSeconds ou keepLastSeconds.
Embutir legendas
POST /v1/add-captions recebe videoUrl e as palavras da primeira fonte que encontra, nesta ordem: captions (entradas com tempo por palavra), transcript, text no estilo subtitle e, por fim, a transcrição automática da fala.
| Campo | O que faz |
|---|---|
style | subtitle (um bloco estático) ou um estilo cinético: word-highlight, karaoke, tiktok-words, word-pop ou bouncy. |
text | Em subtitle: a própria legenda, embutida como um bloco estático durante todo o vídeo. Em um estilo cinético: só o texto de reserva, usado quando a transcrição não encontra nada. |
captions | Entradas com tempo por palavra, { text, startMs, endMs }, uma por palavra nos estilos cinéticos. As words de uma transcrição servem como estão. |
auto_transcribe, transcribe_provider | Transcreve a fala quando nada mais fornece as palavras. Um estilo cinético precisa de marcações de tempo por palavra: incredibly-fast-whisper (o padrão) ou elevenlabs-stt. |
look | outline (o padrão nos estilos cinéticos) ou clean (o padrão em subtitle). |
maxWordsPerLine | De 1 a 20 palavras por linha, além do limite imposto pela largura do quadro. Com 1 ou 2, a leitura fica mais impactante. |
highlightColor, animate | Só nos estilos cinéticos; 400 em subtitle. |
position, positionY, fontSize, fontFamily, fontWeight, color, backgroundColor, strokeColor, strokeWidth, uppercase | A aparência do texto. |
segments | Dá a trechos do vídeo um estilo, um visual e uma posição próprios. |
Uma subtitle de texto simples, sem estilização, é a renderização barata. Um estilo cinético, qualquer campo de estilização, legendas com tempo, a transcrição automática ou segments renderizam pelo preço mais alto e mantêm a taxa de quadros da origem. Veja todas as opções e os dois preços em Adicionar legendas.
Transformar imagens fixas em vídeo
POST /v1/still-to-videorecebe{ imageUrl, audioUrl, motion?, intensity?, resolution?, aspectRatio?, fps?, fit?, padColor? }. O vídeo dura o mesmo que o áudio; não existe campo de duração.motionénone(o padrão),zoom-in,zoom-out,pan-left,pan-rightouken-burns, comintensityde 1 a 10. Veja Imagem fixa para vídeo (Still to Video).POST /v1/slideshowrecebeimageUrls(de 2 a 100), umaudioUrlopcional,imageDurations(segundos por imagem,nullpara automático) ouperImageDuration, umatransitione os mesmos campos de aparência. Com áudio, a apresentação dura o mesmo que o áudio; as durações fixadas que não somam esse total são ajustadas proporcionalmente, e a saída do job avisa isso. Sem áudio, ela dura o número de imagens vezesperImageDuration, em silêncio. Veja Apresentação de slides (Slideshow).
As duas rotas renderizam no servidor, sem modelo de IA, e custam 0 créditos. resolution é 720p, 1080p ou 4K, fps é 24 ou 30, e fit: "contain" adiciona faixas com padColor em vez de cortar a imagem.
Sobrepor imagens a um vídeo
POST /v1/video-overlay coloca de 1 a 20 camadas de imagem sobre um vídeo em uma única renderização e mantém o áudio original intacto. Cada camada é { imageUrl, start, end?, preset?, corner?, anchor?, x?, y?, width?, height?, fit?, opacity?, animate?, zIndex? }. start e end são segundos; sem end, a camada dura até o fim do vídeo. preset é card, corner-badge ou full-frame, e uma posição ou um tamanho explícito o substitui. Uma camada sem nenhum dos dois é um selo de canto, no canto inferior direito, a menos que corner indique outro.
outputAspect (16:9, 9:16, 1:1 ou 4:5) muda o quadro, com baseFit e backgroundColor. O job retorna { videoUrl, thumbnailUrl, width, height, durationSec, warnings }. A rota custa 22 créditos por execução, qualquer que seja o número de camadas, e cada usuário pode enviar 30 requisições por minuto. Veja Sobreposição em vídeo (Video Overlay).
Cortar ou recortar um arquivo armazenado na hora
POST /v1/media/process corta ou recorta um arquivo que você armazenou e responde na mesma requisição, de graça. O corpo é { sourceUrl, type, trim?, crop?, format?, deleteSource? }: type é video ou audio, trim é { startTime, endTime }, crop é { x, y, width, height }, e format é mp4, webm, mp3, wav, m4a ou aac. A rota retorna { data: { url, thumbnailUrl, assetId, sizeBytes, mimeType, metadata } }. deleteSource: true exclui a origem depois, quando ela é sua e nada mais a usa.
Editar áudio
Cada rota retorna um job.
| Método | Caminho | Corpo | O que faz |
|---|---|---|---|
POST | /v1/audio-separation | { audioUrl, mode?, quality? } | Divide uma faixa: vocal_instrumental (o padrão) ou stems completos, com qualidade auto, fast ou best. Veja Separação de áudio (Audio Separation). |
POST | /v1/audio-isolation | { audioUrl } | Mantém a voz principal e remove o fundo. Veja Extrator de voz (Voice Extractor). |
POST | /v1/audio-fx | { audioUrl, preset?, mix?, delayMs?, decay?, eqLow?, eqHigh? } | Um efeito de reverberação, eco, telefone ou megafone. Veja Efeitos de áudio (Audio FX). |
POST | /v1/mix-audio | { audioUrls, trackVolumes? } | Sobrepõe de 2 a 20 faixas, cada uma de 0 a 200 por cento. Veja Mixar áudio (Mix Audio). |
POST | /v1/adjust-volume | { audioUrl or videoUrl, volume?, normalize?, fadeIn?, fadeOut? } | Muda o nível, normaliza ou aplica fade. Veja Ajustar volume (Adjust Volume). |
POST | /v1/combine-audio | { segments: [{ url, startTime?, endTime? }] } | Junta segmentos um após o outro. Veja Combinar áudio (Combine Audio). |
POST | /v1/trim-audio | { audioUrl or videoUrl, startTime?, endTime?, audioFormat? } | Corta áudio, ou extrai o áudio de um vídeo, como mp3 (o padrão), wav ou aac. Veja Cortar áudio (Trim Audio). |
POST | /v1/silence-detect | { audioUrl, thresholdDb?, minSilenceMs?, padMs? } | Encontra os intervalos de silêncio de uma gravação. 11 créditos. Veja Detectar silêncio (Silence Detect). |
POST | /v1/audio-sync | { sources: [{ id, url }], reference? } | Mede as defasagens entre as gravações (de 2 a 6) de uma mesma conversa. Veja Sincronizar áudio (Audio Sync). |
silence-detect usa por padrão thresholdDb: -35, minSilenceMs: 700 e padMs: 120, e aceita áudio ou vídeo. O output_data.json dela é { version, ranges: [{ startMs, endMs }], durationMs }.
audio-sync custa 11 créditos por origem depois da primeira: 11 para 2 origens, 33 para 4, 55 para 6. Os IDs precisam ser únicos, e reference precisa ser um deles (por padrão, a primeira origem). O output_data.json dela é { version, reference, offsets: [{ sourceId, offsetMs, confidence, driftMsPerHour }], notes }, em que um tempo na referência é igual ao tempo na origem mais offsetMs. O desvio (drift) é medido e anotado, nunca corrigido.
Transcrever fala
POST /v1/transcribe transforma fala em texto e retorna um job. O corpo é { audioUrl, provider?, language?, diarize?, tagAudioEvents?, wordTimestamps? }, e audioUrl também pode ser um vídeo.
provider | Tempo por palavra | Observações |
|---|---|---|
elevenlabs-stt | Sempre | O único mecanismo que respeita diarize (quem falou cada palavra) e tagAudioEvents (risos, aplausos). |
incredibly-fast-whisper | Com wordTimestamps: true | Sem a flag, o job é bem-sucedido, é cobrado e retorna só frases. |
whisper | Nunca | Só frases. wordTimestamps: true retorna 400 validation_error antes de qualquer crédito ser gasto. |
Omitir provider executa whisper, então indique um mecanismo sempre que precisar de marcações de tempo por palavra. O output_data do job concluído guarda text, language, words (um { text, startMs, endMs, speaker? } por palavra, em milissegundos), json (a transcrição normalizada, também em milissegundos) e, só nos mecanismos mais antigos, segments em segundos. words entra direto em captions no POST /v1/add-captions.
curl -X POST https://app.nodaro.ai/v1/transcribe \
-H "Authorization: Bearer $NODARO_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "audioUrl": "https://cdn.nodaro.ai/uploads/talk.mp3", "provider": "elevenlabs-stt", "diarize": true }'const { jobId } = await client.audio.transcribe({
audioUrl: 'https://cdn.nodaro.ai/uploads/talk.mp3',
provider: 'elevenlabs-stt',
})
// once completed, burn the words in as kinetic captions
const words = (await client.jobs.get(jobId)).output_data.words
await client.media.addCaptions({
videoUrl: 'https://cdn.nodaro.ai/uploads/talk.mp4',
captions: words,
style: 'word-highlight',
autoTranscribe: false,
})nodaro audio transcribe --audio https://cdn.nodaro.ai/uploads/talk.mp3 --provider elevenlabs-stt --watch
nodaro jobs get <jobId> --json | jq '.output_data.words' > words.json
nodaro media add-captions https://cdn.nodaro.ai/uploads/talk.mp4 \
--captions-file words.json --style word-highlight --no-auto-transcribe --watchPublicar em redes sociais
Os fluxos de conexão abrem janelas pop-up e foram feitos para o app web. A publicação funciona com um token de API pessoal. Os tokens de app OAuth não podem gerenciar conexões.
| Método | Caminho | O que faz |
|---|---|---|
GET | /v1/social/providers | As redes aceitas e se cada uma está disponível nesta implantação. |
GET | /v1/social/connections | As suas contas conectadas. |
DELETE | /v1/social/connections/:id | Desconecta uma conta. |
POST | /v1/social/telegram/connect | Conecta o Telegram com um token de bot: { botToken }. |
POST | /v1/social/connect/custom | Conecta uma rede que usa campos em vez de login: { platform, fields }. |
POST | /v1/social/publish | Publica agora. Retorna um job. 11 créditos. |
POST | /v1/social/scheduled-posts | Agenda um post. 11 créditos, cobrados quando ele é publicado. |
GET | /v1/social/scheduled-posts | Os seus posts agendados, filtrados por from, to e status. |
PATCH | /v1/social/scheduled-posts/:id | Edita um post enquanto ele está queued ou draft. |
DELETE | /v1/social/scheduled-posts/:id | Cancela um post na fila. O histórico dele é mantido. |
GET /v1/social/providers lista todas as redes com { id, label, connectKind, editor, category, capabilities, available }. category é social (um feed em que você posta) ou publishing (um site em que você publica artigos). Uma rede que a implantação não configurou aparece com available: false, nunca fica oculta. As redes que se conectam com campos (Bluesky, Dev.to, Hashnode, Medium, WordPress e Lemmy) descrevem os campos em customFields, e o Nodaro verifica a credencial com a rede antes de salvá-la.
POST /v1/social/publish recebe { platform, action, connectionId?, caption?, mediaUrl or mediaItems, … }. Duas falhas exigem tratamentos diferentes:
503 publish_retryable: nada foi postado. Enviar a mesma requisição de novo é seguro.500 publish_failed: o resultado é desconhecido. Enviar de novo pode postar duas vezes, então verifique a rede primeiro.
Um post agendado recebe { connectionId, action, scheduledAt, caption?, media? }, em que cada item de mídia é { type, r2Key or url }. A mídia precisa ser de arquivos armazenados nesta implantação, que o Nodaro transforma em links novos quando o post sai; links para outros sites são recusados. Editar um post que já está sendo publicado retorna 409 not_editable. Veja Publicar nas redes (Publish to Social) e Publicar nas redes sociais.
Equivalentes no SDK e na CLI
| Área | TypeScript SDK | CLI |
|---|---|---|
| Vozes e modificação de voz | client.voices.list, searchLibrary, listClones, deleteClone, change, recast, analyze, exportMix, design, remix, dub | nodaro voice list, changer, recast, analyze, export, design, remix, dub, clones |
| Mídia | client.media.downloadVideo, downloadVideoProgress, videoMetadata, trimVideo, trimAudio, addCaptions, stillToVideo, slideshow, videoOverlay, saveToStorage, process | nodaro media download, metadata, trim-video, trim-audio, add-captions, still-to-video, slideshow, video-overlay, save |
| Áudio | client.audio.separate, isolate, applyFx, mix, adjustVolume, combine, transcribe | nodaro audio separate, isolate, fx, mix, adjust-volume, combine, transcribe |
| Auxiliares de edição | client.edit.silenceDetect, audioSync | nodaro edit silence-detect, audio-sync |
Pelo MCP, as mesmas rotas são ferramentas como voice_changer, voice_changer_pro, voice_changer_pro_analyze, voice_changer_pro_export, dubbing, transcribe, add_captions e separate_audio. Veja a Referência das ferramentas MCP.
Erros
| Status | Código | Significado |
|---|---|---|
400 | validation_error | Um campo está ausente ou é inválido, por exemplo wordTimestamps no whisper, um campo de estilo que exige um estilo de legenda cinético ou uma exportação com todas as faixas sem som. |
400 | provider_not_configured | A implantação não configurou essa rede social. |
401 | unauthorized | O token está ausente, é inválido ou foi revogado. |
402 | insufficient_credits | Só no Nodaro Cloud. A conta não tem créditos para cobrir o job. |
404 | not_found | Uma rota do Modificador de voz Pro foi chamada em uma implantação que não a oferece. |
409 | not_editable | O post agendado já está sendo publicado. |
410 | voice_cloning_retired | A clonagem de voz não é mais oferecida. |
413 | — | O trecho dublado tem mais de 30 minutos. |
429 | too_many_downloads | Já há 4 importações de vídeo em andamento na sua conta. |
500 | publish_failed | O resultado do post é desconhecido. Verifique a rede antes de enviar de novo. |
503 | publish_retryable | Nada foi postado. É seguro enviar a mesma requisição de novo. |
Perguntas frequentes
Páginas relacionadas
Modificador de voz Pro
Adicionar legendas
Transcrever
Jobs
Envio de arquivos
Última atualização
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.
Treinamento de personagem
Treine um modelo de alta fidelidade de um personagem via REST, consulte o treinamento periodicamente, remova o modelo e saiba quando o Gerar imagem o usa.