Nodaro ドキュメント
ドキュメントノードリファレンスモデルAI エージェント(MCP)開発者向けセルフホスティングリサーチ
REST API

音声とメディア

ボイスカタログ、ボイスチェンジャー、複数話者の声質変換、吹き替え、動画のインポート、字幕、トリミング、オーディオツール、SNS への公開を、Nodaro の REST エンドポイントとして提供します。

音声とメディアのエンドポイントは、Nodaro の音声とメディアのツールを、そのまま REST として提供します。ボイスカタログ、ボイスチェンジャーと複数話者の声質変換、吹き替え、ボイスデザイン、動画のインポート、字幕、トリミング、オーディオツール、文字起こし、SNS への公開が含まれます。そのほとんどはジョブです。POST はすぐに { jobId } を返すので、ステータスが completed になるまで GET /v1/jobs/:id/status をポーリングし、結果を output_data から読み取ります。

これらのルートは、下記で示す例外を除き、すべてのエディションで動作し、ベアラートークンを使います。認証を参照してください。複数のジョブを一括でポーリングする方法は、ジョブを参照してください。ローカルファイルを送るには、先にアップロードしてください。アップロードを参照してください。

ボイス

メソッドパス説明
GET/v1/voices標準ボイスのカタログです。名前、voice_id、性別、アクセント、年齢が含まれます。
GET/v1/voices/library共有のボイスライブラリを search、gender、language、page、page_size などで検索します。
GET/v1/voice-clonesクローン機能が廃止される前に作成したボイスクローンです。
PATCH/v1/voice-clones/:idクローンの名前を変更するか、内容を編集します。
DELETE/v1/voice-clones/:idクローンを削除します。
POST/v1/voice-clones、/v1/voice-clones/from-url廃止されました。どちらも 410 voice_cloning_retired を返します。

ボイスを受け付けるルートでは、カタログのボイスの voice_id、Rachel のような標準ボイスの名前、またはクローンの elevenlabsVoiceId のいずれかを渡します。廃止より前に作成したクローンは、どこでもそのまま使えます。

ボイスライブラリの結果には recommendedProvider が含まれることがあります。これは、そのボイスの動作が確認されているテキスト読み上げモデルです。アプリにモデルピッカーがない場合は、これをテキストから音声(Text to Speech)の provider として送ると、プレビューと同じ声になります。verifiedProviders には、そのボイスの動作が確認されているモデルがすべて挙げられます。アプリにピッカーがある場合は、ユーザーの選択がこのリストにないときだけ上書きしてください。レスポンスの hasMore は、「さらに読み込む」の表示に使います。

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 } : {}),
})

ボイスを設計する、または説明どおりのボイスで話す

メソッドパスボディ結果
POST/v1/voice-design{ text, voiceDescription, model?, loudness?, guidanceScale?, seed?, quality?, shouldEnhance? }プレビューと、再利用できるボイス ID です。
POST/v1/voice-remix{ text, voiceDescription }クローンを使わずに、説明したボイスで話す音声です。

ボイスデザイン(Voice Design)では、text は 100〜1,000 文字のプレビュー用の文で、loudness は -1〜1、guidanceScale は 0〜100 です。ボイスリミックス(Voice Remix)では、text は 1〜5,000 文字です。どちらもジョブを返します。

録音の声を変更する

POST /v1/voice-changer は、オーディオトラック、または話者が話している動画全体の声を、1 つのターゲットボイスに置き換えます。audioUrl か videoUrl のどちらか 1 つだけを送ってください。両方送った場合は、動画が優先されます。動画の場合、Nodaro は音声を取り出して声を変更し、元の映像に戻します。ジョブの output_data には videoUrl と 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
フィールド意味
voiceId必須です。ターゲットのボイスです。
audioUrl または videoUrlいずれか 1 つが必須です。変更する録音です。
modelspeech-to-speech モデルです。
stability、similarityBoost0〜1 です。話し方の安定度と、ターゲットのボイスにどれだけ近いかを指定します。
style0〜1 で、デフォルトは 0 です。話し方を強調しますが、速度と安定度が多少犠牲になります。
useSpeakerBoostターゲットのボイスへの似せ方をより際立たせます。わずかに処理が遅くなります。
seed出力を再現可能にする整数です。
removeBackgroundNoisetrue の場合はクリーンな声だけを返し、false の場合は音楽や効果音を新しい声の下に残します。

料金とコツについては、ボイスチェンジャー(Voice Changer)を参照してください。

複数の話者の声を差し替える

ボイスチェンジャー Pro(Voice Changer Pro)は、録音の中の話者をそれぞれ検出し、言葉とタイミングを保ったまま、話者ごとに異なるボイスを割り当てます。Nodaro Cloud 上で動作します。Nodaro Cloud に接続したセルフホスティング環境では、その接続を通じてワンショットでの声質変換を実行できますが、analyze と export のステップには Nodaro Cloud 自体が必要です。Nodaro Cloud への接続を参照してください。

メソッドパス説明
POST/v1/voice-changer-proマッピングしたすべての話者の声を差し替え、完成した動画として、または別々のステムとして出力します。
POST/v1/voice-changer-pro/analyze声を差し替えずに、話者だけを検出します。Nodaro Cloud 専用です。
POST/v1/voice-changer-pro/exportステムの自分のミックスから、完成した動画をレンダリングします。Nodaro Cloud 専用です。

ボイスを話者にマッピングする

orderedVoices は、検出順に話者をマッピングします。話者 0 にはエントリー 0、話者 1 にはエントリー 1 が対応し、以降も同様です。エントリーは 1〜8 個です。リストの範囲を超えた話者は、自分の声のままになります。各エントリーは、次のいずれかです。

  • ボイス ID:"Rachel" のような ID です。
  • null:声を維持するスロットです。その話者は自分の声のままになり、後に続く話者はそれでも声が差し替えられます。声を維持するスロットは無料ですが、少なくとも 1 つのエントリーはボイスを指定する必要があります。
  • オブジェクト:話者ごとの設定です。{ voiceId, engine?, stability?, similarityBoost?, style?, useSpeakerBoost?, seed?, volumeMode?, volume? }。engine は sts(デフォルト、speech-to-speech)または v3 のいずれかです。v3 は、文字起こしからそのセリフを ElevenLabs v3 でもう一度発話し直すもので、stability は 0、0.5、1 のいずれかしか指定できません。volumeMode は match(デフォルト)、normalize、manual のいずれかで、manual では volume を 0〜200% で指定します。

声を差し替える前に、Nodaro は必ず、声を音楽や効果音から分離します。残りのボディフィールドで、結果を調整します。

フィールド意味
audioUrl または videoUrlいずれか 1 つが必須です。動画の場合、差し替えた音声は元の映像に戻されます。
preserveBackground音楽や効果音を、新しい声の下にミックスして戻します。デフォルトは true です。
separationQualityfast(デフォルト、声をより多く残します)または best(より精細な分離)です。
removeBackgroundNoise結果からさらにノイズを除去します。
musicVolumeMode、musicVolume保持する背景音のレベルです。match(デフォルト)、normalize、または manual(0〜200% を指定)のいずれかです。
voiceFx声だけにかけるリバーブやエコーです。{ preset, wetDryMix?, delayMs?, decay? }。room、hall、church などのリバーブプリセットは wetDryMix を使い、echo と custom は delayMs と decay を使います。
outputvideo(デフォルト、完成した結果)または stems(自分でミックスするための、エフェクトもレベル調整もかけていないトラック)です。
analysis以前の analyze ジョブの output_data です。声質変換で、検出をやり直す代わりに、その話者とステムを再利用します。

声質変換は、マッピングした話者ごとに課金されます。analyze と export は、一律料金です。料金については、ボイスチェンジャー Pro を参照してください。

インタラクティブなフロー:analyze、ステムへの声質変換、export

ワンショットの声質変換は、1 回の呼び出しで完成した動画をレンダリングします。インタラクティブなフローでは、声質変換の料金を払う前に話者を確認し、レンダリングする前に結果をミックスできます。

話者を検出する

POST /v1/voice-changer-pro/analyze に audioUrl または videoUrl を指定し、必要に応じて separationQuality と suggestTitle も指定します。完了したジョブの output_data には、分離された vocalsUrl と backgroundUrl、検出された languageCode と languageProbability が含まれます。speakers のリストには、話者ごとの id、segments、firstStartSec、wordCount、snippet が入ります。suggestTitle を指定した場合は、suggestedTitle も含まれます。拍手のような、人ではない「話者」が検出されることもあるので注意してください。

ステムに声質変換する

POST /v1/voice-changer-pro に output: "stems" と、analysis の output_data 全体を analysis として指定します。声質変換は検出をスキップするため、検出の料金を再度払うことなく、別のボイスでもう一度声質変換できます。

ミックスして書き出す

各ステムのレベルは、自分のインターフェースで設定します。これは無料です。次に、元の videoUrl と、最大 16 個の tracks(それぞれ { url, gain, muted, kind? })を指定して POST /v1/voice-changer-pro/export を呼びます。gain は 0〜200、kind は voice または background で、少なくとも 1 つのトラックはミュートを解除しておく必要があります。任意の voiceFx は、声のトラックにだけ適用されます。動画のストリームはコピーされるだけで、エンコードし直されることはないため、書き出し結果はプレビューと一致します。完了したジョブの output_data.videoUrl が結果です。

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

CLI では、--voices の中の keep という単語が、声を維持するスロットです。

別の言語に吹き替える

POST /v1/dubbing は、オーディオトラックや動画全体を、各話者の声を保ったまま翻訳して吹き替えます。ソースは audioUrl、videoUrl、sourceUrl(YouTube や TikTok のページなど、吹き替えモデル自身が取得できる公開リンク)のいずれか 1 つだけを送ります。動画の場合、output_data.videoUrl に吹き替え済みの動画が返り、output_data.audioUrl には吹き替えたトラックだけが入ります。

フィールド意味
targetLanguage必須です。es や pt-BR のような ISO コードです。
sourceLanguage話されている言語です。省略すると自動検出されます。
numSpeakers0(デフォルト)は自動検出します。話者数がわかっている場合は、1〜20 で指定すると分離の精度が上がります。
startTime、endTimeソースのこの区間だけを、秒単位で吹き替えます。
disableVoiceCloning、dropBackgroundAudio各話者自身の声を再現しない、または音楽や効果音を取り除きます。
highestResolution動画のソースの解像度を保ちます。
useProfanityFilter、targetAccent、watermark不適切な言葉のフィルター、対象言語のアクセント、動画上への吹き替えモデルのウォーターマークです。

吹き替えの料金は、吹き替えた区間の分数単位で、最低 1 分からです。区間は最大 30 分で、それより長い場合は 413 が返されるため、startTime と endTime で区間を指定してください。吹き替え(Dubbing)を参照してください。

POST /v1/download-video は、SNS の動画(YouTube、TikTok、Instagram、X、Facebook)や、動画ファイルへの直接リンクを、あなたのストレージにインポートします。返るのはジョブ ID ではなく { downloadId } です。完成したファイルは、ライブラリに保存されます。

フィールド意味
url必須です。インポートするページまたはファイルです。
maxHeight解像度の上限で、たとえば 720 です。省略すると、利用できる最高の解像度になります。
sectionStartSec、sectionEndSecこの範囲だけを秒単位でインポートします。両方送るか、どちらも送らないかのいずれかにしてください。
requireAudio音声がない結果は、デフォルトで失敗します。多くの場合、ソースが劣化していることを意味するためです。無音のクリップを受け入れる場合は false を送ります。

ダウンロードの進行状況は、サーバー送信イベントのストリームである GET /v1/download-video/progress/:downloadId で追跡します。約 500 ミリ秒ごとに { phase, percent, videoUrl?, thumbnailUrl?, error? } が送られ、completed(保存された videoUrl を伴う)または failed(error を伴う)で終わります。ダウンロードが終わった後、進行状況はごく短い間しか保持されないため、インポートが始まったらすぐに待ち受けを開始してください。1 アカウントにつき同時に実行できるダウンロードは最大 4 件で、5 件目は 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"

関連する 2 つのルートは、すぐに応答します。

  • POST /v1/video-metadata に { url } を送ると、動画をダウンロードせずに、長さ、サイズ、タイトル、ライブ配信中かどうかを読み取れます。一部の区間だけをインポートするかどうかを判断するのに使えます。
  • POST /v1/save-to-storage に { mediaUrl, filename?, mediaType? } を送ると、外部のメディア URL をサーバー上であなたのストレージにコピーします。ジョブを返します。

動画を編集する

メソッドパス説明料金
POST/v1/trim-video動画を指定した範囲にカットします。動画のトリミング(Trim Video)
POST/v1/add-captions動画に字幕を焼き込みます。字幕を追加(Add Captions)
POST/v1/still-to-video1 枚の画像と 1 つのオーディオトラックから、MP4 を作ります。0 クレジット
POST/v1/slideshow2〜100 枚の画像と、任意のオーディオトラックから、MP4 を作ります。0 クレジット
POST/v1/video-overlay動画の上に、タイミング付きの画像レイヤーを 1〜20 個配置します。20 クレジット
POST/v1/media/process保存済みのファイルをカットまたはクロップし、すぐに応答します。無料

動画をトリミングする

POST /v1/trim-video には videoUrl と、好きな単位での範囲を指定します。秒単位の startTime と endTime、trimStartFrames と trimEndFrames、trimStartSeconds と trimEndSeconds、または keepFirstSeconds か keepLastSeconds のいずれかです。

字幕を焼き込む

POST /v1/add-captions には videoUrl を指定し、単語は次の順序で最初に見つかったソースから取得します。captions(単語ごとのタイミング付きエントリー)、transcript、subtitle スタイルの場合は text、それもなければ音声の自動文字起こしです。

フィールド意味
stylesubtitle(静的なブロック)、またはキネティックスタイル:word-highlight、karaoke、tiktok-words、word-pop、bouncy のいずれかです。
textsubtitle の場合:字幕そのもので、動画全体にわたる 1 つの静的なブロックとして焼き込まれます。キネティックスタイルの場合:文字起こしで何も見つからなかったときのフォールバックとしてのみ使われます。
captions単語ごとのタイミング付きエントリー { text, startMs, endMs } で、キネティックスタイルでは単語ごとに 1 つ指定します。文字起こしの words は、そのまま使えます。
auto_transcribe、transcribe_providerほかに単語が得られない場合に、音声を文字起こしします。キネティックスタイルには単語単位のタイミングが必要です:incredibly-fast-whisper(デフォルト)または elevenlabs-stt です。
lookキネティックスタイルではデフォルトが outline、subtitle ではデフォルトが clean です。
maxWordsPerLine1 行あたり 1〜20 語で、フレームの幅による改行に加えて適用されます。1 か 2 にすると、テンポの良い見た目になります。
highlightColor、animateキネティックスタイル専用です。subtitle では 400 です。
position、positionY、fontSize、fontFamily、fontWeight、color、backgroundColor、strokeColor、strokeWidth、uppercaseテキストの見た目です。
segments動画の範囲ごとに、それぞれ異なるスタイル、見た目、位置を指定します。

スタイルを指定しないプレーンテキストの subtitle は、安価なレンダリングです。キネティックスタイル、いずれかのスタイル関連フィールド、タイミング付きのキャプション、自動文字起こし、segments のいずれかを使うと、より高い料金でレンダリングされ、ソースのフレームレートが保たれます。すべてのオプションと両方の料金については、字幕を追加を参照してください。

静止画を動画にする

  • POST /v1/still-to-video は { imageUrl, audioUrl, motion?, intensity?, resolution?, aspectRatio?, fps?, fit?, padColor? } を受け取ります。動画の長さはオーディオと同じで、長さを指定するフィールドはありません。motion は none(デフォルト)、zoom-in、zoom-out、pan-left、pan-right、ken-burns のいずれかで、intensity は 1〜10 です。静止画から動画(Still to Video)を参照してください。
  • POST /v1/slideshow は imageUrls(2〜100 枚)、任意の audioUrl、imageDurations(画像ごとの秒数、自動の場合は null)または perImageDuration、transition、そして同じ見た目のフィールドを受け取ります。オーディオがある場合、スライドショーの長さはオーディオと同じになります。指定した長さの合計が一致しない場合は自動的に調整され、ジョブの出力にその旨が示されます。オーディオがない場合は、画像の枚数に perImageDuration を掛けた長さになり、無音になります。スライドショー(Slideshow)を参照してください。

どちらも、AI モデルを使わずにサーバー上でレンダリングされ、0 クレジットです。resolution は 720p、1080p、4K のいずれか、fps は 24 または 30、fit: "contain" にすると、クロップの代わりに padColor でレターボックスにします。

動画に画像を重ねる

POST /v1/video-overlay は、1 回のレンダリングで動画の上に 1〜20 個の画像レイヤーを配置し、元のオーディオには手を加えません。各レイヤーは { imageUrl, start, end?, preset?, corner?, anchor?, x?, y?, width?, height?, fit?, opacity?, animate?, zIndex? } です。start と end は秒単位で、end を省略すると、そのレイヤーは動画の終わりまで続きます。preset は card、corner-badge、full-frame のいずれかで、明示的な位置やサイズを指定すると、それが優先されます。どちらも指定しないレイヤーは、corner で指定しない限り、右下のコーナーバッジになります。

outputAspect(16:9、9:16、1:1、4:5 のいずれか)で、baseFit と backgroundColor とともにフレームを変更できます。ジョブは { videoUrl, thumbnailUrl, width, height, durationSec, warnings } を返します。レイヤーの数にかかわらず、実行ごとに 20 クレジットで、1 ユーザーにつき 1 分あたり 30 リクエストまで送れます。動画オーバーレイ(Video Overlay)を参照してください。

保存済みのファイルを、その場でカットまたはクロップする

POST /v1/media/process は、保存済みのファイルをカットまたはクロップし、同じリクエストの中で無料で応答します。ボディは { sourceUrl, type, trim?, crop?, format?, deleteSource? } で、type は video または audio、trim は { startTime, endTime }、crop は { x, y, width, height }、format は mp4、webm、mp3、wav、m4a、aac のいずれかです。{ data: { url, thumbnailUrl, assetId, sizeBytes, mimeType, metadata } } を返します。deleteSource: true にすると、そのファイルが自分のものであり、ほかで使われていない場合に限り、処理の後にソースを削除します。

オーディオを編集する

各ルートは、ジョブを返します。

メソッドパスボディ説明
POST/v1/audio-separation{ audioUrl, mode?, quality? }トラックを分割します。vocal_instrumental(デフォルト)か、完全な stems のいずれかで、品質は auto、fast、best です。音源分離(Audio Separation)を参照してください。
POST/v1/audio-isolation{ audioUrl }メインの声を残し、背景音を取り除きます。音声抽出(Voice Extractor)を参照してください。
POST/v1/audio-fx{ audioUrl, preset?, mix?, delayMs?, decay?, eqLow?, eqHigh? }リバーブ、エコー、電話、メガホンのいずれかの効果です。オーディオ FX(Audio FX)を参照してください。
POST/v1/mix-audio{ audioUrls, trackVolumes? }2〜20 個のトラックを、それぞれ 0〜200% の音量で重ねます。オーディオをミックス(Mix Audio)を参照してください。
POST/v1/adjust-volume{ audioUrl or videoUrl, volume?, normalize?, fadeIn?, fadeOut? }レベルの変更、ノーマライズ、フェードを行います。音量調整(Adjust Volume)を参照してください。
POST/v1/combine-audio{ segments: [{ url, startTime?, endTime? }] }セグメントを順につなぎます。オーディオを結合(Combine Audio)を参照してください。
POST/v1/trim-audio{ audioUrl or videoUrl, startTime?, endTime?, audioFormat? }オーディオをカットするか、動画から取り出します。形式は mp3(デフォルト)、wav、aac のいずれかです。オーディオのトリミング(Trim Audio)を参照してください。
POST/v1/silence-detect{ audioUrl, thresholdDb?, minSilenceMs?, padMs? }録音の無音区間を見つけます。10 クレジットです。無音検出(Silence Detect)を参照してください。
POST/v1/audio-sync{ sources: [{ id, url }], reference? }1 つの会話を録音した 2〜6 件の録音の間のオフセットを測定します。音声同期(Audio Sync)を参照してください。

silence-detect のデフォルトは thresholdDb: -35、minSilenceMs: 700、padMs: 120 で、オーディオまたは動画を受け付けます。output_data.json は { version, ranges: [{ startMs, endMs }], durationMs } です。

audio-sync は、最初の 1 件を除くソースごとに 10 クレジットかかります。2 件で 10 クレジット、4 件で 30 クレジット、6 件で 50 クレジットです。ID は重複してはならず、reference はそのいずれか 1 つを指定します(デフォルトは最初のソースです)。output_data.json は { version, reference, offsets: [{ sourceId, offsetMs, confidence, driftMsPerHour }], notes } で、リファレンス上の時刻は、ソース上の時刻に offsetMs を加えたものと等しくなります。ドリフトは測定して記録されるだけで、補正はされません。

音声を文字起こしする

POST /v1/transcribe は、音声をテキストに変換し、ジョブを返します。ボディは { audioUrl, provider?, language?, diarize?, tagAudioEvents?, wordTimestamps? } で、audioUrl には動画も指定できます。

provider単語のタイミング補足
elevenlabs-stt常にありますdiarize(どの単語をどの話者が話したか)と tagAudioEvents(笑い声、拍手など)に対応する唯一のエンジンです。
incredibly-fast-whisperwordTimestamps: true を指定した場合フラグを指定しない場合、ジョブは成功して課金されますが、フレーズのみが返ります。
whisperなしフレーズのみです。wordTimestamps: true を指定すると、クレジットが使われる前に 400 validation_error が返ります。

provider を省略すると whisper が実行されるため、単語単位のタイミングが必要な場合は、常にエンジンを指定してください。完了したジョブの output_data には、text、language、words(1 単語につき 1 つの { text, startMs, endMs, speaker? }、ミリ秒単位)、json(正規化された文字起こしで、同じくミリ秒単位)、そして古いエンジンでのみ、秒単位の segments が含まれます。words は、そのまま POST /v1/add-captions の 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 --watch

SNS に公開する

接続フローはポップアップウィンドウを開くため、Web アプリでの利用を想定しています。公開は、個人用 API トークンで行えます。OAuth アプリのトークンでは、接続を管理できません。

メソッドパス説明
GET/v1/social/providers対応しているネットワークと、それぞれがこのデプロイ環境で利用できるかどうかです。
GET/v1/social/connections接続済みのアカウントです。
DELETE/v1/social/connections/:idアカウントの接続を解除します。
POST/v1/social/telegram/connectボットトークンで Telegram を接続します:{ botToken }。
POST/v1/social/connect/customログインの代わりにフィールドを使うネットワークを接続します:{ platform, fields }。
POST/v1/social/publish今すぐ公開します。ジョブを返します。10 クレジットです。
POST/v1/social/scheduled-posts投稿をスケジュールします。10 クレジットで、公開時に課金されます。
GET/v1/social/scheduled-posts自分のスケジュール済みの投稿を、from、to、status で絞り込んで返します。
PATCH/v1/social/scheduled-posts/:idqueued または draft の間に、投稿を編集します。
DELETE/v1/social/scheduled-posts/:idキュー中の投稿をキャンセルします。履歴は保持されます。

GET /v1/social/providers は、すべてのネットワークを { id, label, connectKind, editor, category, capabilities, available } で一覧表示します。category は、投稿先のフィードを表す social、または記事を公開するサイトを表す publishing のいずれかです。デプロイ環境で設定されていないネットワークも、非表示にはならず、available: false として一覧に含まれます。フィールドで接続するネットワーク(Bluesky、Dev.to、Hashnode、Medium、WordPress、Lemmy)は、そのフィールドを customFields に記述します。Nodaro は、保存する前にそのネットワークで認証情報を確認します。

POST /v1/social/publish は { platform, action, connectionId?, caption?, mediaUrl or mediaItems, … } を受け取ります。2 種類の失敗は、それぞれ異なる対応が必要です。

  • 503 publish_retryable:何も投稿されていません。同一のリクエストを再送しても安全です。
  • 500 publish_failed:結果が不明です。再送すると二重に投稿される可能性があるため、先にネットワーク側を確認してください。

スケジュール投稿は { connectionId, action, scheduledAt, caption?, media? } を受け取り、各メディア項目は { type, r2Key or url } です。メディアは、このデプロイ環境に保存されたファイルである必要があります。投稿が送信されるときに、Nodaro がこれを新しいリンクに変換します。ほかのサイトへのリンクは拒否されます。すでに公開処理中の投稿を編集すると、409 not_editable が返されます。SNS に公開(Publish to Social)と SNS への公開を参照してください。

SDK と CLI の対応表

分野TypeScript SDKCLI
ボイスとボイスチェンジャーclient.voices.list、searchLibrary、listClones、deleteClone、change、recast、analyze、exportMix、design、remix、dubnodaro voice list、changer、recast、analyze、export、design、remix、dub、clones
メディアclient.media.downloadVideo、downloadVideoProgress、videoMetadata、trimVideo、trimAudio、addCaptions、stillToVideo、slideshow、videoOverlay、saveToStorage、processnodaro media download、metadata、trim-video、trim-audio、add-captions、still-to-video、slideshow、video-overlay、save
オーディオclient.audio.separate、isolate、applyFx、mix、adjustVolume、combine、transcribenodaro audio separate、isolate、fx、mix、adjust-volume、combine、transcribe
編集ヘルパーclient.edit.silenceDetect、audioSyncnodaro edit silence-detect、audio-sync

MCP 経由では、同じルートが voice_changer、voice_changer_pro、voice_changer_pro_analyze、voice_changer_pro_export、dubbing、transcribe、add_captions、separate_audio のようなツールになります。MCP ツールリファレンスを参照してください。

エラー

ステータスコード意味
400validation_errorフィールドが不足しているか無効です。たとえば whisper に対する wordTimestamps、キネティックな字幕スタイルが必要なスタイル関連フィールド、すべてミュートされた export などです。
400provider_not_configuredデプロイ環境で、その SNS が設定されていません。
401unauthorizedトークンがないか、無効か、取り消されています。
402insufficient_creditsNodaro Cloud 専用です。アカウントがジョブの料金をまかなえません。
404not_found提供していないデプロイ環境で、ボイスチェンジャー Pro のルートが呼び出されました。
409not_editableスケジュールされた投稿が、すでに公開処理中です。
410voice_cloning_retiredボイスクローンの提供は終了しています。
413—吹き替えの区間が 30 分を超えています。
429too_many_downloadsこのアカウントで、すでに 4 件の動画インポートが実行中です。
500publish_failed投稿の結果が不明です。再送する前に、SNS 側を確認してください。
503publish_retryable何も投稿されていません。同一のリクエストを再送しても安全です。

よくある質問

最終更新

目次